aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2017-08-23 02:56:58 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-08-23 02:56:58 +0000
commit05d1799b6a35546f93a93d9e6d03032dd6b0136d (patch)
tree311af599312cacb21c888aeae828cae59b0d64a1
parent04426e67ca3ee557a0083f9b3c6ba789021bd7a0 (diff)
parentf16c42333aa6b2de30a344dd68246d4a33d93e7d (diff)
downloadsource.android.com-05d1799b6a35546f93a93d9e6d03032dd6b0136d.tar.gz
Merge "Docs: Changes to source.android.com"
-rw-r--r--en/_index.yaml35
-rw-r--r--en/compatibility/_toc-compatibility.yaml2
-rw-r--r--en/compatibility/cts/downloads.html19
-rw-r--r--en/compatibility/cts/images/analog_headphones.pngbin0 -> 113567 bytes
-rw-r--r--en/compatibility/cts/images/attributes_connected.pngbin0 -> 111296 bytes
-rw-r--r--en/compatibility/cts/images/attributes_postconnect.pngbin0 -> 35683 bytes
-rw-r--r--en/compatibility/cts/images/attributes_preconnect.pngbin0 -> 31822 bytes
-rw-r--r--en/compatibility/cts/images/attributes_summary.pngbin0 -> 52669 bytes
-rw-r--r--en/compatibility/cts/images/attributes_test.pngbin0 -> 55878 bytes
-rw-r--r--en/compatibility/cts/images/buttons_connected.pngbin0 -> 146885 bytes
-rw-r--r--en/compatibility/cts/images/buttons_not_recognized.pngbin0 -> 52719 bytes
-rw-r--r--en/compatibility/cts/images/buttons_recognized.pngbin0 -> 52105 bytes
-rw-r--r--en/compatibility/cts/images/buttons_summary.pngbin0 -> 52019 bytes
-rw-r--r--en/compatibility/cts/images/buttons_test.pngbin0 -> 55913 bytes
-rw-r--r--en/compatibility/cts/images/otg_adapter.pngbin0 -> 162691 bytes
-rw-r--r--en/compatibility/cts/images/patch_cables.pngbin0 -> 111631 bytes
-rw-r--r--en/compatibility/cts/images/peripheral_cable.pngbin0 -> 142170 bytes
-rw-r--r--en/compatibility/cts/images/play_connected.pngbin0 -> 103916 bytes
-rw-r--r--en/compatibility/cts/images/play_postconnect.pngbin0 -> 36436 bytes
-rw-r--r--en/compatibility/cts/images/play_preconnect.pngbin0 -> 35598 bytes
-rw-r--r--en/compatibility/cts/images/play_summary.pngbin0 -> 46084 bytes
-rw-r--r--en/compatibility/cts/images/play_test.pngbin0 -> 55780 bytes
-rw-r--r--en/compatibility/cts/images/record_connected.pngbin0 -> 102930 bytes
-rw-r--r--en/compatibility/cts/images/record_connected_back.pngbin0 -> 104348 bytes
-rw-r--r--en/compatibility/cts/images/record_connected_front.pngbin0 -> 116973 bytes
-rw-r--r--en/compatibility/cts/images/record_postconnect.pngbin0 -> 56889 bytes
-rw-r--r--en/compatibility/cts/images/record_preconnect.pngbin0 -> 42413 bytes
-rw-r--r--en/compatibility/cts/images/record_summary.pngbin0 -> 65111 bytes
-rw-r--r--en/compatibility/cts/images/record_test.pngbin0 -> 55860 bytes
-rw-r--r--en/compatibility/cts/images/usb_audio_interface.pngbin0 -> 93763 bytes
-rw-r--r--en/compatibility/cts/images/usb_headset.pngbin0 -> 130630 bytes
-rw-r--r--en/compatibility/cts/usb-audio.html420
-rw-r--r--en/devices/_toc-interfaces.yaml133
-rw-r--r--en/devices/_toc-tech.yaml56
-rw-r--r--en/devices/architecture/configstore/add-class-item.html236
-rw-r--r--en/devices/architecture/configstore/client.html166
-rw-r--r--en/devices/architecture/configstore/index.html108
-rw-r--r--en/devices/architecture/configstore/interface.html186
-rw-r--r--en/devices/architecture/configstore/service.html128
-rw-r--r--en/devices/architecture/dto/compile.html103
-rw-r--r--en/devices/architecture/dto/implement.html187
-rw-r--r--en/devices/architecture/dto/index.html144
-rw-r--r--en/devices/architecture/dto/multiple.html75
-rw-r--r--en/devices/architecture/dto/optimize.html299
-rw-r--r--en/devices/architecture/dto/partitions.html307
-rw-r--r--en/devices/architecture/dto/syntax.html328
-rw-r--r--en/devices/architecture/hal-types.html154
-rw-r--r--en/devices/architecture/hidl-cpp/functions.html153
-rw-r--r--en/devices/architecture/hidl-cpp/index.html132
-rw-r--r--en/devices/architecture/hidl-cpp/interfaces.html271
-rw-r--r--en/devices/architecture/hidl-cpp/packages.html202
-rw-r--r--en/devices/architecture/hidl-cpp/types.html323
-rw-r--r--en/devices/architecture/hidl-java/constants.html87
-rw-r--r--en/devices/architecture/hidl-java/index.html186
-rw-r--r--en/devices/architecture/hidl-java/interfaces.html151
-rw-r--r--en/devices/architecture/hidl-java/types.html161
-rw-r--r--en/devices/architecture/hidl/binder-ipc.html315
-rw-r--r--en/devices/architecture/hidl/code-style.html718
-rw-r--r--en/devices/architecture/hidl/converting.html87
-rw-r--r--en/devices/architecture/hidl/fmq.html424
-rw-r--r--en/devices/architecture/hidl/hashing.html165
-rw-r--r--en/devices/architecture/hidl/index.html337
-rw-r--r--en/devices/architecture/hidl/interfaces.html228
-rw-r--r--en/devices/architecture/hidl/network-stack.html176
-rw-r--r--en/devices/architecture/hidl/services.html219
-rw-r--r--en/devices/architecture/hidl/threading.html156
-rw-r--r--en/devices/architecture/hidl/types.html408
-rw-r--r--en/devices/architecture/hidl/versioning.html655
-rw-r--r--en/devices/architecture/images/treble_configstore_design.pngbin0 -> 12996 bytes
-rw-r--r--en/devices/architecture/images/treble_cpp_compiler_generated_files.pngbin0 -> 45992 bytes
-rw-r--r--en/devices/architecture/images/treble_cpp_legacy_hal_progression.pngbin0 -> 79295 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_appending.pngbin0 -> 16754 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_bootloader.pngbin0 -> 35091 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo.pngbin0 -> 22448 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_ab.pngbin0 -> 32464 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_ab_1.pngbin0 -> 18356 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_ab_2.pngbin0 -> 16084 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_multiple.pngbin0 -> 32146 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_partition_1.pngbin0 -> 4734 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_dtbo_partition_2.pngbin0 -> 4287 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_multiple_dt.pngbin0 -> 18907 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_multiple_dt_runtime.pngbin0 -> 39861 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_overriding.pngbin0 -> 16490 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_partition_1.pngbin0 -> 7449 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_partition_2.pngbin0 -> 6400 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_partition_layout.pngbin0 -> 28046 bytes
-rw-r--r--en/devices/architecture/images/treble_dto_simulate.pngbin0 -> 37300 bytes
-rw-r--r--en/devices/architecture/images/treble_kernel_current.pngbin0 -> 60642 bytes
-rw-r--r--en/devices/architecture/images/treble_kernel_treble.pngbin0 -> 46584 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_bcc_plugin_new.pngbin0 -> 22492 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_bcc_plugin_old.pngbin0 -> 16713 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_cpu_fallback.pngbin0 -> 12179 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_gpu_fallback.pngbin0 -> 30117 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_linking.pngbin0 -> 68722 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_namespace.pngbin0 -> 44325 bytes
-rw-r--r--en/devices/architecture/images/treble_rs_vendor_driver.pngbin0 -> 20643 bytes
-rw-r--r--en/devices/architecture/images/treble_vintf_avb_o_p.pngbin0 -> 36459 bytes
-rw-r--r--en/devices/architecture/images/treble_vintf_avb_p.pngbin0 -> 30246 bytes
-rw-r--r--en/devices/architecture/images/treble_vintf_mm.pngbin0 -> 30295 bytes
-rw-r--r--en/devices/architecture/images/treble_vndk_design.pngbin0 -> 34620 bytes
-rw-r--r--en/devices/architecture/kernel/hardening.html100
-rw-r--r--en/devices/architecture/kernel/index.html80
-rw-r--r--en/devices/architecture/kernel/lldb-debug.html110
-rw-r--r--en/devices/architecture/kernel/modular-kernels.html751
-rw-r--r--en/devices/architecture/kernel/releases.html180
-rw-r--r--en/devices/architecture/kernel/reqs-interfaces.html273
-rw-r--r--en/devices/architecture/kernel/squashfs.html114
-rw-r--r--en/devices/architecture/treble.html59
-rw-r--r--en/devices/architecture/vintf/comp-matrices.html263
-rw-r--r--en/devices/architecture/vintf/index.html113
-rw-r--r--en/devices/architecture/vintf/match-rules.html366
-rw-r--r--en/devices/architecture/vintf/objects.html262
-rw-r--r--en/devices/architecture/vintf/resources.html184
-rw-r--r--en/devices/architecture/vndk/deftool.html433
-rw-r--r--en/devices/architecture/vndk/dir-rules-sepolicy.html189
-rw-r--r--en/devices/architecture/vndk/extensions.html150
-rw-r--r--en/devices/architecture/vndk/index.html267
-rw-r--r--en/devices/architecture/vndk/linker-namespace.html154
-rw-r--r--en/devices/architecture/vndk/renderscript.html449
-rw-r--r--en/devices/audio/usb.html4
-rw-r--r--en/devices/automotive/camera-hal.html625
-rw-r--r--en/devices/automotive/images/vhal_evs_components.pngbin0 -> 57470 bytes
-rw-r--r--en/devices/automotive/images/vhal_evs_get_camera.pngbin0 -> 30059 bytes
-rw-r--r--en/devices/automotive/images/vhal_evs_manager.pngbin0 -> 17184 bytes
-rw-r--r--en/devices/automotive/images/vhal_evs_receive_frame.pngbin0 -> 11283 bytes
-rw-r--r--en/devices/automotive/index.html4
-rw-r--r--en/devices/automotive/ivi_connectivity.html270
-rw-r--r--en/devices/bluetooth.html128
-rw-r--r--en/devices/bluetooth/hci_requirements.html2311
-rw-r--r--en/devices/bluetooth/images/ape_fwk_bluetooth.pngbin0 -> 40601 bytes
-rw-r--r--en/devices/bluetooth/images/ape_fwk_hal_bluetooth.pngbin0 -> 2347 bytes
-rw-r--r--en/devices/bluetooth/images/bt_filter_batch_report.pngbin0 -> 19313 bytes
-rw-r--r--en/devices/bluetooth/images/bt_onfound_onlost.pngbin0 -> 22728 bytes
-rw-r--r--en/devices/bluetooth/images/fluoride_architecture.pngbin0 -> 23913 bytes
-rw-r--r--en/devices/bluetooth/index.html212
-rw-r--r--en/devices/bluetooth/verifying_debugging.html140
-rw-r--r--en/devices/camera/versioning.html85
-rw-r--r--en/devices/graphics/arch-sh.html4
-rw-r--r--en/devices/storage/config.html16
-rw-r--r--en/devices/storage/faster-stats.html106
-rw-r--r--en/devices/tech/config/ambient.html130
-rw-r--r--en/devices/tech/config/perms-whitelist.html192
-rw-r--r--en/devices/tech/config/usb-hal.html94
-rw-r--r--en/devices/tech/connect/oob-users.html170
-rw-r--r--en/devices/tech/dalvik/improvements.html206
-rw-r--r--en/devices/tech/debug/rescue-party.html107
-rw-r--r--en/devices/tech/debug/sanitizers.html356
-rw-r--r--en/devices/tech/debug/storaged.html96
-rw-r--r--en/devices/tech/display/adaptive-icons.html148
-rw-r--r--en/devices/tech/display/images/split-screen-example-ux.pngbin0 -> 423540 bytes
-rw-r--r--en/devices/tech/display/multi-window.html11
-rw-r--r--en/devices/tech/display/night-light.html28
-rw-r--r--en/devices/tech/display/pip.html181
-rw-r--r--en/devices/tech/display/split-screen.html108
-rw-r--r--en/devices/tech/display/widgets-shortcuts.html90
-rw-r--r--en/devices/tech/images/treble_latency_bubble.pngbin0 -> 15669 bytes
-rw-r--r--en/devices/tech/images/treble_priority_inv_rta.pngbin0 -> 12940 bytes
-rw-r--r--en/devices/tech/images/treble_priority_inv_rta_blocked.pngbin0 -> 14509 bytes
-rw-r--r--en/devices/tech/images/treble_systrace_binder_processes.pngbin0 -> 25305 bytes
-rw-r--r--en/devices/tech/images/treble_vts_dash_arch.pngbin0 -> 24354 bytes
-rw-r--r--en/devices/tech/images/treble_vts_dash_entity_ancestry.pngbin0 -> 12684 bytes
-rw-r--r--en/devices/tech/images/treble_vts_descend.pngbin0 -> 16138 bytes
-rw-r--r--en/devices/tech/images/treble_vts_descend_not.pngbin0 -> 10712 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_coverage.pngbin0 -> 45397 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_coverage_source.pngbin0 -> 108393 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_favorites.pngbin0 -> 61301 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_histogram.pngbin0 -> 37605 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_main.pngbin0 -> 30699 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_performance.pngbin0 -> 84547 bytes
-rw-r--r--en/devices/tech/images/treble_vts_ui_results.pngbin0 -> 64434 bytes
-rw-r--r--en/devices/tech/index.html30
-rw-r--r--en/devices/tech/ota/inside_packages.html24
-rw-r--r--en/devices/tech/perf/boot-times.html635
-rw-r--r--en/devices/tech/perf/flash-wear.html175
-rw-r--r--en/devices/tech/perf/task-snapshots.html115
-rw-r--r--en/devices/tech/settings/info-architecture.html292
-rw-r--r--en/devices/tech/settings/patterns-components.html157
-rw-r--r--en/devices/tech/settings/personalized.html77
-rw-r--r--en/devices/tech/settings/universal-search.html199
-rw-r--r--en/devices/tech/vts/database.html224
-rw-r--r--en/devices/tech/vts/index.html58
-rw-r--r--en/devices/tech/vts/performance.html473
-rw-r--r--en/devices/tech/vts/setup.html198
-rw-r--r--en/devices/tech/vts/ui.html161
-rw-r--r--en/reference/_toc.yaml30
-rw-r--r--en/reference/index.html50
-rw-r--r--en/security/_toc.yaml8
-rw-r--r--en/security/bulletin/2017-04-01.html54
-rw-r--r--en/security/bulletin/2017-05-01.html74
-rw-r--r--en/security/bulletin/2017-06-01.html159
-rw-r--r--en/security/bulletin/2017-07-01.html283
-rw-r--r--en/security/bulletin/2017-08-01.html14
-rw-r--r--en/security/images/access-to-keymaster.pngbin20055 -> 36530 bytes
-rw-r--r--en/security/keystore/attestation.html603
-rw-r--r--en/security/keystore/features.html227
-rw-r--r--en/security/keystore/implementer-ref.html1520
-rw-r--r--en/security/keystore/index.html74
-rw-r--r--en/security/keystore/tags.html732
-rw-r--r--en/security/keystore/version-binding.html176
-rw-r--r--en/security/selinux/customize.html15
-rw-r--r--en/security/selinux/device-policy.html18
-rw-r--r--en/security/selinux/implement.html14
-rw-r--r--en/security/selinux/index.html7
-rw-r--r--en/source/64-bit-builds.html2
-rw-r--r--en/source/build-numbers.html39
-rw-r--r--en/source/site-updates.html561
-rw-r--r--zh-cn/compatibility/cdd.html134
-rw-r--r--zh-cn/compatibility/cts/audio-framework.html4
-rw-r--r--zh-cn/compatibility/cts/camera-hal.html114
-rw-r--r--zh-cn/compatibility/cts/camera-its-box-assembly.html6
-rw-r--r--zh-cn/compatibility/cts/camera-its-box.html69
-rw-r--r--zh-cn/compatibility/cts/development.html32
-rw-r--r--zh-cn/compatibility/cts/downloads.html41
-rw-r--r--zh-cn/compatibility/cts/interpret.html12
-rw-r--r--zh-cn/compatibility/cts/run.html2
-rw-r--r--zh-cn/compatibility/cts/setup.html13
-rw-r--r--zh-cn/compatibility/cts/verifier.html36
-rw-r--r--zh-cn/compatibility/index.html18
-rw-r--r--zh-cn/devices/tech/admin/enterprise-telephony.html85
-rw-r--r--zh-cn/devices/tech/admin/managed-profiles.html114
-rw-r--r--zh-cn/devices/tech/admin/multi-user.html111
-rw-r--r--zh-cn/devices/tech/admin/provision.html122
-rw-r--r--zh-cn/devices/tech/admin/testing-setup.html75
-rw-r--r--zh-cn/devices/tech/config/connect_tests.html66
-rw-r--r--zh-cn/devices/tech/config/index.html25
-rw-r--r--zh-cn/devices/tech/config/kernel.html149
-rw-r--r--zh-cn/devices/tech/config/kernel_network_tests.html47
-rw-r--r--zh-cn/devices/tech/config/namespaces_libraries.html51
-rw-r--r--zh-cn/devices/tech/config/renderer.html179
-rw-r--r--zh-cn/devices/tech/connect/call-notification.html101
-rw-r--r--zh-cn/devices/tech/connect/emergency-affordance.html161
-rw-r--r--zh-cn/devices/tech/connect/felica.html44
-rw-r--r--zh-cn/devices/tech/connect/ril.html183
-rw-r--r--zh-cn/devices/tech/dalvik/configure.html285
-rw-r--r--zh-cn/devices/tech/dalvik/constraints.html532
-rw-r--r--zh-cn/devices/tech/dalvik/index.html92
-rw-r--r--zh-cn/devices/tech/datausage/excluding-network-types.html26
-rw-r--r--zh-cn/devices/tech/datausage/iface-overview.html28
-rw-r--r--zh-cn/devices/tech/datausage/index.html27
-rw-r--r--zh-cn/devices/tech/datausage/tags-explained.html34
-rw-r--r--zh-cn/devices/tech/datausage/usage-cycle-resets-dates.html25
-rw-r--r--zh-cn/devices/tech/debug/asan.html172
-rw-r--r--zh-cn/devices/tech/debug/dumpsys.html89
-rw-r--r--zh-cn/devices/tech/debug/eval_perf.html127
-rw-r--r--zh-cn/devices/tech/debug/ftrace.html169
-rw-r--r--zh-cn/devices/tech/debug/jank_capacity.html63
-rw-r--r--zh-cn/devices/tech/debug/native-crash.html400
-rw-r--r--zh-cn/devices/tech/debug/netstats.html125
-rw-r--r--zh-cn/devices/tech/debug/strace.html95
-rw-r--r--zh-cn/devices/tech/debug/systrace.html173
-rw-r--r--zh-cn/devices/tech/display/dnd.html51
-rw-r--r--zh-cn/devices/tech/display/index.html36
-rw-r--r--zh-cn/devices/tech/display/retail-mode.html191
-rw-r--r--zh-cn/devices/tech/index.html70
-rw-r--r--zh-cn/devices/tech/ota/ab_updates.html422
-rw-r--r--zh-cn/devices/tech/ota/block.html83
-rw-r--r--zh-cn/devices/tech/ota/reduce_size.html138
-rw-r--r--zh-cn/devices/tech/ota/tools.html86
-rw-r--r--zh-cn/devices/tech/power/batterystats.html517
-rw-r--r--zh-cn/devices/tech/test_infra/tradefed/fundamentals/devices.html44
-rw-r--r--zh-cn/devices/tech/test_infra/tradefed/fundamentals/options.html73
-rw-r--r--zh-cn/devices/tech/test_infra/tradefed/index.html61
262 files changed, 30775 insertions, 1890 deletions
diff --git a/en/_index.yaml b/en/_index.yaml
index 61e8df7c..ba6f2f4a 100644
--- a/en/_index.yaml
+++ b/en/_index.yaml
@@ -7,7 +7,7 @@ landing_page:
path: /source/downloading
rows:
- items:
- - heading: Android 7.1 updates!
+ - heading: Android 8.0 updates
description: >
Port the latest Android platform to create compelling
devices for your customers.
@@ -60,28 +60,29 @@ landing_page:
image_path: /images/android_stack.png
- heading: News
items:
- - heading: August Android Security Bulletin
+ - heading: Android 8.0 Documentation
description: >
- The August 2017 Android Security Bulletin has been published along with
- links to associated fixes and new build numbers to support the August
- Android security release.
+ Android 8.0 has been released! We've got you covered with complete
+ documentation on new features, improvements, and enhancements.
buttons:
- - label: August 8th, 2017
- path: /security/bulletin/2017-08-01
- - heading: A/B Update Enhancements
+ - label: August 21st, 2017
+ path: /source/site-updates
+ - heading: Project Treble
description: >
- A/B updates have been improved to stream updates in order to minimize
- resource contention and user interruption.
+ Treble is a major re-architect of the Android OS framework that makes it
+ easier, faster, and less costly to update devices to new versions of
+ Android.
buttons:
- - label: August 3rd, 2017
- path: /devices/tech/ota/ab_updates
- - heading: Customize the TV App
+ - label: August 21st, 2017
+ path: /devices/architecture/treble
+ - heading: HIDL Reference
description: >
- Live TV is a reference TV app designed for Android television devices.
- Learn about the supported customization options for Live TV.
+ The Reference section now includes details on the HAL Interface
+ Description Language (HIDL) that specifies the interface between a HAL
+ and its users.
buttons:
- - label: August 1st, 2017
- path: /devices/tv/customize-tv-app
+ - label: August 21st, 2017
+ path: /reference/hidl/index
- classname: devsite-landing-row-100 tf-row-centered
items:
- buttons:
diff --git a/en/compatibility/_toc-compatibility.yaml b/en/compatibility/_toc-compatibility.yaml
index 9e5c1851..31f19da6 100644
--- a/en/compatibility/_toc-compatibility.yaml
+++ b/en/compatibility/_toc-compatibility.yaml
@@ -29,6 +29,8 @@ toc:
path: /compatibility/cts/near-ultrasound
- title: Rotation Vector Crosscheck
path: /compatibility/cts/rotation-vector
+ - title: USB Audio CTS Tests
+ path: /compatibility/cts/usb-audio
- title: Camera Testing
section:
- title: Camera HAL Testing
diff --git a/en/compatibility/cts/downloads.html b/en/compatibility/cts/downloads.html
index ac3b661f..241043b5 100644
--- a/en/compatibility/cts/downloads.html
+++ b/en/compatibility/cts/downloads.html
@@ -28,6 +28,25 @@ you access to key documents and information about the program. As CTS is
updated, new versions are added to this page. CTS versions are denoted by
R&lt;number&gt; in the link name.</p>
+<h2 id="android-80">Android 8.0</h2>
+<p>Android 8.0 is the release of the development milestone code-named Oreo.
+The source code for the following tests can be synced with the
+'android-cts-8.0_r1' tag in the open-source tree.</p>
+<ul>
+<li><a
+href="https://dl.google.com/dl/android/cts/android-cts-8.0_r1-linux_x86-arm.zip">Android
+8.0 R1 Compatibility Test Suite (CTS) - ARM</a></li>
+<li><a
+href="https://dl.google.com/dl/android/cts/android-cts-8.0_r1-linux_x86-x86.zip">Android
+8.0 R1 Compatibility Test Suite (CTS) - x86</a></li>
+<li><a
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r1-linux_x86-arm.zip">Android
+8.0 R1 CTS Verifier - ARM</a></li>
+<li><a
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-8.0_r1-linux_x86-x86.zip">Android
+8.0 R1 CTS Verifier - x86</a></li>
+</ul>
+
<h2 id="android-71">Android 7.1</h2>
<p>Android 7.1 is the release of the development milestone code-named Nougat-MR1.
The source code for the following tests can be synced with the
diff --git a/en/compatibility/cts/images/analog_headphones.png b/en/compatibility/cts/images/analog_headphones.png
new file mode 100644
index 00000000..86adb88e
--- /dev/null
+++ b/en/compatibility/cts/images/analog_headphones.png
Binary files differ
diff --git a/en/compatibility/cts/images/attributes_connected.png b/en/compatibility/cts/images/attributes_connected.png
new file mode 100644
index 00000000..dbd4f297
--- /dev/null
+++ b/en/compatibility/cts/images/attributes_connected.png
Binary files differ
diff --git a/en/compatibility/cts/images/attributes_postconnect.png b/en/compatibility/cts/images/attributes_postconnect.png
new file mode 100644
index 00000000..e218a988
--- /dev/null
+++ b/en/compatibility/cts/images/attributes_postconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/attributes_preconnect.png b/en/compatibility/cts/images/attributes_preconnect.png
new file mode 100644
index 00000000..07eec6dd
--- /dev/null
+++ b/en/compatibility/cts/images/attributes_preconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/attributes_summary.png b/en/compatibility/cts/images/attributes_summary.png
new file mode 100644
index 00000000..70caf20b
--- /dev/null
+++ b/en/compatibility/cts/images/attributes_summary.png
Binary files differ
diff --git a/en/compatibility/cts/images/attributes_test.png b/en/compatibility/cts/images/attributes_test.png
new file mode 100644
index 00000000..eebef861
--- /dev/null
+++ b/en/compatibility/cts/images/attributes_test.png
Binary files differ
diff --git a/en/compatibility/cts/images/buttons_connected.png b/en/compatibility/cts/images/buttons_connected.png
new file mode 100644
index 00000000..e60910ee
--- /dev/null
+++ b/en/compatibility/cts/images/buttons_connected.png
Binary files differ
diff --git a/en/compatibility/cts/images/buttons_not_recognized.png b/en/compatibility/cts/images/buttons_not_recognized.png
new file mode 100644
index 00000000..574010fd
--- /dev/null
+++ b/en/compatibility/cts/images/buttons_not_recognized.png
Binary files differ
diff --git a/en/compatibility/cts/images/buttons_recognized.png b/en/compatibility/cts/images/buttons_recognized.png
new file mode 100644
index 00000000..04afd0cd
--- /dev/null
+++ b/en/compatibility/cts/images/buttons_recognized.png
Binary files differ
diff --git a/en/compatibility/cts/images/buttons_summary.png b/en/compatibility/cts/images/buttons_summary.png
new file mode 100644
index 00000000..04aaf318
--- /dev/null
+++ b/en/compatibility/cts/images/buttons_summary.png
Binary files differ
diff --git a/en/compatibility/cts/images/buttons_test.png b/en/compatibility/cts/images/buttons_test.png
new file mode 100644
index 00000000..dc44081c
--- /dev/null
+++ b/en/compatibility/cts/images/buttons_test.png
Binary files differ
diff --git a/en/compatibility/cts/images/otg_adapter.png b/en/compatibility/cts/images/otg_adapter.png
new file mode 100644
index 00000000..59dcb008
--- /dev/null
+++ b/en/compatibility/cts/images/otg_adapter.png
Binary files differ
diff --git a/en/compatibility/cts/images/patch_cables.png b/en/compatibility/cts/images/patch_cables.png
new file mode 100644
index 00000000..4ba8b6ad
--- /dev/null
+++ b/en/compatibility/cts/images/patch_cables.png
Binary files differ
diff --git a/en/compatibility/cts/images/peripheral_cable.png b/en/compatibility/cts/images/peripheral_cable.png
new file mode 100644
index 00000000..644a3ba5
--- /dev/null
+++ b/en/compatibility/cts/images/peripheral_cable.png
Binary files differ
diff --git a/en/compatibility/cts/images/play_connected.png b/en/compatibility/cts/images/play_connected.png
new file mode 100644
index 00000000..8fd3f45e
--- /dev/null
+++ b/en/compatibility/cts/images/play_connected.png
Binary files differ
diff --git a/en/compatibility/cts/images/play_postconnect.png b/en/compatibility/cts/images/play_postconnect.png
new file mode 100644
index 00000000..46f4c365
--- /dev/null
+++ b/en/compatibility/cts/images/play_postconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/play_preconnect.png b/en/compatibility/cts/images/play_preconnect.png
new file mode 100644
index 00000000..3ae66018
--- /dev/null
+++ b/en/compatibility/cts/images/play_preconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/play_summary.png b/en/compatibility/cts/images/play_summary.png
new file mode 100644
index 00000000..d6b058c3
--- /dev/null
+++ b/en/compatibility/cts/images/play_summary.png
Binary files differ
diff --git a/en/compatibility/cts/images/play_test.png b/en/compatibility/cts/images/play_test.png
new file mode 100644
index 00000000..4f51efaf
--- /dev/null
+++ b/en/compatibility/cts/images/play_test.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_connected.png b/en/compatibility/cts/images/record_connected.png
new file mode 100644
index 00000000..a3bf1f0e
--- /dev/null
+++ b/en/compatibility/cts/images/record_connected.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_connected_back.png b/en/compatibility/cts/images/record_connected_back.png
new file mode 100644
index 00000000..3b9b150d
--- /dev/null
+++ b/en/compatibility/cts/images/record_connected_back.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_connected_front.png b/en/compatibility/cts/images/record_connected_front.png
new file mode 100644
index 00000000..b3d7b295
--- /dev/null
+++ b/en/compatibility/cts/images/record_connected_front.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_postconnect.png b/en/compatibility/cts/images/record_postconnect.png
new file mode 100644
index 00000000..f0dda27f
--- /dev/null
+++ b/en/compatibility/cts/images/record_postconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_preconnect.png b/en/compatibility/cts/images/record_preconnect.png
new file mode 100644
index 00000000..2bb4aba1
--- /dev/null
+++ b/en/compatibility/cts/images/record_preconnect.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_summary.png b/en/compatibility/cts/images/record_summary.png
new file mode 100644
index 00000000..6d82fea6
--- /dev/null
+++ b/en/compatibility/cts/images/record_summary.png
Binary files differ
diff --git a/en/compatibility/cts/images/record_test.png b/en/compatibility/cts/images/record_test.png
new file mode 100644
index 00000000..de805cd7
--- /dev/null
+++ b/en/compatibility/cts/images/record_test.png
Binary files differ
diff --git a/en/compatibility/cts/images/usb_audio_interface.png b/en/compatibility/cts/images/usb_audio_interface.png
new file mode 100644
index 00000000..0f239bf5
--- /dev/null
+++ b/en/compatibility/cts/images/usb_audio_interface.png
Binary files differ
diff --git a/en/compatibility/cts/images/usb_headset.png b/en/compatibility/cts/images/usb_headset.png
new file mode 100644
index 00000000..c42d3d21
--- /dev/null
+++ b/en/compatibility/cts/images/usb_headset.png
Binary files differ
diff --git a/en/compatibility/cts/usb-audio.html b/en/compatibility/cts/usb-audio.html
new file mode 100644
index 00000000..6c8ca5b2
--- /dev/null
+++ b/en/compatibility/cts/usb-audio.html
@@ -0,0 +1,420 @@
+<html devsite>
+ <head>
+ <title>USB Audio CTS Verifier Tests</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>
+Several <a href="/compatibility/cts/">Android Compatibility Test Suite (CTS)</a>
+tests for <a href="https://source.android.com/devices/audio/usb">Android USB audio</a>
+require human intervention and the physical connection of USB audio
+peripherals. For these, additional CTS Verifier tests have been implemented.
+The requirements and protocols for these tests are explained in this document.
+</p>
+
+<h2 id="nomenclature">Nomenclature</h2>
+
+<p>
+Throughout this document, the term "device" and "peripheral" are used in a very
+precise manner:
+</p>
+<ul>
+<li><em>Device</em> refers to the Android device.</li>
+<li><em>Peripheral</em> is used to denote an external USB audio peripheral
+connected to the Android device.</li>
+</ul>
+
+<h2 id="recommended-peripherals">Recommended peripherals</h2>
+
+<p>
+In order for the USB audio CTS Verifier Tests to know the attributes and
+capabilities they are verifying, it is necessary to specify a set of known
+peripherals to test against. For this reason, specific brands and types are
+recommended below. Successful completion of the tests requires one peripheral of
+each category of peripherals specified below. Use of other types will cause the
+tests to fail.
+</p>
+
+<h3 id="usb-audio-interface">USB audio interface</h3>
+
+<p class="note"><strong>Note:</strong> This list is preliminary and subject to change.</p>
+
+<ul>
+<li><a href="http://www.presonus.com/products/audiobox-22VSL">Presonus AudioBox
+22VSL</a></li>
+<li><a href="https://www.presonus.com/products/audiobox-usb">Presonus AudioBox
+USB</a></li>
+</ul>
+
+<table>
+ <tr>
+ <td width="50%">A USB audio interface (A PreSonus AudioBox 22VSL)
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/usb_audio_interface.png" alt="USB audio interface" width="300"
+ id="usb_audio_interface" /></td>
+ </tr>
+</table>
+
+<h3 id="usb-headset">USB headset</h3>
+
+<p class="note"><strong>Note:</strong> This list is preliminary and subject to change.</p>
+
+<p>Google USB headset</p>
+
+<table>
+ <tr>
+ <td width="50%">A USB headset
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/usb_headset.png" alt="USB headset" width="300"
+ id="usb_headset" /></td>
+ </tr>
+</table>
+
+<h3 id="peripheral-profiles">Peripheral profiles</h3>
+
+<p>
+The USB Audio CTS Verifier Tests "know about" these recommended peripherals
+through built-in profiles provided by Android that describe the attributes and
+capabilities of a peripheral. When the peripheral is connected to the Android
+device under test, the correct profile is automatically selected.
+</p>
+
+<h2 id="required-additional-hardware">Required additional hardware</h2>
+
+<p>Patch cables (for loopback)
+2 short ¼" male to ¼" male patch cables to
+connect the outputs to the inputs of the USB</p>
+
+<table>
+ <tr>
+ <td width="50%">
+ ¼" male to ¼" male patch cables
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/patch_cables.png" alt="patch cables" width="300"
+ id="patch_cables" /></td>
+ </td>
+ </tr>
+</table>
+
+<p>USB peripheral cable</p>
+
+<table>
+ <tr>
+ <td width="50%">This cable (which typically comes with the peripheral), connects the USB
+audio peripheral to the host device
+ </td>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/peripheral_cable.png" alt="peripheral cable" width="300"
+ id="peripheral_cable" /></td>
+ </td>
+ </tr>
+</table>
+
+<p>USB "On The Go" (OTG) adapter</p>
+
+<table>
+ <tr>
+ <td width="50%">A USB "On The Go" (OTG) adapter is required to physically connect the
+peripheral to the Android device and indicate to the Android device that it
+should assume the role of "host"
+ </td>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/otg_adapter.png" alt="OTG adapter" width="300"
+ id="otg_adapter" /></td>
+ </td>
+ </tr>
+</table>
+
+<p>Analog headphones to monitor the output of the USB audio interface for the
+Play test.</p>
+
+<table>
+ <tr>
+ <td width="50%">Set of analog headphones.
+ </td>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/analog_headphones.png" alt="analog headphones" width="300"
+ id="analog_headphones" /></td>
+ </td>
+ </tr>
+</table>
+
+<h2 id="tests">Tests</h2>
+
+<p>
+In each test, indicate test success by clicking the <strong>test pass</strong>
+(check mark) button. Otherwise, indicate test failure by clicking the
+<strong>test fail</strong> (exclamation point) button.
+</p>
+
+<h3 id="attributes-test">Attributes test</h3>
+
+<h4 id="abstract">Abstract</h4>
+
+<p>
+This test verifies that the attributes (supported sample-rates, channel
+configurations, sample formats…) match the set of a-priori known attributes of
+the device.
+</p>
+
+<h4 id="process">Process</h4>
+
+<p>
+After invoking the test from the main menu, connect a USB audio peripheral. If
+the attributes match, the <strong>test pass</strong> (check mark) button will be
+enabled. Click the <strong>test pass</strong> button to indicate success. If the
+attributes do not match, indicate test failure by clicking the <strong>test
+fail</strong> (exclamation point) button.
+</p>
+
+<table>
+ <tr>
+ <td width="50%">Select <em>USB Audio Peripheral Attributes Test</em>.
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/attributes_test.png" alt="attributes test" width="300"
+ id="attributes test" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Summary of instructions is displayed
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/attributes_summary.png" alt="attributes summary" width="300"
+ id="attributes_summary" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Pre-connect screen
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/attributes_preconnect.png" alt="attributes
+ preconnect" width="300"
+ id="attributes_preconnect" /></td>
+ </tr>
+ <tr>
+ <td width="50%">USB audio peripheral connected to Android Device with peripheral cable
+and OTG adapter
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/attributes_connected.png" alt="attributes connected" width="300"
+ id="attributes_connected" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Post-connect screen
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/attributes_postconnect.png" alt="attributes post connection" width="300"
+ id="attributes_postconnect" /></td>
+ </tr>
+</table>
+
+<h3 id="play-test">Play test</h3>
+
+<h4 id="abstract">Abstract</h4>
+
+<p>
+This test verifies that audio playback is functioning. It does this by
+generating a 1KHz test tone and presenting it in stereo (two-channels) to the
+USB audio peripheral.
+</p>
+
+<h4 id="process">Process</h4>
+
+<p>
+After invoking the test from the main menu, connect the USB audio interface,
+including the analog headset to the headset output jack on the interface (for
+monitoring).
+</p>
+
+<p>
+Press the <strong>PLAY</strong> button. If the test tone is heard in both
+channels of the headset, indicate test pass by clicking the <strong>test
+pass</strong> (check mark) button. If either or both of the channels do not play
+the tone, indicate test failure by clicking the <strong>test fail</strong>
+(exclamation point) button.
+</p>
+
+<h4 id="notes">Notes</h4>
+
+<table>
+ <tr>
+ <td width="50%">Select <em>USB Audio Peripheral Play Test</em>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/play_test.png" alt="play test" width="300"
+ id="play_test" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Summary of instructions is displayed
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/play_summary.png" alt="play summary" width="300"
+ id="play_summary" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Pre-connect screen
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/play_preconnect.png" alt="play preconnect" width="300"
+ id="play_preconnect" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Connect the USB audio peripheral to the Android Device
+<p>
+The headphones are connected to the headphone output jack on the USB audio
+interface for monitoring
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/play_connected.png" alt="play connected" width="300"
+ id="play_connected" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Post-connect screen
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/play_postconnect.png" alt="play post connection" width="300"
+ id="play_postconnect" /></td>
+ </tr>
+</table>
+
+
+<h3 id="record-loopback-test">Record (loopback) test</h3>
+
+<h4 id="abstract">Abstract</h4>
+
+<p>
+This test verifies that audio recording is functioning. It does this by
+generating a tone at the outputs of the USB audio interface, which is then
+routed via patch cords to the inputs of the USB audio peripheral.
+</p>
+
+<h4 id="process">Process</h4>
+
+<p>
+After invoking the test from the main menu, connect the USB audio interface.
+Connect the analog outputs to the analog inputs with patch cables. Press the
+<strong>RECORD LOOPBACK</strong> button. If both the channels of the recorded
+test tone are shown in the view below, indicate test pass by clicking the
+<strong>test pass</strong> (check mark) button. If either or both of the
+channels does not display, indicate test failure by clicking the <strong>test
+fail</strong> (exclamation point) button.
+</p>
+
+<h4 id="notes">Notes</h4>
+
+<p>
+Ensure positive connection of both input and output jacks on the peripheral. It
+will be necessary to adjust the input levels to correctly display the recorded
+signal.
+</p>
+
+<table>
+ <tr>
+ <td width="50%">Select <em>USB Audio Peripheral Record Test</em>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_test.png" alt="record test" width="300"
+ id="record_test" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Summary of instructions is displayed
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_summary.png" alt="record summary" width="300"
+ id="record_summary" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Pre-connect screen
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_preconnect.png" alt="record preconnect" width="300"
+ id="record_preconnect" /></td>
+ </tr>
+ <tr>
+ <td width="50%">USB audio Interface with loopback connected to Android device
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_connected.png" alt="record connected" width="300"
+ id="record_connected" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Connections on the back of the USB audio interface
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_connected_back.png" alt="record connected in back" width="300"
+ id="record_connected_back" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Connections on the front of the USB audio interface
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_connected_front.png" alt="record connected in front" width="300"
+ id="record_connected_front" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Post-connect screen, with record test running
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/record_postconnect.png" alt="record post connection" width="300"
+ id="record_postconnect" /></td>
+ </tr>
+</table>
+<h3></h3>
+<h3 id="headset-buttons-test">Headset buttons test</h3>
+<h4 id="abstract">Abstract</h4>
+<p>
+This test verifies the <strong>media/transport </strong>buttons on the
+recommended headset are correctly recognized.
+</p>
+<h4 id="process">Process</h4>
+<p>
+After invoking the test from the main menu, connect the USB headset peripheral.
+Press each <strong>media/transport</strong> (play, pause, volume up & volume
+down) button on the headset. As each is recognized, it will be recognized in the
+test panel. When all buttons have been recognized, the <strong>test
+pass</strong> (check mark) button will be enabled. Click the <strong>test
+pass</strong> button to indicate success. If the full set of buttons is not
+recognized, indicate test failure by clicking the <strong>test fail</strong>
+(exclamation point) button.
+</p>
+<h4 id="notes">Notes</h4>
+<table>
+ <tr>
+ <td width="50%">The USB headset peripheral connected to the Android device
+<p>
+Note the OTG adapter
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/buttons_connected.png" alt="buttons connected" width="300"
+ id="buttons_connected" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Select <em>USB Audio Peripheral Buttons Test</em>
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/buttons_test.png" alt="buttons test" width="300"
+ id="buttons_test" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Summary of instructions is displayed
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/buttons_summary.png" alt="buttons summary" width="300"
+ id="buttons_summary" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Peripheral connected, but no buttons recognized (yet)
+<p>
+Note that the expected (buttons which are known to the device profile) are
+indicated with with white text; those that are not part of the test peripheral
+are displayed in grey text
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/buttons_not_recognized.png" alt="buttons not recognized" width="300"
+ id="buttons not recognized" /></td>
+ </tr>
+ <tr>
+ <td width="50%">Peripheral connected, and expected buttons recognized
+ </td>
+ <td width="50%"><img src="/compatibility/cts/images/buttons_recognized.png" alt="buttons recognized" width="300"
+ id="buttons recognized" /></td>
+ </tr>
+</table>
+
+</body>
+</html>
diff --git a/en/devices/_toc-interfaces.yaml b/en/devices/_toc-interfaces.yaml
index fc1d43a6..78759ac0 100644
--- a/en/devices/_toc-interfaces.yaml
+++ b/en/devices/_toc-interfaces.yaml
@@ -7,14 +7,132 @@ toc:
path: /devices/architecture/
- title: Hardware Abstraction Layer (HAL)
path: /devices/architecture/hal
+ - title: HAL Types
+ path: /devices/architecture/hal-types
- title: Treble
path: /devices/architecture/treble
- title: Kernel
section:
+ - title: Overview
+ path: /devices/architecture/kernel/
+ - title: Stable Releases & Updates
+ path: /devices/architecture/kernel/releases
+ - title: Modular Kernel Requirements
+ path: /devices/architecture/kernel/modular-kernels
+ - title: Interface Requirements
+ path: /devices/architecture/kernel/reqs-interfaces
- title: Configuration
path: /devices/architecture/kernel/config
+ - title: Kernel Hardening
+ path: /devices/architecture/kernel/hardening
+ - title: SquashFS
+ path: /devices/architecture/kernel/squashfs
+ - title: LLDB Debugging
+ path: /devices/architecture/kernel/lldb-debug
- title: Network Tests
path: /devices/architecture/kernel/network_tests
+ - title: HIDL (General)
+ section:
+ - title: Overview
+ path: /devices/architecture/hidl/
+ - title: Interfaces & Packages
+ path: /devices/architecture/hidl/interfaces
+ - title: Interface Hashing
+ path: /devices/architecture/hidl/hashing
+ - title: Services & Data Transfer
+ path: /devices/architecture/hidl/services
+ - title: Fast Message Queue
+ path: /devices/architecture/hidl/fmq
+ - title: Using Binder IPC
+ path: /devices/architecture/hidl/binder-ipc
+ - title: Network Stack Configuration Tools
+ path: /devices/architecture/hidl/network-stack
+ - title: Threading Models
+ path: /devices/architecture/hidl/threading
+ - title: Converting Modules
+ path: /devices/architecture/hidl/converting
+ - title: Data Types
+ path: /devices/architecture/hidl/types
+ - title: Versioning
+ path: /devices/architecture/hidl/versioning
+ - title: Code Style Guide
+ path: /devices/architecture/hidl/code-style
+ - title: HIDL (C++)
+ section:
+ - title: Overview
+ path: /devices/architecture/hidl-cpp/
+ - title: Packages
+ path: /devices/architecture/hidl-cpp/packages
+ - title: Interfaces
+ path: /devices/architecture/hidl-cpp/interfaces
+ - title: Data Types
+ path: /devices/architecture/hidl-cpp/types
+ - title: Functions
+ path: /devices/architecture/hidl-cpp/functions
+ - title: HIDL (Java)
+ section:
+ - title: Overview
+ path: /devices/architecture/hidl-java/
+ - title: Data Types
+ path: /devices/architecture/hidl-java/types
+ - title: Interface Errors & Methods
+ path: /devices/architecture/hidl-java/interfaces
+ - title: Exporting Constants
+ path: /devices/architecture/hidl-java/constants
+ - title: ConfigStore HAL
+ section:
+ - title: Overview
+ path: /devices/architecture/configstore/
+ - title: Creating the HAL Interface
+ path: /devices/architecture/configstore/interface
+ - title: Implementing the Service
+ path: /devices/architecture/configstore/service
+ - title: Client-Side Usage
+ path: /devices/architecture/configstore/client
+ - title: Adding Classes & Items
+ path: /devices/architecture/configstore/add-class-item
+ - title: Device Tree Overlays
+ section:
+ - title: Overview
+ path: /devices/architecture/dto/
+ - title: Implementing DTO
+ path: /devices/architecture/dto/implement
+ - title: DTO Syntax
+ path: /devices/architecture/dto/syntax
+ - title: Compiling & Verifying
+ path: /devices/architecture/dto/compile
+ - title: Using Multiple DTs
+ path: /devices/architecture/dto/multiple
+ - title: DTB/DTBO Partition Format
+ path: /devices/architecture/dto/partitions
+ - title: Optimizing DTO
+ path: /devices/architecture/dto/optimize
+ - title: Vendor NDK
+ section:
+ - title: Overview
+ path: /devices/architecture/vndk/
+ - title: VNDK Extensions
+ path: /devices/architecture/vndk/extensions
+ - title: VNDK Definition Tool
+ path: /devices/architecture/vndk/deftool
+ - title: Linker Namespace
+ path: /devices/architecture/vndk/linker-namespace
+ - title: Directories, Rules, and sepolicy
+ path: /devices/architecture/vndk/dir-rules-sepolicy
+ - title: Renderscript
+ path: /devices/architecture/vndk/renderscript
+ - title: Vendor Interface Object
+ section:
+ - title: Overview
+ path: /devices/architecture/vintf/
+ - title: VINTF Object Data
+ path: /devices/architecture/vintf/objects
+ - title: Compatibility Matrices
+ path: /devices/architecture/vintf/comp-matrices
+ - title: Matching Rules
+ path: /devices/architecture/vintf/match-rules
+ - title: Resources
+ path: /devices/architecture/vintf/resources
- title: Audio
section:
- title: Overview
@@ -79,8 +197,18 @@ toc:
path: /devices/automotive/
- title: Vehicle Properties
path: /devices/automotive/properties
+ - title: Camera HAL
+ path: /devices/automotive/camera-hal
+ - title: IVI Connectivity
+ path: /devices/automotive/ivi_connectivity
- title: Bluetooth
- path: /devices/bluetooth
+ section:
+ - title: Overview
+ path: /devices/bluetooth
+ - title: Verifying and Debugging
+ path: /devices/bluetooth/verifying_debugging
+ - title: HCI Requirements
+ path: /devices/bluetooth/hci_requirements
- title: Camera
section:
- title: Overview
@@ -260,6 +388,8 @@ toc:
path: /devices/storage/config
- title: Configuration Examples
path: /devices/storage/config-example
+ - title: Faster Statistics
+ path: /devices/storage/faster-stats
- title: TV
section:
- title: Overview
@@ -270,3 +400,4 @@ toc:
path: /devices/tv/reference-tv-app
- title: Customize the TV App
path: /devices/tv/customize-tv-app
+
diff --git a/en/devices/_toc-tech.yaml b/en/devices/_toc-tech.yaml
index da603b20..acbcf334 100644
--- a/en/devices/_toc-tech.yaml
+++ b/en/devices/_toc-tech.yaml
@@ -5,6 +5,8 @@ toc:
section:
- title: Overview
path: /devices/tech/dalvik
+ - title: Improvements
+ path: /devices/tech/dalvik/improvements
- title: Bytecode Format
path: /devices/tech/dalvik/dalvik-bytecode
- title: Dex Format
@@ -23,16 +25,22 @@ toc:
section:
- title: Overview
path: /devices/tech/config/
+ - title: Ambient Capabilities
+ path: /devices/tech/config/ambient
- title: Carrier Customization
path: /devices/tech/config/carrier
- title: File DAC Configuration
path: /devices/tech/config/filesystem
- title: Namespaces for Libraries
path: /devices/tech/config/namespaces_libraries
+ - title: Privileged Permission Whitelist
+ path: /devices/tech/config/perms-whitelist
- title: Runtime Permissions
path: /devices/tech/config/runtime_perms
- title: UICC
path: /devices/tech/config/uicc
+ - title: USB HAL
+ path: /devices/tech/config/usb-hal
- title: Visual Voicemail
path: /devices/tech/config/voicemail
- title: Connectivity
@@ -49,6 +57,8 @@ toc:
path: /devices/tech/connect/emergency-affordance
- title: Host Card Emulation of FeliCa
path: /devices/tech/connect/felica
+ - title: Out-of-Balance Users
+ path: /devices/tech/connect/oob-users
- title: Network Connectivity Tests
path: /devices/tech/connect/connect_tests
- title: Radio Interface Layer (RIL)
@@ -91,10 +101,16 @@ toc:
path: /devices/tech/debug/jank_jitter
- title: AddressSanitizer
path: /devices/tech/debug/asan
+ - title: LLVM Sanitizers
+ path: /devices/tech/debug/sanitizers
- title: Using GDB
path: /devices/tech/debug/gdb
- title: Native Memory Use
path: /devices/tech/debug/native-memory
+ - title: Rescue Party
+ path: /devices/tech/debug/rescue-party
+ - title: Storaged
+ path: /devices/tech/debug/storaged
- title: Strace
path: /devices/tech/debug/strace
- title: Valgrind
@@ -123,6 +139,8 @@ toc:
section:
- title: Overview
path: /devices/tech/display/
+ - title: Adaptive Icons
+ path: /devices/tech/display/adaptive-icons
- title: App Shortcuts
path: /devices/tech/display/app-shortcuts
- title: Circular Icons
@@ -135,10 +153,14 @@ toc:
path: /devices/tech/display/multi-window
- title: Night Light
path: /devices/tech/display/night-light
+ - title: Picture-in-picture
+ path: /devices/tech/display/pip
- title: Retail Demo Mode
path: /devices/tech/display/retail-mode
-- title: HAL File Reference
- path: /reference/hal/
+ - title: Split-Screen Interactions
+ path: /devices/tech/display/split-screen
+ - title: Widgets & Shortcuts
+ path: /devices/tech/display/widgets-shortcuts
- title: OTA Updates
section:
- title: Overview
@@ -161,8 +183,14 @@ toc:
section:
- title: Overview
path: /devices/tech/perf/
+ - title: Boot Times
+ path: /devices/tech/perf/boot-times
+ - title: Flash Wear Management
+ path: /devices/tech/perf/flash-wear
- title: Low RAM
path: /devices/tech/perf/low-ram
+ - title: Task Snapshots
+ path: /devices/tech/perf/task-snapshots
- title: Power
section:
- title: Overview
@@ -183,6 +211,14 @@ toc:
section:
- title: Overview
path: /devices/tech/settings/
+ - title: Patterns and Components
+ path: /devices/tech/settings/patterns-components
+ - title: Information Architecture
+ path: /devices/tech/settings/info-architecture
+ - title: Personalized Settings
+ path: /devices/tech/settings/personalized
+ - title: Universal Search
+ path: /devices/tech/settings/universal-search
- title: Testing Infrastructure
section:
- title: Overview
@@ -199,7 +235,19 @@ toc:
path: /devices/tech/test_infra/tradefed/fundamentals/options
- title: An End-to-End Example
path: /devices/tech/test_infra/tradefed/full_example
- - title: Systems Testing with VTS
- path: /devices/tech/test_infra/tradefed/fundamentals/vts
- title: Package Index
path: /reference/tradefed/
+- title: Vendor Test Suite (VTS)
+ section:
+ - title: Overview
+ path: /devices/tech/vts/
+ - title: Systems Testing with VTS
+ path: /devices/tech/test_infra/tradefed/fundamentals/vts
+ - title: VTS Dashboard Setup
+ path: /devices/tech/vts/setup
+ - title: VTS Dashboard Database
+ path: /devices/tech/vts/database
+ - title: VTS Dashboard UI
+ path: /devices/tech/vts/ui
+ - title: Performance Testing
+ path: /devices/tech/vts/performance
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 &lt;android/hardware/configstore/1.0/IChargerConfigs.h&gt;
+#include "ChargerConfigs.h"
+
+using android::hardware::configstore::V1_0::IChargerConfigs;
+using android::hardware::configstore::V1_0::implementation::ChargerConfigs;
+
+int main() {
+ ... // other code
+ sp&lt;IChargerConfigs&gt; chargerConfigs = new ChargerConfigs;
+ status = chargerConfigs-&gt;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">
+ &lt;hal format="hidl"&gt;
+ &lt;name&gt;android.hardware.configstore&lt;/name&gt;
+ ...
+ &lt;interface&gt;
+ &lt;name&gt;IChargerConfigs&lt;/name&gt;
+ &lt;instance&gt;default&lt;/instance&gt;
+ &lt;/interface&gt;
+ &lt;/hal&gt;
+</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&lt;void&gt; 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&lt;void&gt; 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 &lt;android/hardware/configstore/1.0/IChargerConfigs.h&gt;
+#include &lt;configstore/Utils.h&gt;
+</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&lt;
+ IChargerConfigs,
+ &IChargerConfigs::disableInitBlank&gt;(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>&lt;configstore/Utils.h&gt;</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 &lt;configstore/Utils.h&gt;
+using namespace android::hardware::configstore;
+using namespace android::hardware::configstore::V1_0;
+
+static bool vsyncPhaseOffsetNs = getBool&lt;ISurfaceFlingerConfigs,
+ ISurfaceFlingerConfigs::forceHwcForVirtualDisplays&gt;(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>&lt;configstore/Utils.h&gt;</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-&gt;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()-&gt;v1_0API(); // NOT ALLOWED
+
+V1_0::IConfig::getService()-&gt;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()-&gt;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 &amp; 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>&lt;modulename&gt;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&lt;void&gt; 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&lt;void&gt; 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_&lt;interface name&gt;</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&lt;ISurfaceFlingerConfigs&gt; surfaceFlingerConfigs = new SurfaceFlingerConfigs;
+status_t status = surfaceFlingerConfigs-&gt;registerAsService();
+
+sp&lt;IBluetoothConfigs&gt; bluetoothConfigs = new BluetoothConfigs;
+status = bluetoothConfigs-&gt;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>
diff --git a/en/devices/architecture/dto/compile.html b/en/devices/architecture/dto/compile.html
new file mode 100644
index 00000000..65e3cbc2
--- /dev/null
+++ b/en/devices/architecture/dto/compile.html
@@ -0,0 +1,103 @@
+<html devsite>
+ <head>
+ <title>Compiling &amp; Verifying</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 use Device Tree Compiler (DTC) to compile the Device Tree Source
+files. However, before applying the overlay DT on the target main DT, you should
+also verify the result by simulating the behavior of DTO.</p>
+
+<h2 id=compile>Compiling with DTC</h2>
+<p>When using <code>dtc</code> to compile <code>.dts</code>, you must add option
+<code>-@</code> to add a <code>__symbols__</code> node in the resulting
+<code>.dtbo</code>. The <code>__symbols__</code> node contains a list of all
+nodes that are marked with a label, which the DTO library can use for
+references.</p>
+
+<p>Sample command to build main DT <code>.dts</code>:</p>
+
+<pre class="devsite-terminal">
+dtc -@ -O dtb -o my_main_dt.dtb my_main_dt.dts
+</pre>
+
+<p>Sample command to build the overlay DT <code>.dts</code>:</p>
+
+<pre class="devsite-terminal">
+dtc -@ -O dtb -o my_overlay_dt.dtbo my_overlay_dt.dts
+</pre>
+
+<p class="note"><strong>Note:</strong> If you encounter the DTC build error:
+<code>invalid option --'@'</code>, you might need to update your DTC version.
+Upstream of AOSP, the official DTC supports DTO as of
+<a href="https://github.com/dgibson/dtc/tree/v1.4.4" class="external">version
+1.4.4</a> and most patches are merged after December 2016. For DTO support, we
+recommend using the
+<code><a href="https://android.googlesource.com/platform/external/dtc/" class="external">external/dtc</code></a>
+in AOSP, which is synced with the latest DTC (with DTO patches merged as
+needed).</p>
+
+<h2 id=verify>Verify DTO results on the host</h2>
+<p>Verification can help you identify errors that might occur when placing the
+overlay DT on the main DT. Before updating the target, you can verify the
+result of overlaying DT on the host by simulating the behavior of DTO using
+<code>/include/</code> in <code>.dts</code>.</p>
+
+<p class="note"><strong>Note:</strong> <code>/include/</code> does NOT support
+the use of <code>__overlay__</code> in overlay DT sources.</p>
+
+<p><img src="../images/treble_dto_simulate.png"></p>
+<p><strong>Figure 1.</strong> Use syntax <code>/include/</code> to simulate DTO
+on the host.</p>
+
+<ol>
+<li>Create a copy of the overlay <code>.dts</code>. In the copy, remove the
+first line header. Example:
+<pre>
+/dts-v1/;
+/plugin/;
+</pre>
+Save the file as <code>my_overlay_dt_wo_header.dts</code> (or any filename you
+want).</li>
+
+<li>Create a copy of the main <code>.dts</code>. In the copy, after the last
+line, append the include syntax for the file you created in step 1. For example:
+<pre>
+/include/ "my_overlay_dt_wo_header.dts"
+</pre>
+Save the file as <code>my_main_dt_with_include.dts</code> (or any filename you
+want).</li>
+
+<li>Use <code>dtc</code> to compile <code>my_main_dt_with_include.dts</code> to
+get the merged DT, which should be the same result as DTO. For example:
+<pre class="devsite-terminal">
+dtc -@ -O dtb -o my_merged_dt.dtb my_main_dt_with_include.dts
+</pre>
+</li>
+
+<li>Use <code>dtc</code> to dump <code>my_merged_dt.dto</code>.
+<pre class="devsite-terminal">
+dtc -O dts -o my_merged_dt.dts my_merged_dt.dtb
+</pre>
+</li>
+</ol>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/implement.html b/en/devices/architecture/dto/implement.html
new file mode 100644
index 00000000..5d10a92c
--- /dev/null
+++ b/en/devices/architecture/dto/implement.html
@@ -0,0 +1,187 @@
+<html devsite>
+ <head>
+ <title>Implementing DTOs</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>Implementing DTO involves dividing the device tree, building, partitioning,
+and running. After you have a working implementation, you must also maintain
+compatibility between the two DTs and determine a strategy for ensuring the
+security of each DT partition.</p>
+
+<h2 id=divide>Dividing the DT</h2>
+<p>Start by dividing the device tree into two (2) parts:</p>
+<ul>
+<li><strong>Main DT</strong>. The SoC-only part and the default configurations,
+provided by SoC vendor.</li>
+<li><strong>Overlay DT</strong>. The device-specific configurations, provided by
+ODM/OEM.</li>
+</ul>
+<p>After dividing the device trees, you must ensure compatibility between main
+DT and overlay DT so that merging main DT and overlay DT results in a complete
+DT for the device. For details on DTO format and rules, see
+<a href="/devices/architecture/dto/syntax.html">DTO Syntax</a>. For details on
+multiple device trees, see
+<a href="/devices/architecture/dto/multiple.html">Multiple DTs</a>.</p>
+
+<h2 id=build>Building main &amp; overlay DTs</h2>
+<p>To build the main DT:</p>
+<ol>
+<li>Compile main DT <code>.dts</code> into <code>.dtb</code> file.</li>
+<li>Flash <code>.dtb</code> file into a bootloader runtime-accessible partition
+(detailed below).</li>
+</ol>
+
+<p>To build the overlay DT:</p>
+<ol>
+<li>Compile overlay DT <code>.dts</code> into <code>.dtbo</code> file. While
+this file format is the same as the <code>.dtb</code> file formatted as a
+flattened device tree, the different file extension distinguishes it from the
+main DT.
+</li>
+<li>Flash <code>.dtbo</code> file into a bootloader runtime-accessible partition
+(as detailed below).</li>
+</ol>
+
+<p>For details on compiling with DTC and verifying DTO results on the host, see
+<a href="/devices/architecture/dto/compile.html">Compiling &amp; Verifying</a>.
+</p>
+
+<h2 id=partition>Partitioning DTs</h2>
+<p>Determine a bootloader runtime-accessible and trusted location in flash
+memory to put <code>.dtb</code> and <code>.dtbo</code>.</p>
+
+<p>Example locations for the main DT:</p>
+<ul>
+<li>Part of boot partition, appended to the kernel (<code>image.gz</code>).</li>
+<li>Separate DT blobs (<code>.dtb</code>) in dedicated partition
+(<code>dtb</code>).</li>
+</ul>
+
+<p>Example locations for the overlay DT:</p>
+
+<div style="width:75%">
+<div class="attempt-left">
+<table><tr><th style="text-align: center;">Unique Partition</th></tr></table>
+<figure id="treble_dto_dtbo_partition_1">
+<img src="../images/treble_dto_dtbo_partition_1.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 1.</strong> Put <code>.dtbo</code> into a unique partition, e.g.
+<code>dtbo</code> partition.
+</figcaption>
+</figure>
+</div>
+<div class="attempt-right">
+<figure id="treble_dto_dtbo_partition_2">
+<table><tr><th style="text-align: center;">ODM Partition</th></tr></table>
+<img src="../images/treble_dto_dtbo_partition_2.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 2.</strong> Put <code>.dtbo</code> into <code>odm</code>
+partition (do this only if your bootloader has capability to load data from the
+filesystem of <code>odm</code> partition).
+</figcaption>
+</figure>
+</div>
+</div>
+
+<p class="note" style="clear:both"><strong>Note:</strong> The size of the
+overlay DT partition depends on the device and the amount of changes needed on
+top of the main DT blob. Typically, 8 MB is more than enough and allows room to
+grow in the future if required.</p>
+
+<p>For devices that support
+<a href="https://source.android.com/devices/tech/ota/ab_updates.html">seamless
+(A/B) updates</a>, A/B the main DT and overlay DT partitions:</p>
+
+<div style="width:75%">
+<div class="attempt-left">
+<table><tr><th style="text-align: center;">Example 1</th></tr></table>
+<figure id="treble_dto_dtbo_ab_1">
+<img src="../images/treble_dto_dtbo_ab_1.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 3.</strong> DTBO partition A/B, example 1.
+</figcaption>
+</figure>
+</div>
+<div class="attempt-right">
+<table><tr><th style="text-align: center;">Example 2</th></tr></table>
+<figure id="treble_dto_dtbo_ab_2">
+<img src="../images/treble_dto_dtbo_ab_2.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 4.</strong> DTBO partition A/B, example 2.
+</figcaption>
+</figure>
+</div>
+</div>
+
+<h2 id=run style="clear:both">Running in bootloader</h2>
+<p>To run:</p>
+
+<figure id=treble_dto_dtbo>
+<img src="../images/treble_dto_dtbo.png">
+<figcaption><strong>Figure 5.</strong> Typical runtime implementation for device
+tree overlay in bootloader.</figcaption>
+</figure>
+
+<ol>
+<li>Load <code>.dtb</code> from storage into memory.</li>
+<li>Load <code>.dtbo</code> from storage into memory.</li>
+<li>Overlay <code>.dtb</code> with <code>.dtbo</code> to be a merged DT.</li>
+<li>Start kernel given the memory address of the merged DT.</li>
+</ol>
+
+<h2 id=maintain>Maintaining compatibility</h2>
+<p>The main DTB (from SoC vendor) is treated as an API surface for DTBOs. After
+separating the device tree into a SoC-common part and a device-specific part,
+you must keep the two parts mutually compatible in the future, including:</p>
+
+<ul>
+<li><strong>DT definition in main DT</strong> <em>(e.g. nodes, properties,
+labels)</em>. Any definition change in main DT could trigger changes in overlay
+DT. For example, to correct a node name in main DT, define an "alias" label that
+maps to the original node name (to avoid the change of overlay DT).</li>
+<li><strong>Overlay DT store location</strong> <em>(e.g. partition name, store
+format)</em>.</li>
+</ul>
+
+<h2 id=security>Ensuring security</h2>
+<p>Bootloader must ensure the DTB/DTBO is secure, unmodified, and uncorrupted.
+You could use any solution to secure DTB/DTBO, for example,
+<a href="/security/verifiedboot/verified-boot#signature_format">Boot image
+signature</a> in VBoot 1.0 or
+<a href="https://android.googlesource.com/platform/external/avb/+/master/README.md#The-VBMeta-struct" class="external">AVB HASH footer</a> (VBoot 2.0).
+</p>
+
+<ul>
+<li>If DTB/DTBO is in a unique partition, you can add that partition to the
+trust chain of AVB. The trust chain starts from a hardware-protected root of
+trust and goes to the bootloader, which verifies the integrity and authenticity
+of DTB/DTBO partition.</li>
+<li>If DTB/DTBO is in an existing partition (such as the <code>odm</code>
+partition), that partition should be in the trust chain of AVB. (DTBO partition
+could share a public key with <code>odm</code> partition).</li>
+</ul>
+
+<p>For details, refer to <a href="/security/verifiedboot/index.html">Verified
+Boot</a>.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/index.html b/en/devices/architecture/dto/index.html
new file mode 100644
index 00000000..3fdf3c28
--- /dev/null
+++ b/en/devices/architecture/dto/index.html
@@ -0,0 +1,144 @@
+<html devsite>
+ <head>
+ <title>Device Tree Overlays</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>A device tree (DT) is a data structure of named nodes and properties that
+describe non-discoverable hardware. Operating systems, such as the Linux kernel
+used in Android, use DTs to support a wide range of hardware configurations used
+by Android-powered devices. Hardware vendors supply their own DT source files,
+which Linux then compiles into the Device Tree Blob (DTB) file used by the
+bootloader.</p>
+
+A <a href="https://lkml.org/lkml/2012/11/5/615" class="external">device tree
+overlay</a> (DTO) enables a central DTB to be overlaid on the device tree. A
+bootloader using DTO can maintain the system-on-chip (SoC) DT and dynamically
+overlay a device-specific DT, adding nodes to the tree and making changes to
+properties in the existing tree.</p>
+
+<p>This page details a typical bootloader workflow for loading a DT and provides
+a list of common DT terms. Other pages in this section describe how to
+<a href="/devices/architecture/dto/implement.html">implement bootloader support
+for DTO</a>, how to
+<a href="/devices/architecture/dto/compile.html">compile</a>, verify, and
+<a href="/devices/architecture/dto/optimize.html">optimize your DTO
+implementation</a>, and how to
+<a href="/devices/architecture/dto/multiple.html">use multiple DTs</a>. You can
+also get details on <a href="/devices/architecture/dto/syntax.html">DTO
+syntax</a> and recommended
+<a href="/devices/architecture/dto/partition.html">DTO/DTBO partition
+formatting</a>.</p>
+
+<h2 id=load-dt>Loading a device tree</h2>
+<p>Loading a device tree in bootloader involves building, partitioning, and
+running.</p>
+
+<figure id="treble_dto_bootloader">
+<img src="../images/treble_dto_bootloader.png">
+<figcaption><strong>Figure 1.</strong> Typical implementation for loading device
+tree in bootloader.</figcaption>
+</figure>
+
+<ol>
+<li>To build:
+<ul>
+<li>Use the device tree compiler (<code>dtc</code>) to compile device tree
+source (<code>.dts</code>) into a device tree blob (<code>.dtb</code>),
+formatted as a flattened device tree.</li>
+<li>Flash the <code>.dtb</code> file into a bootloader runtime-accessible
+location (detailed below).</li>
+</ul>
+</li>
+<li>To partition, determine a bootloader runtime-accessible and trusted location
+in flash memory to put <code>.dtb</code>. Example locations:
+
+<div style="width:75%">
+<div class="attempt-left">
+<table><tr><th style="text-align: center;">Boot Partition</th></tr></table>
+<figure id="treble_dto_partition_1">
+<img src="../images/treble_dto_partition_1.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 2.</strong> Put <code>.dtb</code> in boot partition by appending
+to <code>image.gz</code> and passing as "<code>kernel</code>" to
+<code>mkbootimg</code>.
+</figcaption>
+</figure>
+</div>
+<div class="attempt-right">
+<table><tr><th style="text-align: center;">Unique Partition</th></tr></table>
+<figure id="treble_dto_partition_2">
+<img src="../images/treble_dto_partition_2.png" style="display:block; margin:0 auto">
+<figcaption>
+<strong>Figure 3.</strong> Put <code>.dtb</code> in an unique partition (e.g.
+<code>dtb</code> partition).
+</figcaption>
+</figure>
+</div>
+</div>
+</li>
+
+<li style="clear:both">To run:
+<ul>
+<li>Load <code>.dtb</code> from storage into memory.</li>
+<li>Start kernel given the memory address of the loaded DT.</li>
+</ul>
+</li>
+</ol>
+
+<h2 id=terms>Terminology</h2>
+<p>This section uses the following device tree terms:</p>
+<table>
+<tbody>
+<tr>
+<th>DT</th>
+<td>Device Tree</td>
+</tr>
+<tr>
+<th>DTB</th>
+<td>Device Tree Blob</td>
+</tr>
+<tr>
+<th>DTBO</th>
+<td>Device Tree Blob for Overlay</td>
+</tr>
+<tr>
+<th>DTC</th>
+<td>Device Tree Compiler</td>
+</tr>
+<tr>
+<th>DTO</th>
+<td>Device Tree Overlay</td>
+</tr>
+<tr>
+<th>DTS</th>
+<td>Device Tree Source</td>
+</tr>
+<tr>
+<th>FDT</th>
+<td>Flattened Device Tree, a binary format contained in a <code>.dtb</code> blob
+file</td>
+</tr>
+</tbody>
+</table>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/multiple.html b/en/devices/architecture/dto/multiple.html
new file mode 100644
index 00000000..52f47a46
--- /dev/null
+++ b/en/devices/architecture/dto/multiple.html
@@ -0,0 +1,75 @@
+<html devsite>
+ <head>
+ <title>Using Multiple DTs</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>Many SoC vendors and ODMs support the use of multiple DTs on a device,
+enabling one image to power multiple SKUs/configurations. In such cases, the
+bootloader identifies the hardware and loads the corresponding DT at runtime:
+</p>
+
+<p><img src="../images/treble_dto_multiple_dt.png"></p>
+<figcaption><strong>Figure 1.</strong> Multiple device trees overlay in
+bootloader.</figcaption>
+
+<p class="note"><strong>Note:</strong> Using multiple DTs is not mandatory.</p>
+
+<h2 id=setting>Setting up</h2>
+<p>To add support for multiple DTs to the DTO model, set up a list of main DTs
+and another list of overlay DTs.</p>
+
+<p><img src="../images/treble_dto_multiple_dt_runtime.png"></p>
+<figcaption><strong>Figure 2.</strong> Runtime DTO implementation for multiple
+DTs.</figcaption>
+
+<p>The bootloader should be able to:</p>
+
+<ul>
+<li>read the SoC ID and select the main DT correspondingly, and</li>
+<li>read the board ID and select the overlay DT accordingly.</li>
+</ul>
+
+<p>Only one main DT and one overlay DT are selected for use at runtime, and the
+selected pair must be compatible.</p>
+
+<h2 id=partition>Partitioning</h2>
+<p>To partition, determine a bootloader runtime-accessible and trusted location
+in flash memory to store the DTBs and DTBOs (bootloader must be able to locate
+these files in the matching process). Keep in mind that DTBs and DTBOs can not
+exist in the same partition. If your DTBs/DTBOs are in the
+<code>dtb</code>/<code>dtbo</code> partition, use the table structure and header
+format detailed in <a href="/devices/architecture/dto/partitions.html">DTB/DTBO
+Partition Format</a>.</p>
+
+<h2 id=runtime>Running in bootloader</h2>
+<p>To run:</p>
+<ol>
+<li><strong>Identify the SoC</strong> and load the corresponding .dtb from
+storage into memory.</li>
+<li><strong>Identify the board</strong> and load the corresponding
+<code>.dtbo</code> from storage into memory.</li>
+<li>Overlay the <code>.dtb</code> with the <code>.dtbo</code> to be a merged
+DT.</li>
+<li>Start kernel given the memory address of the merged DT.</li>
+</ol>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/optimize.html b/en/devices/architecture/dto/optimize.html
new file mode 100644
index 00000000..7502d7ad
--- /dev/null
+++ b/en/devices/architecture/dto/optimize.html
@@ -0,0 +1,299 @@
+<html devsite>
+ <head>
+ <title>Optimizing DTOs</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>This page details optimizations you can make to your DTO implementation,
+describes restrictions against overlaying the root node, and provides sample
+implementation instructions and code.</p>
+
+<h2 id=kernel>Kernel command line</h2>
+<p>The original kernel command line in device tree is located in the
+<code>chosen/bootargs</code> node. The bootloader must concatenate this location
+with other sources of kernel command line:</p>
+<pre class="prettyprint">
+/dts-v1/;
+
+/ {
+ chosen: chosen {
+ bootargs = "...";
+ };
+};
+</pre>
+
+<p>DTO <strong>cannot</strong> concatenate values from main DT and overlay DT.
+We recommend putting the kernel command line of the main DT in
+<code>chosen/bootargs</code> and the kernel command line of the overlay DT in
+<code>chosen/bootargs_ext</code>. Bootloader can then concatenate these
+locations and pass the result to the kernel.</p>
+
+<table>
+<tr>
+<th width="50%">main.dts</th>
+<th>overlay.dts</th>
+</tr>
+<tr>
+<td>
+<pre class="prettyprint">
+/dts-v1/;
+
+/ {
+ chosen: chosen {
+ bootargs = "...";
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+/dts-v1/;
+/plugin/;
+
+&amp;chosen {
+ bootargs_ext = "...";
+};
+</pre>
+</td>
+</tr>
+</table>
+
+<h2 id=libufdt>libufdt</h2>
+<p>While the latest
+<code><a href="https://github.com/dgibson/dtc/tree/master/libfdt" class="external">libfdt</code></a>
+supports DTO, we recommend using <code>libufdt</code> to implement DTO (source
+at
+<code><a href="https://android.googlesource.com/platform/system/libufdt/+/refs/heads/master" class="external">platform/system/libufdt</code></a>
+in AOSP). <code>libufdt</code> builds a real tree structure (un-flattened device
+tree, or <em>ufdt</em>) from the flattened device tree (FDT), so it can improve
+the merging of two <code>.dtb</code> files from O(N2) to O(N), where N is the
+number of nodes in the tree.</p>
+
+<h3 id=performance>Performance testing</h3>
+<p>In Google's internal testing, using <code>libufdt</code> on 2405
+<code>.dtb</code> and 283 <code>.dtbo</code> DT nodes results in file sizes of
+70,618 and 8,566 bytes after compilation. Compared with a
+<a href="http://fxr.watson.org/fxr/source/boot/fdt/" class="external">DTO
+implementation</a> ported from FreeBSD (124ms runtime), <code>libufdt</code>
+DTO runtime is 10ms.</p>
+
+<p>In performance testing for Pixel devices, we compared <code>libufdt</code>
+and <code>libfdt</code>. The number of base nodes effect is similar, but
+includes the following differences:</p>
+<ul>
+<li>500 overlay (append or override) operations have 6~8x time difference</li>
+<li>1000 overlay (append or override) operations have 8~10x time difference</li>
+</ul>
+
+<p>Example with appending count set to X:</p>
+<p><img src="../images/treble_dto_appending.png"></p>
+<figcaption><strong>Figure 1.</strong> Appending count is X.</figcaption>
+
+<p>Example with overriding count set to X:</p>
+<p><img src="../images/treble_dto_overriding.png"></p>
+<figcaption><strong>Figure 2.</strong> Overriding count is X.</figcaption>
+
+<p><code>libufdt</code> is developed with some <code>libfdt</code> APIs and data
+structures. When using <code>libufdt</code>, you must include and link
+<code>libfdt</code> (however in your code you can use <code>libfdt</code> API to
+operate DTB or DTBO).</p>
+
+<h3 id=api>libufdt DTO API</h3>
+<p>The main API to DTO in <code>libufdt</code> is as follows:</p>
+<pre class="prettyprint">
+struct fdt_header *ufdt_apply_overlay(
+ struct fdt_header *main_fdt_header,
+ size_t main_fdt_size,
+ void *overlay_fdt,
+ size_t overlay_size);
+</pre>
+
+<p>The parameter <code>main_fdt_header</code> is the main DT and
+<code>overlay_fdt</code> is the buffer containing the contents of a
+<code>.dtbo</code> file. The return value is a new buffer containing the merged
+DT (or <code>null</code> in case of error). The merged DT is formated in FDT,
+which you can pass to the kernel when starting the kernel.</p>
+
+<p>The new buffer from the return value is created by <code>dto_malloc()</code>,
+which you should implement when porting <code>libufdt</code> into bootloader.
+For reference implementations, refer to
+<code>sysdeps/libufdt_sysdeps_*.c</code>.</p>
+
+<h2 id=root>Root node restrictions</h2>
+<p>You cannot overlay a new node or property into the root node of main DT
+because overlay operations rely on labels. Because the main DT must define a
+label and the overlay DT assigns the nodes to be overlaid with labels, we
+cannot give a label for the root node (and therefore cannot overlay the root
+node).</p>
+
+<p>SoC vendors must define the overlaying ability of main DT; ODM/OEMs can only
+append or override nodes with labels defined by the SoC vendor. As a workaround,
+you can define a <strong><code>odm</code></strong> node under the root node in
+base DT, enabling all ODM nodes in overlay DT to add new nodes. Alternatively,
+you could put all SoC-related nodes in the base DT into a
+<strong><code>soc</code></strong> node under root node as described below:</p>
+
+<table>
+<tr>
+<th width="50%">main.dts</th>
+<th>overlay.dts</th>
+</tr>
+<tr>
+<td>
+<pre>
+/dts-v1/;
+
+/ {
+ compatible = "corp,bar";
+ ...
+
+ chosen: chosen {
+ bootargs = "...";
+ };
+
+ /* nodes for all soc nodes */
+ soc {
+ ...
+ soc_device@0: soc_device@0 {
+ compatible = "corp,bar";
+ ...
+ };
+ ...
+ };
+
+ odm: odm {
+ /* reserved for overlay by odm */
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+/dts-v1/;
+/plugin/;
+
+/ {
+};
+
+&amp;chosen {
+ bootargs_ex = "...";
+};
+
+&amp;odm {
+ odm_device@0 {
+ ...
+ };
+ ...
+};
+</pre>
+</td>
+</tr>
+</table>
+
+<h2 id=sample>Sample DTO implementation</h2>
+<p>The following instructions walk you through a sample implementation of DTO
+with <code>libufdt</code> (sample code below).</p>
+
+<h3 id=sample-instructions>Sample DTO instructions</h3>
+
+<ol>
+<li>Include libraries. To use <code>libufdt</code>, include <code>libfdt</code>
+for data structures and APIs:
+<pre class="prettyprint">
+#include &lt;libfdt.h&gt;
+#include &lt;ufdt_overlay.h&gt;
+</pre>
+</li>
+
+<li>Load main DT and overlay DT. Load <code>.dtb</code> and <code>.dtbo</code>
+from storage into memory (exact steps depend on your design). At this point, you
+should have the buffer and size of <code>.dtb</code>/<code>.dtbo</code>:
+<pre class="prettyprint">
+main_size = my_load_main_dtb(main_buf, main_buf_size)
+</pre>
+<pre class="prettyprint">
+overlay_size = my_load_overlay_dtb(overlay_buf, overlay_buf_size);
+</pre>
+</li>
+
+<li>Overlay the DTs:
+<ol>
+
+<li>Use <code>ufdt_install_blob()</code> to get the FDT header for main DT:
+<pre class="prettyprint">
+main_fdt_header = ufdt_install_blob(main_buf, main_size);
+main_fdt_size = main_size;
+</pre>
+</li>
+<li>Call <code>ufdt_apply_overlay()</code> to DTO to get a merged DT in FDT
+format:
+<pre class="prettyprint">
+merged_fdt = ufdt_apply_overlay(main_fdt_header, main_fdt_size,
+ overlay_buf, overlay_size);
+</pre>
+</li>
+
+<li>To get the size of <code>merged_fdt</code>, use <code>dtc_totalsize()</code>:
+<pre class="prettyprint">
+merged_fdt_size = dtc_totalsize(merged_fdt);
+</pre>
+</li>
+
+<li>Pass merged DT to start kernel. When you start the kernel, pass merged DT to
+kernel:
+<pre class="prettyprint">
+my_kernel_entry(0, machine_type, merged_fdt);
+</pre>
+</li>
+</ol></li></ol>
+
+<h3 id=sample-code>Sample DTO code</h3>
+<pre class="prettyprint">
+#include &lt;libfdt.h&gt;
+#include &lt;ufdt_overlay.h&gt;
+
+…
+
+{
+ struct fdt_header *main_fdt_header;
+ struct fdt_header *merged_fdt;
+
+ /* load main dtb into memory and get the size */
+ main_size = my_load_main_dtb(main_buf, main_buf_size);
+
+ /* load overlay dtb into memory and get the size */
+ overlay_size = my_load_overlay_dtb(overlay_buf, overlay_buf_size);
+
+ /* overlay */
+ main_fdt_header = ufdt_install_blob(main_buf, main_size);
+ main_fdt_size = main_size;
+ merged_fdt = ufdt_apply_overlay(main_fdt_header, main_fdt_size,
+ overlay_buf, overlay_size);
+ merged_fdt_size = dtc_totalsize(merged_fdt);
+
+ /* pass to kernel */
+ my_kernel_entry(0, machine_type, merged_fdt);
+}
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/partitions.html b/en/devices/architecture/dto/partitions.html
new file mode 100644
index 00000000..bcbea204
--- /dev/null
+++ b/en/devices/architecture/dto/partitions.html
@@ -0,0 +1,307 @@
+<html devsite>
+ <head>
+ <title>DTB/DTBO Partitions</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>If your DTB/DTBO is in a unique partition, e.g. <code>dtb</code> and
+<code>dtbo</code> partition, use the following table structure and header
+format:</p>
+
+<p><img src="../images/treble_dto_partition_layout.png"></p>
+<figcaption><strong>Figure 1.</strong> Example
+<code>dtb</code>/<code>dtbo</code> partition layout (for AVB signature, see
+<a href="/devices/architecture/dto/implement.html#security">Security</a>).
+</figcaption>
+
+<h2 id=structures>Data structures</h2>
+<p>The <code>dt_table_header</code> is <strong>only</strong> for the
+<code>dtb</code>/<code>dtbo</code> partition; you CANNOT append this format
+after the end of <code>image.gz</code>. If you have a single DTB/DTBO, you must
+still use this format (and the <code>dt_entry_size</code> in
+<code>dt_table_header</code> is 1).</p>
+
+<pre class="prettyprint">
+#define DT_TABLE_MAGIC 0xd7b7ab1e
+
+struct dt_table_header {
+ uint32_t magic; // DT_TABLE_MAGIC
+ uint32_t total_size; // includes dt_table_header + all dt_table_entry
+ // and all dtb/dtbo
+ uint32_t header_size; // sizeof(dt_table_header)
+
+ uint32_t dt_entry_size; // sizeof(dt_table_entry)
+ uint32_t dt_entry_count; // number of dt_table_entry
+ uint32_t dt_entries_offset; // offset to the first dt_table_entry
+ // from head of dt_table_header
+
+ uint32_t page_size; // flash page size we assume
+ uint32_t reserved[1]; // must be zero
+};
+
+struct dt_table_entry {
+ uint32_t dt_size;
+ uint32_t dt_offset; // offset from head of dt_table_header
+
+ uint32_t id; // optional, must be zero if unused
+ uint32_t rev; // optional, must be zero if unused
+ uint32_t custom[4]; // optional, must be zero if unused
+};
+</pre>
+
+<p>To read all <code>dt_table_entry</code>, use the <code>dt_entry_size</code>,
+<code>dt_entry_count</code>, and <code>dt_entries_offset</code>. Example:</p>
+<pre class="prettyprint">
+my_read(entries_buf,
+ header_addr + header-&gt;dt_entries_offset,
+ header-&gt;dt_entry_size * header-&gt;dt_entry_count);
+</pre>
+
+<p>The <code>id</code>, <code>rev</code>, <code>custom</code> in
+<code>dt_table_entry</code> are optional hardware identifications of the device
+tree the bootloader can use to efficiently identify the DTB/DTBO to load. If the
+bootloader requires additional information, put it in the DTB/DTBO where
+bootloader can read it by parsing DTB/DTBO (see the sample code below).</p>
+
+<h2 id=sample-code>Sample code</h2>
+<p>The following sample code checks the hardware identification in bootloader.
+</p>
+
+<ul>
+<li>The <code>check_dtbo()</code> function checks the hardware identification.
+It first checks the data in struct <code>dt_table_entry</code> (<code>id</code>,
+<code>rev</code>, etc.). If this data is not enough, it loads <code>dtb</code>
+data into memory and checks the value in <code>dtb</code>.</li>
+<li>The values of <code>my_hw_information</code> and <code>soc_id</code>
+properties are parsed in the root node (example in <code>my_dtbo_1.dts</code>).
+
+<pre class="prettyprint">
+[my_dtbo_1.dts]
+/dts-v1/;
+/plugin/;
+
+/ {
+ /* As DTS design, these properties only for loader, won't overlay */
+ compatible = "board_manufacturer,board_model";
+
+ /* These properties are examples */
+ board_id = &lt;0x00010000&gt;;
+ board_rev = &lt;0x00010001&gt;;
+ another_hw_information = "some_data";
+ soc_id = &lt;0x68000000&gt;;
+ ...
+};
+
+&amp;device@0 {
+ value = &lt;0x1&gt;;
+ status = "okay";
+};
+
+
+[my_bootloader.c]
+int check_dtbo(const dt_table_entry *entry, uint32_t header_addr) {
+ ...
+ if (entry-&gt;id != ... || entry-&gt;rev != ...) {
+ ...
+ }
+ ...
+ void * fdt_buf = my_load_dtb(header_addr + entry-&gt;dt_offset, entry-&gt;dt_size);
+ int root_node_off = fdt_path_offset(fdt_buf, "/");
+ ...
+ const char *my_hw_information =
+ (const char *)fdt_getprop(fdt_buf, root_node_off, "my_hw_information", NULL);
+ if (my_hw_information != NULL &amp;&amp; strcmp(my_hw_information, ...) != 0) {
+ ...
+ }
+ const fdt32_t *soc_id = fdt_getprop(fdt_buf, root_node_off, "soc_id", NULL);
+ if (soc_id != NULL &amp;&amp; *soc_id != ...) {
+ ...
+ }
+ ...
+}
+</pre></li></ul>
+
+<h2 id=mkdtimg>mkdtimg</h2>
+<p><code>mkdtimg</code> is a tool for creating
+<code>dtb</code>/<code>dtbo</code> images
+(<a href="https://android-review.googlesource.com/#/q/topic:mkdtimg+(status:open+OR+status:merged+OR+status:pending)" class="external">source
+code</a> at <code>system/libufdt</code> in AOSP). <code>mkdtimg</code> supports
+several commands, including <code>create</code>, <code>cfg_create</code>, and
+<code>dump</code>.</p>
+
+<h3 id=create>create</h3>
+<p>Use the <code>create</code> command to create a
+<code>dtb</code>/<code>dtbo</code> image:</p>
+<pre class="prettyprint">
+$mkdtimg create &lt;image_filename&gt; (&lt;global-option&gt;...) \
+ &lt;ftb1_filename&gt; (&lt;entry1_option&gt;...) \
+ &lt;ftb2_filename&gt; (&lt;entry2_option&gt;...) \
+ ...
+</pre>
+
+<p><code>ftbX_filename</code> generates a <code>dt_table_entry</code> in the
+image. <code>entryX_option</code>s are the values to assign to
+<code>dt_table_entry</code>. These values can be any of the following:</p>
+<pre class="prettyprint">
+--id=&lt;number|path&gt;
+--rev=&lt;number|path&gt;
+--custom0=&lt;number|path&gt;
+--custom1=&lt;number|path&gt;
+--custom2=&lt;number|path&gt;
+--custom3=&lt;number|path&gt;
+</pre>
+
+<p>Number values can be a 32-bit digit (such as 68000) or a hex number (such as
+0x6800). Alternatively, you can specify a path using the format:</p>
+<pre class="prettyprint">
+&lt;full_node_path&gt;:&lt;property_name&gt;
+</pre>
+
+<p>For example, <code>/board/:id</code>. <code>mkdtimg</code> reads the value
+from the path in the DTB/DTBO file and assigns the value (32-bit) to a relative
+property in <code>dt_table_entry</code>. Alternatively, you can give a
+<code>global_option</code> as a default option for all entries. The default
+value of <code>page_size</code> in <code>dt_table_header</code> is 2048; use
+<code>global_option --page_size=&lt;number&gt;</code> to assign a different
+value.</p>
+
+<p>Example:</p>
+<pre class="prettyprint">
+[board1.dts]
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "board_manufacturer,board_model";
+ board_id = &lt;0x00010000&gt;;
+ board_rev = &lt;0x00010001&gt;;
+ another_hw_information = "some_data";
+ ...
+};
+
+&amp;device@0 {
+ value = &lt;0x1&gt;;
+ status = "okay";
+};
+
+
+$mkdtimg create dtbo.img --id=/:board_id --custom0=0xabc \
+ board1.dtbo \
+ board2.dtbo --id=0x6800 \
+ board3.dtbo --id=0x6801 --custom0=0x123
+</pre>
+
+<ul>
+<li>First <code>dt_table_entry</code> (<code>board1.dtbo</code>) <code>id</code>
+is <code>0x00010000</code> and <code>custom[0]</code> is
+<code>0x00000abc</code>.</li>
+<li>Second <code>id</code> is <code>0x00006800</code> and
+<code>custom[0]</code> is <code>0x00000abc</code>.</li>
+<li>Third <code>id</code> is <code>0x00006801</code> and <code>custom[0]</code>
+is <code>0x00000123</code>.</li>
+<li>All others use the default value (<code>0</code>).</li>
+</ul>
+
+<h3 id=cfg-create>cfg_create</h3>
+<p>The <code>cfg_create</code> command creates an image with a config file in
+the following format:</p>
+<pre class="prettyprint">
+# global options
+ &lt;global_option&gt;
+ ...
+# entries
+&lt;ftb1_filename&gt; # comment
+ &lt;entry1_option&gt; # comment
+ ...
+&lt;ftb2_filename&gt;
+ &lt;entry2_option&gt;
+ ...
+...
+</pre>
+
+<p>Options <code>global_option</code> and <code>entryX_option</code> must start
+with one or more space characters (these options are the same as
+<code>create</code> options, without the <code>--</code> prefix). Empty lines or
+lines beginning with <code>#</code> are ignored.</p>
+
+<p>Example:</p>
+<pre class="prettyprint">
+[dtboimg.cfg]
+# global options
+ id=/:board_id
+ rev=/:board_rev
+ custom0=0xabc
+
+board1.dtbo
+
+board2.dtbo
+ id=0x6800 # override the value of id in global options
+
+board2.dtbo
+ id=0x6801 # override the value of id in global options
+ custom0=0x123 # override the value of custom0 in global options
+
+
+$mkdtimg cfg_create dtbo.img dtboimg.cfg
+</pre>
+
+<p><code>mkdtimg</code> does not handle alignment for
+<code>.dtb</code>/<code>.dtbo</code> files but rather appends them to the image.
+When you use <code>dtc</code> to compile <code>.dts</code> to
+<code>.dtb</code>/<code>.dtbo</code>, you must add option <code>-a</code>. For
+example, adding the option <code>-a 4</code> adds padding so the size of
+<code>.dtb</code>/<code>.dtbo</code> aligns to 4 bytes.</p>
+
+<p>Several DT table entries can share a <code>.dtb</code>/<code>.dtbo</code>. If
+you use the same filename for different entries, it stores only one content in
+the image with same <code>dt_offset</code> and <code>dt_size</code>. This is
+useful when using different hardware with identical DTs.</p>
+
+<h3 id=dump>dump</h3>
+<p>For <code>dtb</code>/<code>dtbo</code> images, use the <code>dump</code>
+command to print the information in the image. Example:</p>
+<pre class="prettyprint">
+$mkdtimg dump dtbo.img
+dt_table_header:
+ magic = d7b7ab1e
+ total_size = 1300
+ header_size = 32
+ dt_entry_size = 32
+ dt_entry_count = 3
+ dt_entries_offset = 32
+ page_size = 2048
+ reserved[0] = 00000000
+dt_table_entry[0]:
+ dt_size = 380
+ dt_offset = 128
+ id = 00010000
+ rev = 00010001
+ custom[0] = 00000abc
+ custom[1] = 00000000
+ custom[2] = 00000000
+ custom[3] = 00000000
+ (FDT)size = 380
+ (FDT)compatible = board_manufacturer,board_model
+...
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/dto/syntax.html b/en/devices/architecture/dto/syntax.html
new file mode 100644
index 00000000..64981420
--- /dev/null
+++ b/en/devices/architecture/dto/syntax.html
@@ -0,0 +1,328 @@
+<html devsite>
+ <head>
+ <title>DTO Syntax</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>Device Tree Source (DTS) format is a textual representation of a device tree.
+The Device Tree Compiler (DTC) processes this format into a binary device tree,
+which is the form expected by the Linux kernel.</p>
+
+<h2 id=reference>Using references</h2>
+
+<p>The <a href="https://github.com/pantoniou/dtc" class="external">DTC</a>
+(Device Tree compiler + overlay patches) project describes the DTS format in
+<a href="https://android.googlesource.com/platform/external/dtc/+/refs/heads/master/Documentation/dts-format.txt" class="external">dtc-format.txt</a>
+and
+<a href="https://android.googlesource.com/platform/external/dtc/+/refs/heads/master/Documentation/manual.txt" class="external">manual.txt</a>.
+DTO format and rules are described in
+<a href="https://android.googlesource.com/platform/external/dtc/+/refs/heads/master/Documentation/dt-object-internal.txt" class="external">dt-object-internal.txt</a>.
+These documents describe how to update the main DT using node
+<code>fragment@x</code> and syntax <code>__overlay__</code> in overlay DT. For
+example:</p>
+<pre class="prettyprint">
+/ {
+ fragment@0 {
+ target = &lt;&amp;some_node&gt;;
+ __overlay__ {
+ some_prop = "okay";
+ ...
+ };
+ };
+};
+</pre>
+
+<p>However, Google strongly recommends you do <strong>not</strong> use
+<code>fragment@x</code> and syntax <code>__overlay__</code>, and instead use the
+reference syntax. For example:</p>
+<pre class="prettyprint">
+&amp;some_node {
+ some_prop = "okay";
+ ...
+};
+</pre>
+
+<p>Reference syntax is compiled by <code>dtc</code> into the same object as the
+above using syntax <code>__overlay__</code>. This syntax does not force you to
+number the fragments, enabling you to read and write overlay DTS easily. If your
+<code>dtc</code> doesn't support this syntactic sugar, use the
+<a href="https://android.googlesource.com/platform/external/dtc" class="external">dtc
+in AOSP</a>.</p>
+
+<h2 id=labels>Using labels</h2>
+<p>To allow undefined references to nodes not present at compilation time, the
+overlay DT <code>.dts</code> file must have a tag <code>/plugin/</code> in its
+header. For example:</p>
+
+<pre class="prettyprint">
+/dts-v1/;
+/plugin/;
+</pre>
+
+<p>From here you can target the nodes to be overlaid using a reference, which is
+an absolute node path prefixed with an ampersand (&amp;). For example, for
+<code>node@0</code> in the main DT:</p>
+
+<table>
+<tr>
+<th width="50%">Define labels in the main DT ...</th>
+<th>... then use the labels.</th>
+</tr>
+
+<tr>
+<td>
+<pre class="prettyprint">
+[my_main_dt.dts]
+
+/dts-v1/;
+
+/ {
+ my_node: node@0 {
+ status = "disabled";
+
+ my_child: child@0 {
+ value = &lt;0xffffffff&gt;;
+ };
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+[my_overlay_dt.dts]
+
+/dts-v1/;
+/plugin/;
+
+&amp;my_node {
+ status = "okay";
+};
+
+&amp;my_child {
+ value = &lt;0x1&gt;;
+};
+</pre>
+</td>
+</tr>
+</table>
+
+<h2 id=override>Overriding</h2>
+<p>If the reference target property exists in the main DT, it is overridden
+after DTO; otherwise, it is appended. For example:</p>
+
+<table>
+<tr>
+<th width="33%">main.dts</th>
+<th width="33%">overlay.dts</th>
+<th>Merged Result</th>
+</tr>
+
+<tr>
+<td>
+<pre class="prettyprint">
+[my_main_dt.dts]
+
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ my_node: node@0 {
+ status = "disabled";
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+[my_overlay_dt.dts]
+
+/dts-v1/;
+/plugin/;
+
+&amp;my_node {
+ status = "okay";
+};
+</pre>
+</td>
+
+<td>
+<pre class="prettyprint">
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ ...
+
+ node@0 {
+ linux,phandle = <0x1>;
+ phandle = <0x1>;
+ status = "okay";
+ };
+};
+</pre>
+</td>
+</tr>
+</table>
+
+<h2 id=append>Appending</h2>
+<p>If the reference target property does not exist in the main DT, it is
+appended after DTO. For example:</p>
+
+<table>
+<tr>
+<th width="33%">main.dts</th>
+<th width="33%">overlay.dts</th>
+<th>Merged Result</th>
+</tr>
+
+<tr>
+<td>
+<pre class="prettyprint">
+[my_main_dt.dts]
+
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ my_node: node@0 {
+ status = "okay";
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+[my_overlay_dt.dts]
+
+/dts-v1/;
+/plugin/;
+
+&amp;my_node {
+ new_prop = "bar";
+};
+</pre>
+</td>
+
+<td>
+<pre class="prettyprint">
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ ...
+
+ node@0 {
+ linux,phandle = &lt;0x1&gt;;
+ phandle = &lt;0x1&gt;;
+ status = "okay";
+ new_prop = "bar";
+ };
+};
+</pre>
+</td>
+</tr>
+</table>
+
+<h2 id="child">Child nodes</h2>
+<p>Examples of child node syntax:</p>
+
+<table>
+<tr>
+<th width="33%">main.dts</th>
+<th width="33%">overlay.dts</th>
+<th>Merged Result</th>
+</tr>
+
+<tr>
+<td>
+<pre class="prettyprint">
+[my_main_dt.dts]
+
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ my_nodes: nodes {
+ compatible = "corp,bar";
+
+ node@0 {
+ status = "disabled";
+ };
+ };
+};
+</pre>
+</td>
+
+<td class="alt">
+<pre class="prettyprint">
+[my_overlay_dt.dts]
+
+/dts-v1/;
+/plugin/;
+
+&amp;my_nodes {
+ new_prop1 = "abc";
+
+ node@0 {
+ status = "okay";
+ new_prop2 = "xyz";
+ };
+};
+</pre>
+</td>
+
+<td>
+<pre class="prettyprint">
+/dts-v1/;
+
+/ {
+ compatible = "corp,foo";
+
+ ...
+
+ nodes {
+ linux,phandle = &lt;0x1&gt;;
+ phandle = &lt;0x1&gt;;
+ compatible = "corp,bar";
+ new_prop1 = "abc";
+
+ node@0 {
+ linux,phandle = &lt;0x2&gt;;
+ phandle = &lt;0x2&gt;;
+ status = "okay";
+ new_prop2 = "xyz";
+ };
+ };
+};
+</pre>
+</td>
+</tr>
+</table>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hal-types.html b/en/devices/architecture/hal-types.html
new file mode 100644
index 00000000..52cb869f
--- /dev/null
+++ b/en/devices/architecture/hal-types.html
@@ -0,0 +1,154 @@
+<html devsite>
+ <head>
+ <title>HAL Types</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>As part of the Android O rearchitecture of the lower layers of the Android OS
+to support better modularity, devices running Android O must support binderized
+or passthrough HALs:</p>
+
+<ul>
+<li><strong>Binderized HALs</strong>. HALs expressed in HAL interface definition
+language (HIDL). These HALs replace both conventional and legacy HALs used in
+earlier versions of Android and can serve the HAL in binderized mode. All
+devices launching with Android O or later must support binderized HALs only.</li>
+
+<li><strong>Passthrough HALs</strong>. A HIDL-wrapped conventional or legacy
+HAL. These HALs wrap existing HALs and can serve the HAL in binderized and
+same-process (passthrough) modes. Devices upgrading to Android O can use
+passthrough HALs.</li>
+</ul>
+
+<h2 id=requirements>HAL mode requirements</h2>
+
+<table>
+<tbody>
+
+<tr>
+<th>Device</th>
+<th>Passthrough</th>
+<th>Binderized</th>
+</tr>
+
+<tr>
+<td><em>Launch with Android O</em></td>
+<td>HALs listed in <a href="#passthrough">Passthrough HALs</a> must be
+passthrough.</td>
+<td>All other HALs are binderized (including HALs that are vendor
+extensions).</td>
+</tr>
+
+<tr>
+<td rowspan=2><em>Upgrade to Android O</em></td>
+<td>HALs listed in <a href="#passthrough">Passthrough HALs</a> must be
+passthrough.</td>
+<td>HALs listed in <a href="#binderized">Binderized HALs</a> must be
+binderized.</td>
+</tr>
+
+<tr>
+<td colspan=2>All other HALs provided by the vendor image can be in passthrough
+OR binderized mode.</td>
+</tr>
+
+</tbody>
+</table>
+
+<h2 id=binderized>Binderized HALs</h2>
+<p>Android requires the following HALS to to be binderized on all Android
+devices regardless of whether they are launch devices or upgrade devices:</p>
+
+<ul>
+<li><code>android.hardware.biometrics.fingerprint@2.1</code>. Replaces
+<code>fingerprintd</code> which is no longer in Android O.</li>
+<li><code>android.hardware.configstore@1.0</code>. New in Android O.</li>
+<li><code>android.hardware.dumpstate@1.0</code>. The original interface provided
+by this HAL could not be shimmed and was changed. Because of this,
+<code>dumpstate_board</code> must be re-implemented on a given device (this is
+an optional HAL).</li>
+<li><code>android.hardware.graphics.allocator@2.0</code>. Required to be
+binderized in Android O so file descriptors don't have to be shared between
+trusted and untrusted processes.</li>
+<li><code>android.hardware.radio@1.0</code>. Replaces the interface provided by
+<code>rild</code> which lives in its own process.</li>
+<li><code>android.hardware.usb@1.0</code>. New in Android O.</li>
+<li><code>android.hardware.wifi@1.0</code>. New in Android O, replaces the
+legacy Wi-Fi HAL library that was loaded into <code>system_server</code>.</li>
+<li><code>android.hardware.wifi.supplicant@1.0</code>. A HIDL interface over the
+existing <code>wpa_supplicant</code> process.</li>
+</ul>
+
+<p class=note><strong>NOTE</strong>: Android provides the following HIDL
+interfaces which will always be in binderized mode:
+<code>android.frameworks.*</code>, <code>android.system.*</code> , and
+<code>android.hidl.*</code> (except for <code>android.hidl.memory@1.0</code>
+as described below).</p>
+
+<h2 id=passthrough>Passthrough HALs</h2>
+<p>Android requires the following HALs to be in passthrough mode on all Android
+devices regardless of whether they are launch devices or upgrade devices:</p>
+
+<ul>
+<li><code>android.hardware.graphics.mapper@1.0</code>. Maps memory into the
+process it lives in.</li>
+<li><code>android.hardware.renderscript@1.0</code>. Passes items in the same
+process (equivalent to <code>openGL</code>).</li>
+</ul>
+<p>All HALs not listed above must be binderized for launch devices.</p>
+
+<h2 id=same-process>Same-Process HALs</h2>
+<p>Same-Process HALs (SP-HALs) always open in the same process in which they are
+used. They include all HALs not expressed in HIDL as well as some that are
+<strong>not</strong> binderized. Membership in the SP-HAL set is controlled only
+by Google, with no exceptions.</p>
+
+<p>SP-HALs include the following:</p>
+
+<ul>
+<li><code>openGL</code></li>
+<li><code>Vulkan</code></li>
+<li><code>android.hidl.memory@1.0</code> (provided by the Android system, always
+passthrough)</li>
+<li><code>android.hardware.graphics.mapper@1.0</code>.</li>
+<li><code>android.hardware.renderscript@1.0</code></li>
+</ul>
+
+<h2 id=legacy>Conventional &amp; legacy HALs</h2>
+
+<p>Conventional HALs (deprecated in Android O) are interfaces that conform to a
+specific named and versioned application binary interface (ABI). The bulk of
+Android system interfaces
+(<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera3.h">camera</a>,
+<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/audio.h">audio</a>,
+<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/sensors.h">sensors</a>,
+etc.) are in the form of conventional HALs, which are defined under
+<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware">hardware/libhardware/include/hardware</a>.</p>
+
+<p>Legacy HALs (also deprecated in Android O) are interfaces that predate
+conventional HALs. A few important subsystems (Wi-Fi, Radio Interface Layer, and
+Bluetooth) are legacy HALs. While there's no uniform or standardized way to
+describe a legacy HAL, anything predating Android O that is not a conventional
+HAL is a legacy HAL. Parts of some legacy HALs are contained in
+<a href="https://android.googlesource.com/platform/hardware/libhardware_legacy/+/master">libhardware_legacy</a>,
+while other parts are interspersed throughout the codebase.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-cpp/functions.html b/en/devices/architecture/hidl-cpp/functions.html
new file mode 100644
index 00000000..5d52b31d
--- /dev/null
+++ b/en/devices/architecture/hidl-cpp/functions.html
@@ -0,0 +1,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>
diff --git a/en/devices/architecture/hidl-cpp/index.html b/en/devices/architecture/hidl-cpp/index.html
new file mode 100644
index 00000000..af685400
--- /dev/null
+++ b/en/devices/architecture/hidl-cpp/index.html
@@ -0,0 +1,132 @@
+<html devsite>
+ <head>
+ <title>HIDL C++</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 re-architects the Android OS to define clear interfaces between the
+device-independent Android platform and device- and vendor-specific code.
+Android already defines many such interfaces in the form of HAL interfaces,
+defined as C headers in <code>hardware/libhardware</code>. HIDL replaces these
+HAL interfaces with stable, versioned interfaces, which can be client- and
+server-side HIDL interfaces in C++ (described below) or
+<a href="/devices/architecture/hidl-java/index.html">Java</a>.</p>
+
+<p>The pages in this section describe C++ implementations of HIDL interfaces,
+including details about the files auto-generated from the HIDL <code>.hal</code>
+files by the <code>hidl-gen</code> compiler, how these files are packaged, and
+how to integrate these files with the C++ code that uses them.</p>
+
+<h2 id=client-server>Client &amp; server implementations</h2>
+<p>HIDL interfaces have client and server implementations:</p>
+
+<ul>
+<li>A <strong>client</strong> of a HIDL interface is the code that uses the
+interface by calling methods on it.</li>
+<li>A <strong>server</strong> is an implementation of a HIDL interface that
+receives calls from clients and returns results (if necessary).</li>
+</ul>
+
+<p>In transitioning from <code>libhardware</code> HALs to HIDL HALs, the HAL
+implementation becomes the server and the process calling into the HAL becomes
+the client. Default implementations can serve both passthrough and binderized
+HALs, and can change over time:</p>
+
+<p><img src="../images/treble_cpp_legacy_hal_progression.png"></p>
+<p><strong>Figure 1.</strong> Development progression for legacy HALs.</p>
+
+<h2>Creating the HAL client</h2>
+<p>Start by including the HAL libraries in the makefile:</p>
+
+<ul>
+<li>Make: <code>LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0</code></li>
+<li>Soong: <code>shared_libs: [ …, android.hardware.nfc@1.0 ]</code></li>
+</ul>
+
+<p>Next, include the HAL header files:</p>
+
+<pre class="prettyprint">
+#include &lt;android/hardware/nfc/1.0/IFoo.h&gt;
+…
+// in code:
+sp&lt;IFoo&gt; client = IFoo::getService();
+client-&gt;doThing();
+</pre>
+
+<h2>Creating the HAL server</h2>
+<p>To create the HAL implementation, you must have the <code>.hal</code> files
+that represent your HAL and have already generated makefiles for your HAL using
+<code>-Lmakefile</code> or <code>-Landroidbp</code> on <code>hidl-gen</code>
+(<code>./hardware/interfaces/update-makefiles.sh</code> does this for internal
+HAL files and is a good reference). When transferring over HALs from
+<code>libhardware</code>, you can do a lot of this work easily using c2hal.</p>
+
+<p>To create the necessary files to implement your HAL:</p>
+
+<pre class="prettyprint">
+PACKAGE=android.hardware.nfc@1.0
+LOC=hardware/interfaces/nfc/1.0/default/
+make hidl-gen -j64
+hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport $PACKAGE
+hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport $PACKAGE
+</pre>
+
+<p>For the HAL to work in passthrough mode (for legacy devices), you must have
+the function <em>HIDL_FETCH_IModuleName</em> residing in
+<code>/system/lib(64)?/hw/android.hardware.package@3.0-impl(-$OPTIONAL_IDENTIFIER).so</code>
+where <code>$OPTIONAL_IDENTIFIER</code> is a string identifying the passthrough
+implementation. The passthrough mode requirements are met automatically by the
+above commands, which also create the <code>android.hardware.nfc@1.0-impl</code>
+target.</p>
+
+<p>Next, fill out the stubs with functionality and setup a daemon. Example
+daemon code (supporting passthrough):</p>
+
+<pre class="prettyprint">
+#include &lt;hidl/LegacySupport.h&gt;
+
+int main(int /* argc */, char* /* argv */ []) {
+ return defaultPassthroughServiceImplementation&lt;INfc&gt;("nfc");
+}
+</pre>
+
+<p><code>defaultPassthroughServiceImplementation</code> will
+<code>dlopen()</code> the provided <code>-impl</code> library and provide it as
+a binderized service. Example daemon code (for pure binderized service):</p>
+
+<pre class="prettyprint">
+int main(int /* argc */, char* /* argv */ []) {
+ Nfc nfc = new Nfc();
+ nfc-&gt;registerAsService();
+}
+</pre>
+
+<p>This daemon should live in <code>$PACKAGE + "-service"</code> (for example,
+<code>android.hardware.nfc@1.0-service</code>). The
+<a href="/security/selinux/device-policy.html">sepolicy</a> for a specific class
+of HALs is the attribute <code>hal_&lt;module&gt;</code> (for instance,
+<code>hal_nfc)</code>. This attribute must be applied to the daemon that runs a
+particular HAL (if the same process serves multiple HALs, multiple attributes
+can be applied to it).</p>
+
+</body>
+</html>
diff --git a/en/devices/architecture/hidl-cpp/interfaces.html b/en/devices/architecture/hidl-cpp/interfaces.html
new file mode 100644
index 00000000..5047e8d0
--- /dev/null
+++ b/en/devices/architecture/hidl-cpp/interfaces.html
@@ -0,0 +1,271 @@
+<html devsite>
+ <head>
+ <title>Interfaces</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>Every interface defined in a HIDL package has its own autogenerated C++ class
+inside its package's namespace. Clients and servers deal with interfaces in
+different ways:</p>
+
+<ul>
+<li><strong>Servers</strong> implement interfaces.</li>
+<li><strong>Clients</strong> call methods on interfaces.</li>
+</ul>
+
+<p>Interfaces can either be registered by name by the server or passed as
+parameters to HIDL-defined methods. For example, framework code may serve an
+interface to receive asynchronous messages from the HAL and pass that interface
+directly to the HAL without registering it.</p>
+
+<h2 id=server>Server implementation</h2>
+<p>A server implementing the <code>IFoo</code> interface must include the
+<code>IFoo</code> header file that was autogenerated:</p>
+
+<pre class="prettyprint">
+#include &lt;android/hardware/samples/1.0/IFoo.h&gt;
+</pre>
+
+<p>The header is automatically exported by the shared library of the
+<code>IFoo</code> interface to link against. Example <code>IFoo.hal</code>:</p>
+
+<pre class="prettyprint">
+// IFoo.hal
+interface IFoo {
+ someMethod() generates (vec&lt;uint32_t&gt;);
+ ...
+}
+</pre>
+
+<p>Example skeleton for a server implementation of the IFoo interface:</p>
+
+<pre class="prettyprint">
+// From the IFoo.h header
+using android::hardware::samples::V1_0::IFoo;
+
+class FooImpl : public IFoo {
+ Return&lt;void&gt; someMethod(foo my_foo, someMethod_cb _cb) {
+ vec&lt;uint32_t&gt; return_data;
+ // Compute return_data
+ _cb(return_data);
+ return Void();
+ }
+ ...
+};
+</pre>
+
+<p>To make the implementation of a server interface available to a client, you
+can:</p>
+
+<ol>
+<li><strong>Register</strong> the interface implementation with the
+<code>hwservicemanager</code> (see details below),
+<br><br>
+OR<br><br>
+</li>
+<li><strong>Pass</strong> the interface implementation as an argument of an
+interface method (for detals, see <a href="#asynchronous">Asynchronous
+callbacks</a>).</li>
+</ol>
+
+<p>When registering the interface implementation, the
+<code>hwservicemanager</code> process keeps track of registered HIDL interfaces
+running on the device by name and version. Servers can register a HIDL interface
+implementation by name and clients can request service implementations by name
+and version. This process serves the HIDL interface
+<code>android.hidl.manager@1.0::IServiceManager</code>.</p>
+
+<p>Each auto-generated HIDL interface header file (such as <code>IFoo.h</code>)
+has a <code>registerAsService()</code> method that can be used to register the
+interface implementation with the <code>hwservicemanager</code>. The only
+required argument is the name of the interface implementations as clients will
+use this name to retrieve the interface from the <code>hwservicemanager</code>
+later:</p>
+
+<pre class="prettyprint">
+::android::sp&lt;IFoo&gt; myFoo = new FooImpl();
+::android::sp&lt;IFoo&gt; myFoo = new FooAnotherImpl();
+myFoo-&gt;registerAsService();
+mySecondFoo-&gt;registerAsService("another_foo");
+</pre>
+
+<p>The <code>hwservicemanager</code> treats the combination of
+<code>[package@version::interface, instance_name]</code> as unique to enable
+different interfaces (or different versions of the same interface) to register
+with identical instance names without conflicts. If you call
+<code>registerAsService()</code> with the exact same package version, interface,
+and instance name, the <code>hwservicemanager</code> drops its reference to the
+previously registered service and uses the new one.</p>
+
+<h2 id=client>Client implementation</h2>
+<p>Just as the server does, a client must <code>#include</code> every interface
+it refers to:</p>
+
+<pre class="prettyprint">
+#include &lt;android/hardware/samples/1.0/IFoo.h&gt;
+</pre>
+
+<p>A client can obtain an interface in two ways:</p>
+
+<ul>
+<li>Through <code>I&lt;InterfaceName&gt;::getService</code> (via the
+<code>hwservicemanager</code>)</li>
+<li>Through an interface method</li>
+</ul>
+
+<p>Each autogenerated interface header file has a static <code>getService</code>
+method that can be used to retrieve a service instance from the
+<code>hwservicemanager</code>:</p>
+
+<pre class="prettyprint">
+// getService will return nullptr if the service can't be found
+sp&lt;IFoo&gt; myFoo = IFoo::getService();
+sp&lt;IFoo&gt; myAlternateFoo = IFoo::getService("another_foo");
+</pre>
+
+<p>Now the client has an an <code>IFoo</code> interface, and can call methods to
+it as if it were a local class implementation. In reality, the implementation
+may run in the same process, a different process, or even on another device
+(with HAL remoting). Because the client called <code>getService</code> on an
+<code>IFoo</code> object included from version <code>1.0 </code>of the package,
+the <code>hwservicemanager</code> returns a server implementation only if that
+implementation is compatible with <code>1.0</code> clients. In practice, this
+means only server implementations with version <code>1.n</code> (version
+<code>x.(y+1)</code> of an interface must extend (inherit from)
+<code>x.y</code>).</p>
+
+<p>Additionally the method <code>castFrom</code> is provided to cast between
+different interfaces. This method works by making an IPC call to the remote
+interface to make sure the underlying type is the same as the type that is being
+requested. If the requested type is unavailable, then <code>nullptr</code> is
+returned.</p>
+
+<pre class="prettyprint">
+sp&lt;V1_0::IFoo&gt; foo1_0 = V1_0::IFoo::getService();
+sp&lt;V1_1::IFoo&gt; foo1_1 = V1_1::IFoo::castFrom(foo1_0);
+</pre>
+
+<h2 id=asynchronous>Asynchronous callbacks</h2>
+<p>Many existing HAL implementations talk to asynchronous hardware, which means
+they need an asynchronous way to notify clients of new events that have
+occurred. A HIDL interface can be used as an asynchronous callback because HIDL
+interface functions can take HIDL interface objects as parameters.</p>
+
+<p>Example interface file <code>IFooCallback.hal</code>:</p>
+
+<pre class="prettyprint">
+package android.hardware.samples@1.0;
+interface IFooCallback {
+ sendEvent(uint32_t event_id);
+ sendData(hidl_vec&lt;uint8_t&gt; data);
+}
+</pre>
+
+<p>Example new method in <code>IFoo</code> that takes an
+<code>IFooCallback</code> parameter:</p>
+
+<pre class="prettyprint">
+package android.hardware.samples@1.0;
+interface IFoo {
+ struct Foo {
+ int64_t some_value;
+ Handle my_handle;
+ };
+
+ someMethod(Foo foo) generates (int32_t ret);
+ another_method() generates (hidl_vec&lt;uint32_t&gt;);
+ register_callback(IFooCallback callback);
+};
+</pre>
+
+<p>The <em>client</em> using the <code>IFoo</code> interface is the
+<em>server</em> of the <code>IFooCallback</code> interface; it provides an
+implementation of <code>IFooCallback</code>:</p>
+
+<pre class="prettyprint">
+class FooCallback : public IFooCallback {
+ Return&lt;void&gt; sendEvent(uint32_t event_id) {
+ // process the event from the HAL
+ }
+ Return&lt;void&gt; sendData(hidl_vec&lt;uint8_t&gt; data) {
+ // process data from the HAL
+ }
+};
+</pre>
+
+<p>It can also simply pass that over an existing instance of the
+<code>IFoo</code> interface:</p>
+<pre class="prettyprint">
+sp&lt;IFooCallback&gt; myFooCallback = new FooCallback();
+myFoo.registerCallback(myFooCallback);
+</pre>
+
+<p>The server implementing <code>IFoo</code> receives this as an
+<code>sp&lt;IFooCallback&gt;</code> object. It can store the callback, and call
+back into the client whenever it wants to use this interface.</p>
+
+<h2 id=death>Death recipients</h2>
+<p>As service implementations can run in a different process, it can happen
+that the process implementing an interface dies while the client stays alive.
+Any calls on an interface object hosted in a process that has died will fail
+with a transport error (<code>isOK()</code> will return false). The only way to
+recover from such a failure is to request a new instance of the service by
+calling <code>I&lt;InterfaceName&gt;::getService()</code>. This works only if
+the process that crashed has restarted and re-registered its services with the
+<code>servicemanager</code> (which is generally true for HAL implementations).
+</p>
+
+<p>Instead of dealing with this reactively, clients of an interface can also
+register a <em>death recipient</em> to get a notification when a service dies.
+To register for such notifications on a retrieved <code>IFoo</code> interface, a
+client can do the following:</p>
+
+<pre class="prettyprint">
+foo-&gt;linkToDeath(recipient, 1481 /* cookie */);
+</pre>
+
+<p>The <code>recipient</code> parameter must be an implementation of the
+<code>android::hardware::hidl_death_recipient</code> interface provided by HIDL,
+which contains a single method <code>serviceDied()</code> that will be called
+from a thread in the RPC threadpool when the process hosting the interface dies:
+</p>
+
+<pre class="prettyprint">
+class MyDeathRecipient : android::hardware::hidl_death_recipient {
+ virtual void serviceDied(uint64_t cookie, const android::wp&lt;::android::hidl::base::V1_0::IBase&gt;&amp; who) {
+ // Deal with the fact that the service died
+ }
+}
+</pre>
+
+<p>The <code>cookie</code> parameter contains the cookie that was passed in with
+<code>linkToDeath()</code>, whereas the <code>who</code> parameter contains a
+weak pointer to the object representing the service in the client. With the
+sample call given above, <code>cookie</code> equals 1481, and <code>who</code>
+equals <code>foo</code>.</p>
+
+<p>It's also possible to unregister a death recipient after registering it:</p>
+
+<pre class="prettyprint">
+foo-&gt;unlinkToDeath(recipient);
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-cpp/packages.html b/en/devices/architecture/hidl-cpp/packages.html
new file mode 100644
index 00000000..2c8e096d
--- /dev/null
+++ b/en/devices/architecture/hidl-cpp/packages.html
@@ -0,0 +1,202 @@
+<html devsite>
+ <head>
+ <title>Packages</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 class=note><strong>Note:</strong> This section uses sample <code>.hal</code>
+files to illustrate how HIDL language constructs map to C++.</p>
+
+<p>With few exceptions, HIDL interface packages are located in
+<code>hardware/interfaces</code> or the <code>vendor/</code> directory. The
+<code>hardware/interfaces</code> top-level maps directly to the
+<code>android.hardware</code> package namespace; the version is a subdirectory
+under the package (not interface) namespace.</p>
+
+<p>The <code>hidl-gen</code> compiler compiles the <code>.hal</code> files into
+a set of a <code>.h</code> and <code>.cpp</code> files. From these autogenerated
+files a shared library that client/server implementations link against is built.
+The <code>Android.bp</code> file that builds this shared library is
+autogenerated by the <code>hardware/interfaces/update-makefiles.sh</code>
+script. Every time you add a new package to <code>hardware/interfaces</code>, or
+add/remove <code>.hal</code> files to/from an existing package, you must rerun
+the script to ensure the generated shared library is up-to-date.</p>
+
+<p>For example, the <code>IFoo.hal</code> sample file should be located in
+<code>hardware/interfaces/samples/1.0</code>. The sample
+<code><strong>IFoo.hal</code></strong> file creates an IFoo interface in the
+<strong>samples</strong> package:</p>
+
+<pre class="prettyprint">
+package android.hardware.samples@1.0;
+interface IFoo {
+ struct Foo {
+ int64_t someValue;
+ handle myHandle;
+ };
+
+ someMethod() generates (vec&lt;uint32_t&gt;);
+ anotherMethod(Foo foo) generates (int32_t ret);
+};
+</pre>
+
+<h2 id=generated-files>Generated files</h2>
+
+<p>Autogenerated files in a HIDL package are linked into a single shared
+library with the same name as the package (for example,
+<code>android.hardware.samples@1.0</code>). The shared library also exports a
+single header, <code>IFoo.h</code>, which can be included by clients and
+servers. Using the <code>hidl-gen</code> compiler with the <code>IFoo.hal</code>
+interface file as an input, binderized mode has the following autogenerated
+files:</p>
+
+<p><img src="../images/treble_cpp_compiler_generated_files.png"></p>
+<p><strong>Figure 1.</strong> Files generated by compiler.</p>
+
+<ul>
+<li><code><strong>IFoo.h</code></strong>. Describes the pure <code>IFoo</code>
+interface in a C++ class; it contains the methods and types defined in the
+<code>IFoo</code> interface in the <code>IFoo.hal</code> file, translated to C++
+types where necessary. <strong>Does not contain</strong> details related to the
+RPC mechanism (e.g., <code>HwBinder</code>) used to implement this interface.
+The class is namespaced with the package and version, e.g.
+<code>::android::hardware::samples::IFoo::V1_0</code>. Both clients and servers
+include this header: Clients for calling methods on it and servers for
+implementing those methods.</li>
+<li><code><strong>IHwFoo.h</code></strong>. Header file that contains
+declarations for functions that serialize data types used in the interface.
+Developers should never include his header directly (it does not contain any
+classes).</li>
+<li><code><strong>BpFoo.h</code></strong>. A class that inherits from
+<code>IFoo</code> and describes the <code>HwBinder</code> proxy (client-side)
+implementation of the interface. Developers should never refer to this class
+directly.</li>
+<li><code><strong>BnFoo.h</code></strong>.<strong> </strong>A class that holds a
+reference to an <code>IFoo</code> implementation and describes the
+<code>HwBinder</code> stub (server-side) implementation of the interface.
+Developers should never refer to this class directly.</li>
+<li><code><strong>FooAll.cpp</code></strong>. A class that contains the
+implementations for both the <code>HwBinder</code> proxy and the
+<code>HwBinder</code> stub. When a client calls an interface method, the proxy
+automatically marshals the arguments from the client and sends the transaction
+to the binder kernel driver, which delivers the transaction to the stub on the
+other side (which then calls the actual server implementation).</li>
+</ul>
+
+<p>The files are structured similarly to the files generated by
+<code>aidl-cpp</code> (for details, see "Passthrough mode" in the
+<a href="/devices/architecture/hidl/index.html">HIDL Overview</a>). The only
+autogenerated file that is independent of the RPC mechanism used by HIDL is
+<code>IFoo.h</code>; all other files are tied to the HwBinder RPC mechanism used
+by HIDL. Therefore, client and server implementations <strong>should never
+directly refer to anything other than <code>IFoo</code></strong>. To achieve
+this, include only <code>IFoo.h</code> and link against the generated shared
+library.</p>
+
+<p class=note><strong>Note</strong>: HwBinder is only one possible transport;
+new transports may be added in the future.</p>
+
+<h2 id=link-libraries>Linking to shared libraries</h2>
+<p>A client or server that uses any interface in a package must include the
+shared library of that package in <strong>one (1)</strong> of the following
+locations:</p>
+
+<ul>
+<li>In <strong>Android.mk</strong>:
+<pre class="prettyprint">
+LOCAL_SHARED_LIBRARIES += android.hardware.samples@1.0
+</pre>
+</li>
+
+<li>In <strong>Android.bp</strong>:
+<pre class="prettyprint">
+shared_libs: [
+ /* ... */
+ "android.hardware.samples@1.0",
+],
+</pre>
+</li>
+</ul>
+
+<p>For specific libraries:</p>
+
+<table>
+
+<tr>
+<th><code>libhidlbase</code></th>
+<td>Includes standard HIDL data-types. Unless your interface consists only of
+primitives that map directly to C++ primitives, you must also link this library:
+<pre class="prettyprint">
+LOCAL_SHARED_LIBRARIES += libhidlbase
+</pre>
+</td>
+</tr>
+
+<tr>
+<th><code>libhidltransport</code></th>
+<td>Handles the transport of HIDL calls over different RPC/IPC mechanisms. You
+must always link this library:
+<pre class="prettyprint">
+LOCAL_SHARED_LIBRARIES += libhidltransport
+</pre>
+</td>
+</tr>
+
+<tr>
+<th><code>libhwbinder</code></th>
+<td>You must also link to this library:
+<pre class="prettyprint">
+LOCAL_SHARED_LIBRARIES += libhwbinder
+</pre>
+</td>
+</tr>
+
+<tr>
+<th><code>libfmq</code></th>
+<td>To use Fast Message Queue IPC, you must also link to this library.
+<pre class="prettyprint">
+LOCAL_SHARED_LIBRARIES += libfmq
+</pre>
+</td>
+</tr>
+
+</tbody>
+</table>
+
+<h2 id=namespaces>Namespaces</h2>
+<p>HIDL functions and types such as <code>Return&lt;T&gt;</code> and
+<code>Void()</code> are declared in namespace <code>::android::hardware</code>.
+The C++ namespace of a package is determined by the package name and version.
+For example, a package <strong>mypackage</strong> with version 1.2 under
+<code>hardware/interfaces</code> has the following qualities:</p>
+
+<ul>
+<li><strong>C++ namespace</strong> is
+<code>::android::hardware::mypackage::V1_2</code></li>
+<li><strong>Fully qualified name </strong>of <code>IMyInterface</code> in that
+package is: <code>::android::hardware::mypackage::V1_2::IMyInterface</code>.
+(<code>IMyInterface</code> is an identifier, not part of the namespace).</li>
+<li><strong>Types</strong> defined in the package's <code>types.hal</code> file
+are identified as:
+<code>::android::hardware::mypackage::V1_2::MyPackageType</code></li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-cpp/types.html b/en/devices/architecture/hidl-cpp/types.html
new file mode 100644
index 00000000..1d93df74
--- /dev/null
+++ b/en/devices/architecture/hidl-cpp/types.html
@@ -0,0 +1,323 @@
+<html devsite>
+ <head>
+ <title>Data Types</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>HIDL data declarations generate C++ standard-layout data structures. These
+structures can be placed anywhere that feels natural (on the stack, at file or
+global scope, or on the heap) and can be composed in the same fashion. Client
+code calls HIDL proxy code passing in const references and primitive types,
+while the stub and proxy code hides the details of serialization.</p>
+
+<p class=note><strong>Note:</strong> At no point is developer-written code
+required to explicitly serialize or deserialize data structures.</p>
+
+<p>The table below maps HIDL primitives to C++ data types:</p>
+
+<table>
+<tbody>
+<tr>
+<th><strong>HIDL Type</strong></th>
+<th><strong>C++ Type</strong></th>
+<th><strong>Header/Library</strong></th>
+</tr>
+
+<tr>
+<td><pre>enum</pre></td>
+<td><pre>enum class</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>uint8_t..uint64_t</pre></td>
+<td><pre>uint8_t..uint64_t</pre></td>
+<td><pre>&lt;stdint.h&gt;</pre></td>
+</tr>
+
+<tr>
+<td><pre>int8_t..int64_t</pre></td>
+<td><pre>int8_t..int64_t</pre></td>
+<td><pre>&lt;stdint.h&gt;</pre></td>
+</tr>
+
+<tr>
+<td><pre>float</pre></td>
+<td><pre>float</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>double</pre></td>
+<td><pre>double</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>vec&lt;T&gt;</pre></td>
+<td><pre>hidl_vec&lt;T&gt;</pre></td>
+<td><pre>libhidlbase</pre></td>
+</tr>
+
+<tr>
+<td><pre>T[S1][S2]...[SN]</pre></td>
+<td><pre>T[S1][S2]...[SN]</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>string</pre></td>
+<td><pre>hidl_string</pre></td>
+<td><pre>libhidlbase</pre></td>
+</tr>
+
+<tr>
+<td><pre>handle</pre></td>
+<td><pre>hidl_handle</pre></td>
+<td><pre>libhidlbase</pre></td>
+</tr>
+
+<tr>
+<td><pre>opaque</pre></td>
+<td><pre>uint64_t</pre></td>
+<td><pre>&lt;stdint.h&gt;</pre>
+</td>
+</tr>
+
+<tr>
+<td><pre>struct</pre></td>
+<td><pre>struct</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>union</pre></td>
+<td><pre>union</pre></td>
+<td></td>
+</tr>
+
+<tr>
+<td><pre>fmq_sync</pre></td>
+<td><pre>MQDescriptorSync</pre></td>
+<td><pre>libhidlbase</pre></td>
+</tr>
+
+<tr>
+<td><pre>fmq_unsync</pre></td>
+<td><pre>MQDescriptorUnsync</pre></td>
+<td><pre>libhidlbase</pre></td>
+</tr>
+
+</tbody>
+</table>
+
+<p>The sections below describe data types in more detail.</p>
+
+<h2 id=enum>enum</h2>
+<p>An enum in HIDL becomes an enum in C++. For example:</p>
+<pre class="prettyprint">
+enum Mode : uint8_t { WRITE = 1 &lt;&lt; 0, READ = 1 &lt;&lt; 1 };
+</pre>
+
+<p>&hellip; becomes:</p>
+<pre class="prettyprint">
+enum class Mode : uint8_t { WRITE = 1, READ = 2 };
+</pre>
+
+<h2 id=bitfield>bitfield&lt;T&gt;</h2>
+<p><code>bitfield&lt;T&gt;</code> (where <code>T</code> is a user-defined enum)
+becomes the underlying type of that enum in C++. In the above example,
+<code>bitfield&lt;Mode&gt;</code> becomes <code>uint8_t</code>.</p>
+
+<h2 id=vect>vec&lt;T&gt;</h2>
+<p>The <code>hidl_vec&lt;T&gt;</code> class template is part of
+<code>libhidlbase</code> and can be used to pass a vector of any HIDL type with
+an arbitrary size. The comparable fixed size container is
+<code>hidl_array</code>. A <code>hidl_vec&lt;T&gt;</code> can also be
+initialized to point to an external data buffer of type <code>T</code>, using
+the <code>hidl_vec::setToExternal()</code> function.</p>
+
+<p>In addition to emitting/inserting the struct appropriately in the generated
+C++ header, the use of <code>vec&lt;T&gt;</code> generates some convenience
+functions to translate to/from <code>std::vector</code> and bare <code>T</code>
+pointers. If the <code>vec&lt;T&gt;</code> is used as a parameter, the function
+using it will be overloaded (two prototypes will be generated) to accept and
+pass both the HIDL struct and a <code>std::vector&lt;T&gt;</code> type for that
+parameter.</p>
+
+<h2 id=arrays>array</h2>
+<p>Constant arrays in hidl are represented by the <code>hidl_array</code> class
+in <code>libhidlbase</code>. A <code>hidl_array&lt;T, S1, S2, &hellip;,
+SN&gt;</code> represents an N dimensional fixed size array
+<code>T[S1][S2]&hellip;[SN]</code>.</p>
+
+<h2 id=string>string</h2>
+<p>The <code>hidl_string</code> class (part of <code>libhidlbase</code>) can be
+used to pass strings over HIDL interfaces and is defined in
+<code>/system/libhidl/base/include/hidl/HidlSupport.h</code>. The first storage
+location in the class is a pointer to its character buffer.</p>
+
+<p><code>hidl_string</code> knows how to convert to and from
+<code>std::string and char*</code> (C-style string) using
+<code>operator=</code>, implicit casts, and <code>.c_str()</code> function.
+HIDL string structs has the appropriate copy constructors and assignment
+operators to:</p>
+
+<ul>
+<li>Load the HIDL string from an <code>std::string</code> or a C string.</li>
+<li>Create a new <code>std::string</code> from a HIDL string.</li>
+</ul>
+
+<p>In addition, HIDL strings have conversion constructors so C strings
+(<code>char *</code>) and C++ strings (<code>std::string</code>) can be used on
+methods that take a HIDL string.</p>
+
+<h2 id=struct>struct</h2>
+<p>A <code>struct</code> in HIDL can contain only fixed-size data types and no
+functions. HIDL struct definitions map directly to standard-layout
+<code>struct</code>s in C++, ensuring that <code>struct</code>s have a
+consistent memory layout. A struct can include HIDL types, including
+<code>handle</code>, <code>string</code>, and <code>vec&lt;T&gt;</code>, that
+point to separate variable-length buffers.</p>
+
+<h2 id=handle>handle</h2>
+
+<p class=warning><strong>WARNING:</strong> Addresses of any kind (even physical
+device addresses) must never be part of a native handle. Passing this
+information between processes is dangerous and makes them susceptible to attack.
+Any values passed between processes must be validated before being used to look
+up allocated memory within a process. Otherwise, bad handles may cause bad
+memory access or memory corruption.</p>
+
+<p>The <code>handle</code> type is represented by the <code>hidl_handle</code>
+structure in C++, which is a simple wrapper around a pointer to a
+<code>const native_handle_t</code> object (this has been present in Android for
+a long time).</p>
+
+<pre>
+typedef struct native_handle
+{
+ int version; /* sizeof(native_handle_t) */
+ int numFds; /* number of file descriptors at &amp;data[0] */
+ int numInts; /* number of ints at &amp;data[numFds] */
+ int data[0]; /* numFds + numInts ints */
+} native_handle_t;
+</pre>
+
+<p>By default, <code>hidl_handle</code> does <strong>not</strong> take ownership
+of the <code>native_handle_t</code> pointer it wraps. It merely exists to safely
+store a pointer to a <code>native_handle_t</code> such that it can be used in
+both 32- and 64-bit processes.</p>
+
+<p>Scenarios in which the <code>hidl_handle</code> does own its enclosed file
+descriptors include:</p>
+<ul>
+<li>Following a call to the <code>setTo(native_handle_t* handle, bool
+shouldOwn)</code> method with the <code>shouldOwn</code> parameter set to
+<code>true</code></li>
+<li>When the <code>hidl_handle</code> object is created by copy construction
+from another <code>hidl_handle</code> object</li>
+<li>When the <code>hidl_handle</code> object is copy-assigned from another
+<code>hidl_handle</code> object</li>
+</ul>
+
+<p><code>hidl_handle</code> provides both implicit and explicit conversions
+to/from <code>native_handle_t* </code>objects. The main use for the
+<code>handle</code> type in HIDL is to pass file descriptors over HIDL
+interfaces. A single file descriptor is therefore represented by a
+<code>native_handle_t</code> with no <code>int</code>s and a single
+<code>fd</code>. If the client and server live in a different process, the RPC
+implementation will automatically take care of the file descriptor to ensure
+both processes can operate on the same file.</p>
+
+<p>Although a file descriptor received in a <code>hidl_handle</code> by a
+process will be valid in that process, it will not persist beyond the receiving
+function (it will be closed once the function returns). A process that wants to
+retain persistent access to the file descriptor must <code>dup()</code> the
+enclosed file descriptors, or copy the entire <code>hidl_handle</code> object.
+</p>
+
+<h2 id=memory>memory</h2>
+<p>The HIDL <code>memory</code> type maps to the <code>hidl_memory</code> class
+in <code>libhidlbase</code>, which represents unmapped shared memory. This is
+the object that must be passed between processes to share memory in HIDL. To
+use shared memory:</p>
+
+<ol>
+<li>Obtain an instance of <code>IAllocator</code> (currently only instance
+"ashmem" is available) and use it to allocate shared memory.</li>
+<li><code>IAllocator::allocate()</code> returns a <code>hidl_memory</code>
+object that can be passed through HIDL RPC and be mapped into a process using
+<code>libhidlmemory</code>'s <code>mapMemory</code> function.</li>
+<li><code>mapMemory</code> returns a reference to an
+<code>sp&lt;IMemory&gt;</code> object that can be used to access the memory.
+(<code>IMemory</code> and <code>IAllocator</code> are defined in
+<code>android.hidl.memory@1.0</code>.)</li>
+</ol>
+
+<p>An instance of <code>IAllocator</code> can be used to allocate memory:</p>
+<pre class="prettyprint">
+#include &lt;android/hidl/allocator/1.0/IAllocator.h&gt;
+#include &lt;android/hidl/memory/1.0/IMemory.h&gt;
+#include &lt;hidlmemory/mapping.h&gt;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hardware::hidl_memory;
+....
+ sp&lt;IAllocator&gt; ashmemAllocator = IAllocator::getService("ashmem");
+ ashmemAllocator-&gt;allocate(2048, [&amp;](bool success, const hidl_memory&amp; mem) {
+ if (!success) { /* error */ }
+ // now you can use the hidl_memory object 'mem' or pass it around
+ }));
+</pre>
+
+<p>Actual changes to the memory must be done through an <code>IMemory</code>
+object, either on the side that created <code>mem</code> or on the side that
+receives it over HIDL RPC.</p>
+
+<pre class="prettyprint">
+// Same includes as above
+
+sp&lt;IMemory&gt; memory = mapMemory(mem);
+void* data = memory-&gt;getPointer();
+memory-&gt;update();
+// update memory however you wish after calling update and before calling commit
+data[0] = 42;
+memory-&gt;commit();
+// …
+memory-&gt;update(); // the same memory can be updated multiple times
+// …
+memory-&gt;commit();
+</pre>
+
+<h2 id=interfaces>interface</h2>
+<p>Interfaces can be passed as objects. The word <em>interface</em> can be used
+as syntactic sugar for the type <code>android.hidl.base@1.0::IBase</code>;
+in addition, the current interface and any imported interfaces will be defined
+as a type.</p>
+
+<p>Variables that hold Interfaces should be strong pointers:
+<code>sp&lt;IName&gt;</code>. HIDL functions that take interface parameters
+will convert raw pointers to strong pointers, causing non-intuitive behavior
+(the pointer can be cleared unexpectedly). To avoid problems, always store HIDL
+interfaces as a <code>sp&lt;&gt;</code>.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-java/constants.html b/en/devices/architecture/hidl-java/constants.html
new file mode 100644
index 00000000..30c55b95
--- /dev/null
+++ b/en/devices/architecture/hidl-java/constants.html
@@ -0,0 +1,87 @@
+<html devsite>
+ <head>
+ <title>Exporting Constants</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>In cases where an interface is not Java-compatible (because it uses unions
+for example) it may still be desirable to export the constants (enum values) to
+the Java world. This scenario is supported by <code>hidl-gen -Ljava-constants
+&hellip;</code> which extracts annotated enum declarations from the interface
+file(s) in a package and produces a java library named
+<code>[PACKAGE-NAME]-V[PACKAGE-VERSION]-java-constants</code>. Annotate each
+enum declaration to be exported as follows:</p>
+
+<pre class="prettyprint">
+@export
+enum Foo : int32_t {
+ SOME_VALUE,
+ SOME_OTHER_VALUE,
+};
+</pre>
+
+<p>If necessary, the name under which this type is exported to the Java world
+can be different from that chosen in the interface declaration by adding the
+annotation-parameter <code>name</code>:</p>
+
+<pre class="prettyprint">
+@export(name="JavaFoo")
+enum Foo : int32_t {
+ SOME_VALUE,
+ SOME_OTHER_VALUE,
+};
+</pre>
+
+<p>If Java conventions or personal preference ask for a common prefix to be
+added to the enum type's values, use the annotation-parameter
+<code>value_prefix</code>:</p>
+
+<pre class="prettyprint">
+// File "types.hal".
+
+package android.hardware.bar@1.0;
+
+@export(name="JavaFoo", value_prefix="JAVA_")
+enum Foo : int32_t {
+ SOME_VALUE,
+ SOME_OTHER_VALUE,
+};
+</pre>
+
+<p>The resulting Java class appears as follows:</p>
+
+<pre class="prettyprint">
+package android.hardware.bar.V1_0;
+
+public class Constants {
+ public final class JavaFoo {
+ public static final int JAVA_SOME_VALUE = 0;
+ public static final int JAVA_SOME_OTHER_VALUE = 1;
+ };
+};
+</pre>
+
+<p>Finally, Java type declaration for enum types declared in
+<code>types.hal</code> are grouped inside a class <code>Constants</code> in the
+given package. Enum types declared as children of an interface will be grouped
+under that interface's Java class declaration.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-java/index.html b/en/devices/architecture/hidl-java/index.html
new file mode 100644
index 00000000..3b94247e
--- /dev/null
+++ b/en/devices/architecture/hidl-java/index.html
@@ -0,0 +1,186 @@
+<html devsite>
+ <head>
+ <title>HIDL Java</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 re-architects the Android OS to define clear interfaces between the
+device-independent Android platform and device- and vendor-specific code.
+Android already defines many such interfaces in the form of HAL interfaces,
+defined as C headers in <code>hardware/libhardware</code>. HIDL replaces these
+HAL interfaces with stable, versioned interfaces, which can be in Java
+(described below) or as client- and server-side HIDL interfaces in
+<a href="/devices/architecture/hidl-cpp/index.html">C++</a>.</p>
+
+<p>HIDL interfaces are intended to be used primarily from native code, and as a
+result HIDL is focused on the auto-generation of efficient code in C++. However,
+HIDL interfaces must also be able to be used directly from Java as some Android
+subsystems (such as Telephony) will most likely have Java HIDL interfaces.</p>
+
+<p>The pages in this section describe the Java frontend for HIDL interfaces,
+detail how to create, register, and use services, and explain how HALs and HAL
+clients written in Java interact with the HIDL RPC system.</p>
+
+<h2 id=client>Being a client</h2>
+<p>To access an interface IFoo in package <code>android.hardware.foo</code>
+version 1.0 that is registered as service name <code>foo-bar</code>:</p>
+
+<ol>
+<li>Add libraries:
+
+<ul>
+<li>Add the following to Android.mk:
+<pre class="prettyprint">LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java</pre>
+
+<strong>OR</strong><br>
+</li>
+
+<li>Add the following to Android.bp:
+<pre class="prettyprint">
+shared_libs: [
+ /* &hellip; */
+ "android.hardware.foo-V1.0-java",
+],
+</pre>
+The static version of the library is also available as
+<code>android.hardware.foo-V1.0-java-static</code>.</li>
+</ul>
+</li>
+<li>Add the following to your Java file:
+<pre class="prettyprint">
+import android.hardware.foo.V1_0.IFoo;
+...
+IFoo server = IFoo.getService(); // throws exception if not available
+IFoo anotherServer = IFoo.getService("second_impl");
+server.doSomething(&hellip;);
+</pre>
+</li>
+</ol>
+
+<h2 id=service>Providing a service</h2>
+<p>Framework code in Java may need to serve interfaces to receive asynchronous
+callbacks from HALs.</p>
+
+<p class=warning><strong>Warning</strong>: Do not implement a driver (HAL) in
+Java. We strongly recommend you implement drivers in C++.</p>
+
+<p>For interface <code>IFooCallback</code> in version 1.0 of package
+<code>android.hardware.foo</code>, you can implement your interface in Java
+using the following steps:</p>
+
+<ol>
+<li>Define your interface in HIDL.</li>
+<li>Open <code>/tmp/android/hardware/foo/IFooCallback.java</code> as a
+reference.</li>
+<li>Create a new module for your Java implementation.</li>
+<li>Examine the abstract class
+<code>android.hardware.foo.V1_0.IFooCallback.Stub</code>, then write a new class
+to extend it and implement the abstract methods.</li>
+</ol>
+
+<h3 id=autogen>Viewing auto-generated files</h3>
+<p>To view the automatically-generated files, run:</p>
+<pre class="prettyprint">
+hidl-gen -o /tmp -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
+</pre>
+
+<p>These commands generate the directory
+<code>/tmp/android/hardware/foo/1.0</code>. For the file
+<code>hardware/interfaces/foo/1.0/IFooCallback.hal</code>, this generates the
+file <code>/tmp/android/hardware/foo/1.0/IFooCallback.java</code>, which
+encapsulates the Java interface, the proxy code, and the stubs (both proxy and
+stubs conform to the interface).</p>
+
+<p><code>-Lmakefile</code> generates the rules that run this command at build
+time and allow you to include
+<code>android.hardware.foo-V1.0-java(-static)?</code> and link against the
+appropriate files. A script that automatically does this for a project full of
+interfaces can be found at <code>hardware/interfaces/update-makefiles.sh</code>.
+The paths in this example are relative; hardware/interfaces can be a temporary
+directory under your code tree to enable you to develop a HAL prior to
+publishing it.</p>
+
+<h2 id=service>Running a service</h2>
+<p>The HAL provides an interface <code>IFoo</code>, which must make asynchronous
+callbacks to the framework over interface <code>IFooCallback</code>. The
+<code>IFooCallback</code> interface is not registered by name as a discoverable
+service; instead, <code>IFoo</code> must contain a method such as
+<code>setFooCallback(IFooCallback x)</code>.</p>
+
+<p>To set up <code>IFooCallback</code> from version 1.0 of package
+<code>android.hardware.foo</code>, add
+<code>android.hardware.foo-V1.0-java</code> to <code>Android.mk</code>. The code
+to run the service is:</p>
+
+<pre class="prettyprint">
+import android.hardware.foo.V1_0.IFoo;
+import android.hardware.foo.V1_0.IFooCallback.Stub;
+....
+class FooCallback extends IFoo.Stub {
+ // implement methods
+}
+....
+// Get the service you will be receiving callbacks from.
+// This also starts the threadpool for your callback service.
+IFoo server = IFoo.getService(); // throws exception if not available
+....
+// This must be a persistent instance variable, not local,
+// to avoid premature garbage collection.
+FooCallback mFooCallback = new FooCallback();
+....
+// Do this once to create the callback service and tell the "foo-bar" service
+server.setFooCallback(mFooCallback);
+</pre>
+
+<h2 id=extensions>Interface extensions</h2>
+<p>Assuming a given service implements an interface <code>IFoo</code> across all
+devices, it's possible that on a particular device the service may provide
+additional capabilities implemented in an interface extension
+<code>IBetterFoo</code>, i.e.:</p>
+
+<pre class="prettyprint">
+interface IFoo {
+ ...
+};
+
+interface IBetterFoo extends IFoo {
+ ...
+};
+</pre>
+
+<p>Calling code aware of the extended interface can use the
+<code>castFrom()</code> Java method to safely cast the base interface to the
+extended interface:</p>
+
+<pre class="prettyprint">
+IFoo baseService = Foo.getService();
+IBetterFoo extendedService = IBetterFoo.castFrom(baseService);
+if (extendedService != null) {
+ // The service implements the extended interface.
+} else {
+ // The service only implements the base interface.
+}
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-java/interfaces.html b/en/devices/architecture/hidl-java/interfaces.html
new file mode 100644
index 00000000..024b64ce
--- /dev/null
+++ b/en/devices/architecture/hidl-java/interfaces.html
@@ -0,0 +1,151 @@
+<html devsite>
+ <head>
+ <title>Interface Methods &amp; Errors</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>This section details interface methods and errors.</p>
+
+<h2 id=void>Void methods</h2>
+<p>Methods that do not return results are translated into Java methods that
+return <code>void</code>. For example, the HIDL declaration:</p>
+
+<pre class="prettyprint">
+doThisWith(float param);
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+void doThisWith(float param);
+</pre>
+
+<h2 id=single-result>Single-result methods</h2>
+<p>Methods that return a single result are translated into their Java
+equivalents also returning a single result. For example, the following:</p>
+
+<pre class="prettyprint">
+doQuiteABit(int32_t a, int64_t b,
+ float c, double d) generates (double something);
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+double doQuiteABit(int a, long b, float c, double d);
+</pre>
+
+
+<h2 id=multiple-result>Multiple-result methods</h2>
+<p>For each method that returns more than one result, a callback class is
+generated that supplies all the results in its <code>onValues</code> method.
+That callback acts as an additional parameter to the method. For example, the
+following:</p>
+
+<pre class="prettyprint">
+oneProducesTwoThings(SomeEnum x) generates (double a, double b);
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+public interface oneProducesTwoThingsCallback {
+ public void onValues(double a, double b);
+}
+void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);
+</pre>
+
+<p>A caller of <code>oneProducesTwoThings()</code> would typically use an
+anonymous inner class or lambda to implement the callback locally:</p>
+
+<pre class="prettyprint">
+someInstanceOfFoo.oneProducesTwoThings(
+ 5 /* x */,
+ new IFoo.oneProducesTwoThingsCallback() {
+ @Override
+ void onValues(double a, double b) {
+ // do something interesting with a and b.
+ ...
+ }});
+</pre>
+
+<p>or:</p>
+
+<pre class="prettyprint">
+someInstanceOfFoo.oneProducesTwoThings(5 /* x */,
+ (a, b) -&gt; a &gt; 3.0 ? f(a, b) : g(a, b)));
+</pre>
+
+<p>You can also define a class to use as a callback … </p>
+
+<pre class="prettyprint">
+class MyCallback implements oneProducesTwoThingsCallback {
+ public void onValues(double a, double b) {
+ // do something interesting with a and b.
+ }
+}
+</pre>
+
+<p>… and pass an instance of <code>MyCallback</code> as the third parameter to
+<code>oneProducesTwoThings()</code>.</p>
+
+<h2 id=errors>Transport errors and death recipients</h2>
+<p>Because service implementations can run in a different process, in some cases
+the client can stay alive even when the process implementing an interface dies.
+Calls on an interface object hosted in a dead process fail with a transport
+error (a runtime exception thrown by the called method). Recovery from such a
+failure is possible by requesting a new instance of the service by calling
+<code>I&lt;InterfaceName&gt;.getService()</code>. However, this method works
+only if the process that crashed has restarted and re-registered its services
+with the servicemanager (which is generally true for HAL implementations).</p>
+
+<p>Clients of an interface can also register a <em>death recipient</em> to get a
+notification when a service dies. Transport errors can still occur if a call is
+made just as the server dies. To register for such notifications on a retrieved
+<code>IFoo</code> interface, a client can do the following:</p>
+
+<pre class="prettyprint">
+foo.linkToDeath(recipient, 1481 /* cookie */);
+</pre>
+
+<p>The <code>recipient</code> parameter must be an implementation of the
+interface <code>HwBinder.DeathRecipient</code> provided by HIDL. The interface
+contains a single method <code>serviceDied()</code> that is called when the
+process hosting the interface dies.</p>
+
+<pre class="prettyprint">
+final class DeathRecipient implements HwBinder.DeathRecipient {
+ @Override
+ public void serviceDied(long cookie) {
+ // Deal with service going away
+ }
+}
+</pre>
+
+<p>The <code>cookie</code> parameter contains the cookie that was passed with
+the call to <code>linkToDeath()</code>. It's also possible to unregister a death
+recipient after registering it using:</p>
+
+<pre class="prettyprint">
+foo.unlinkToDeath(recipient);
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl-java/types.html b/en/devices/architecture/hidl-java/types.html
new file mode 100644
index 00000000..8cc2d258
--- /dev/null
+++ b/en/devices/architecture/hidl-java/types.html
@@ -0,0 +1,161 @@
+<html devsite>
+ <head>
+ <title>Data Types</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>Given a HIDL interface file, the Java HIDL backend generates Java interfaces,
+Stub, and Proxy code. It supports all scalar HIDL types
+([<code>u</code>]<code>int</code>{<code>8,16,32,64}_t, float, double,</code> and
+<code>enum</code>s), as well as strings, interfaces, struct types, and arrays
+and vectors of supported HIDL types. The Java HIDL backend <strong>does NOT
+support union types, native handles, shared memory, and fmq types</strong>.</p>
+
+<p>As Java runtime does not support the concept of unsigned integers natively,
+all unsigned types (and enums based on them) are silently treated as their
+signed equivalents, i.e. <code>uint32_t</code> becomes an <code>int</code> in
+the Java interface. No value conversion is performed; the implementor on the
+Java side must use the signed values as if they were unsigned.</p>
+
+<h2 id=enum>Enums</h2>
+<p>Enums do not generate Java enum classes but are instead translated into inner
+classes containing a static constant definition for each enum case. If the enum
+class derives from some other enum class, it inherits that class's storage type.
+Enumerations based on an unsigned integer type are rewritten into their signed
+equivalent.</p>
+
+<p>For example, a <code>SomeBaseEnum</code> with a type of
+<code>uint8_t</code>:</p>
+
+<pre class="prettyprint">
+enum SomeBaseEnum : uint8_t { foo = 3 };
+enum SomeEnum : SomeBaseEnum {
+ quux = 33,
+ goober = 127
+};
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+public final class SomeBaseEnum { public static final byte foo = 3; }
+public final class SomeEnum {
+ public static final byte foo = 3;
+ public static final byte quux = 33;
+ public static final byte goober = 127;
+}
+</pre>
+
+<p>And:</p>
+
+<pre class="prettyprint">
+enum SomeEnum : uint8_t {
+ FIRST_CASE = 10,
+ SECOND_CASE = 192
+};
+</pre>
+
+<p>… is rewritten as:</p>
+
+<pre class="prettyprint">
+public final class SomeEnum {
+ static public final byte FIRST_CASE = 10; // no change
+ static public final byte SECOND_CASE = -64;
+}
+</pre>
+
+<h2 id=string>Strings</h2>
+<p><code>String</code>s in Java are utf-8 or utf-16 but are converted to utf-8
+as the common HIDL type when transported. Additionally, a <code>String</code>
+must not be null when passed into HIDL.</p>
+
+<h2 id=array-vect>Arrays and vectors</h2>
+<p>Arrays are translated into Java arrays and vectors are translated into
+<code>ArrayList&lt;T&gt;</code> where T is the appropriate object type, possibly
+wrapping scalar types such as <code>vec&lt;int32_t&gt; =&gt;
+ArrayList&lt;Integer&gt;</code>). For example:</p>
+
+<pre class="prettyprint">
+takeAnArray(int32_t[3] array);
+returnAVector() generates (vec&lt;int32_t&gt; result);
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+void takeAnArray(int[] array);
+ArrayList&lt;Integer&gt; returnAVector();
+</pre>
+
+<h2 id=struct>Structures</h2>
+<p>Structures are translated into Java classes with a similar layout. For
+example:</p>
+
+<pre class="prettyprint">
+struct Bar {vec&lt;bool&gt; someBools;
+ };
+ struct Foo {
+ int32_t a;
+ int8_t b;
+ float[10] c;
+ Bar d;
+ };
+</pre>
+
+<p>… becomes:</p>
+
+<pre class="prettyprint">
+class Bar {
+ public final ArrayList&lt;Boolean&gt; someBools = new ArrayList();
+};
+class Foo {
+ public int a;
+ public byte b;
+ public final float[] c = new float[10];
+ public final Bar d = new Bar();
+}
+</pre>
+
+<h2 id=declared>Declared types</h2>
+<p>Each top-level type declared in <code>types.hal</code> gets its own .java
+output file (as required by Java). For example, the following
+<code>types.hal</code> file results in two extra files being created (Foo.java
+and Bar.java):</p>
+
+<pre class="prettyprint">
+struct Foo {
+ ...
+};
+
+struct Bar {
+ ...
+
+ struct Baz {
+ };
+
+ ...
+};
+</pre>
+
+<p>The definition of Baz lives in a static inner class of Bar (in Bar.java).</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/binder-ipc.html b/en/devices/architecture/hidl/binder-ipc.html
new file mode 100644
index 00000000..811bc3b7
--- /dev/null
+++ b/en/devices/architecture/hidl/binder-ipc.html
@@ -0,0 +1,315 @@
+<html devsite>
+ <head>
+ <title>Using Binder IPC</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>This page describes changes to the binder driver in Android O, provides
+details on using binder IPC, and lists required SELinux policy.</p>
+
+<h2 id=binder-changes>Changes to binder driver</h2>
+
+<p>Starting in Android O, the Android framework and HALs now communicate with
+each other using binder. As this communication dramatically increases binder
+traffic, Android O includes several improvements designed to keep binder IPC
+fast. SoC vendors and OEMs integrating the latest version of the driver should
+review the list of these improvements, relevant SHAs for the 3.18, 4.4, and 4.9
+kernels, and required userspace changes.</p>
+
+<h3 id=contexts>Multiple binder domains (contexts)</h3>
+<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em>
+<p>
+To cleanly split the binder traffic between framework (device-independent) and
+vendor (device-specific) code, Android O introduces the concept of a <em>binder
+context</em>. Each binder context has its own device node and its own context
+(service) manager. You can access the context manager only through the device
+node to which it belongs and, when passing a binder node through a certain
+context, it is accessible from that same context only by another process, thus
+completely isolating the domains from each other. For details on using, see
+<a href="#vndbinder">vndbinder</a> and
+<a href="#vndservicemanager">vndservicemanager</a>.
+</p>
+
+
+<h3 id=scatter>Scatter-gather</h3>
+<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em>
+<p>
+In previous releases of Android, every piece of data in a binder call was copied
+three times:
+</p>
+<ul>
+<li>Once to serialize it into a
+<code><a href="https://developer.android.com/reference/android/os/Parcel.html">Parcel</a></code>
+in the calling process</li>
+<li>Once in the kernel driver to copy the <code>Parcel</code> to the target
+process</li>
+<li>Once to unserialize the <code>Parcel</code> in the target process</li>
+</ul>
+
+<p>
+Android O uses
+<a href="https://en.wikipedia.org/wiki/Vectored_I/O">scatter-gather
+optimization</a> to reduce the number of copies from 3 to 1. Instead of
+serializing data in a <code>Parcel</code> first, data remains in its original
+structure and memory layout and the driver immediately copies it to the target
+process. After the data is in the target process, the structure and memory
+layout is the same and the data can be read without requiring another copy.
+</p>
+
+<h3 id=locking>Fine-grained locking</h3>
+<em>In common-3.18, common-4.4, common-4.9, and upstream</em>
+
+<p>
+In previous Android releases, the binder driver used a global lock to protect
+against concurrent access to critical data structures. While there was minimal
+contention for the lock, the main problem was that if a low-priority thread
+obtained the lock and then got preempted, it could seriously delay
+higher-priority threads needing to obtain the same lock. This caused jank in the
+platform.
+</p>
+<p>
+Initial attempts to resolve this problem involved disabling preemption while
+holding the global lock. However, this was more of a hack than a true solution,
+and was eventually rejected by upstream and discarded. Subsequent attempts
+focused on making locking more fine-grained, a version of which has been running
+on Pixel devices since January 2017. While the majority of those changes were
+made public, substantial improvements were made in future versions.
+</p>
+<p>
+After identifying small issues in the fine-grained locking implementation, we
+devised an improved solution with a different locking architecture and submitted
+the changes in the 3.18, 4.4, and 4.9 common branches. We continue to test this
+implementation on a large number of different devices; as we are unaware of any
+outstanding issues, this is the recommended implementation for devices shipping
+with Android O.
+</p>
+<p class="note"><strong>Note:</strong> We strongly encourage budgeting
+sufficient testing hours for fine-grained locking.
+</p>
+<h3 id=rt-priority>Real-time priority inheritance</h3>
+<em>In common-3.18, common-4.4, common-4.9 (upstream coming soon)</em>
+
+<p>
+The binder driver has always supported nice priority inheritance. As an
+increasing number of processes in Android run at real-time priority, in some
+cases it now makes sense that if a real-time thread makes a binder call, the
+thread in the process that handles that call also runs at real-time priority. To
+support these use cases, Android O now implements real-time priority inheritance
+in the binder driver.
+</p>
+<p>
+In addition to transaction-level priority inheritance, <em>node priority
+inheritance</em> allows a node (binder service object) to specify a minimum
+priority at which calls into this node should be executed. Previous versions of
+Android already supported node priority inheritance with nice values, but
+Android O adds support for real-time scheduling policies node inheritance.
+</p>
+<p class="note"><strong>Note:</strong> The Android performance team found that
+real-time priority inheritance caused unwanted side-effects in the framework
+binder domain (<code>/dev/binder</code>), so real-time priority inheritance is
+<strong>disabled</strong> for that domain.
+</p>
+
+<h3 id=userspace>Userspace changes</h3>
+<p>
+Android O includes all userspace changes required to work with the current
+binder driver in the common kernel with one exception: The original
+implementation to disable real-time priority inheritance for
+<code>/dev/binder</code> used an
+<a href="https://android.googlesource.com/kernel/msm/+/868f6ee048c6ff51dbd92353dd5c68bea4419c78" class="external">ioctl</a>. Subsequent development switched control of priority
+inheritance to a more fine-grained method that is per binder mode (and not per
+context). Thus, the ioctl is not in the Android common branch and is instead
+<a href="https://android-review.googlesource.com/#/c/421861/" class="external">submitted
+in our common kernels</a>.
+</p>
+<p>
+The effect of this change is that real-time priority inheritance is disabled by
+default for <em>every</em> node. The Android performance team has found it
+beneficial to enable real-time priority inheritance for all nodes in the
+<code>hwbinder</code> domain. To achieve that same effect, cherry-pick
+<a href="https://android-review.googlesource.com/#/c/440359/" class="external">this
+change</a> in userspace.
+</p>
+<h3 id=shas>SHAs for common kernels</h3>
+<p>
+To obtain necessary changes to the binder driver, sync to the SHAs below (or
+later):
+</p>
+<ul>
+<li>Common-3.18<br>
+cc8b90c121de ANDROID: binder: don't check prio permissions on restore.</li>
+<li>Common-4.4<br>
+76b376eac7a2 ANDROID: binder: don't check prio permissions on restore.</li>
+<li>Common-4.9<br>
+ecd972d4f9b5 ANDROID: binder: don't check prio permissions on restore.</li>
+</ul>
+
+<h2 id=ipc>Using binder IPC</h2>
+<p>Historically, vendor processes have used binder interprocess communication
+(IPC) to communicate. In Android O, the <code>/dev/binder</code> device node
+becomes exclusive to framework processes, meaning vendor processes no longer
+have access to it. Vendor processes can access <code>/dev/hwbinder</code>, but
+must convert their AIDL interfaces to use HIDL. For vendors who want to continue
+using AIDL interfaces between vendor processes, Android supports binder IPC as
+described below.</p>
+
+<h3 id=vndbinder>vndbinder</h3>
+<p>Android O supports a new binder domain for use by vendor services, accessed
+using <code>/dev/vndbinder</code> instead of <code>/dev/binder</code>. With the
+addition of <code>/dev/vndbinder</code>, Android now has the following three
+IPC domains:</p>
+
+<table>
+ <tr>
+ <th>IPC Domain</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>/dev/binder</code></td>
+ <td>IPC between framework/app processes with AIDL interfaces</td>
+ </tr>
+ <tr>
+ <td><code>/dev/hwbinder</code></td>
+ <td>IPC between framework/vendor processes with HIDL interfaces
+ <br>IPC between vendor processes with HIDL interfaces</td>
+ </tr>
+ <tr>
+ <td><code>/dev/vndbinder</code></td>
+ <td>IPC between vendor/vendor processes with AIDL Interfaces</td>
+ </tr>
+</table>
+
+<p>For <code>/dev/vndbinder</code> to appear, ensure the kernel configuration
+item <code>CONFIG_ANDROID_BINDER_DEVICES</code> is set to
+<code>"binder,hwbinder,vndbinder"</code> (this is the default in Android's
+common kernel trees).</p>
+
+<p>Normally, vendor processes don't open the binder driver directly and instead
+link against the <code>libbinder</code> userspace library, which opens the
+binder driver. Adding a method for <code>::android::ProcessState()</code>
+selects the binder driver for <code>libbinder</code>. Vendor processes should
+call this method <strong>before</strong> calling into <code>ProcessState,</code>
+<code>IPCThreadState</code>, or before making any binder calls in general. To
+use, place the following call after the <code>main()</code> of a vendor process
+(client and server):</p>
+
+<pre class="prettyprint">ProcessState::initWithDriver("/dev/vndbinder");</pre>
+
+<h3 id=vndservicemanager>vndservicemanager</h3>
+<p>Previously, binder services were registered with <code>servicemanager</code>,
+where they could be retrieved by other processes. In Android O,
+<code>servicemanager</code> is now used exclusively by framework and app
+processes and vendor processes can no longer access it.</p>
+
+<p>However, vendor services can now use <code>vndservicemanager</code>, a new
+instance of <code>servicemanager</code> that uses <code>/dev/vndbinder</code>
+instead of <code>/dev/binder</code> and which is built from the same sources as
+framework <code>servicemanager</code>. Vendor processes do not need to make
+changes to talk to <code>vndservicemanager</code>; when a vendor process opens
+/<code>dev/vndbinder</code>, service lookups automatically go to
+<code>vndservicemanager</code>.</p>
+
+<p>The <code>vndservicemanager</code> binary is included in Android's default
+device makefiles.</p>
+
+<h2 id=selinux>SELinux policy</h2>
+<p>Vendor processes that want to use binder functionality to communicate with
+each other need the following:</p>
+<ol>
+<li>Access to <code>/dev/vndbinder</code>.</li>
+<li>Binder <code>{transfer, call}</code> hooks into
+<code>vndservicemanager</code>.</li>
+<li><code>binder_call(A, B)</code> for any vendor domain A that wants to call
+into vendor domain B over the vendor binder interface.</li>
+<li>Permission to <code>{add, find}</code> services in
+<code>vndservicemanager</code>.</li>
+</ol>
+
+<p>To fulfill requirements 1 and 2, use the <code>vndbinder_use()</code>
+macro:</p>
+
+<pre class="prettyprint">vndbinder_use(some_vendor_process_domain);</pre>
+
+<p>To fulfill requirement 3, the <code>binder_call(A, B)</code> for vendor
+processes A and B that need to talk over binder can stay in place, and doesn't
+need renaming.</p>
+
+<p>To fulfill requirement 4, you must make changes in the way service names,
+service labels, and rules are handled.</p>
+
+<p>For details on SELinux, see
+<a href="https://source.android.com/security/selinux/">Security-Enhanced Linux
+in Android</a>. For details on SELinux in Android 8.0, see
+<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
+8.0</a>.</p>
+
+<h3 id=names>Service names</h3>
+<p>Previously, vendor processes registered service names in a
+<code>service_contexts</code> file and added corresponding rules for accessing
+that file. Example <code>service_contexts</code> file from
+<code>device/google/marlin/sepolicy</code>:</p>
+
+<pre class="devsite-click-to-copy">
+AtCmdFwd u:object_r:atfwd_service:s0
+cneservice u:object_r:cne_service:s0
+qti.ims.connectionmanagerservice u:object_r:imscm_service:s0
+rcs u:object_r:radio_service:s0
+uce u:object_r:uce_service:s0
+vendor.qcom.PeripheralManager u:object_r:per_mgr_service:s0
+</pre>
+
+<p>In Android O, <code>vndservicemanager</code> loads the
+<code>vndservice_contexts</code> file instead. Vendor services migrating to
+<code>vndservicemanager</code> (and which are already in the old
+<code>service_contexts</code> file) should be added to the new
+<code>vndservice_contexts</code> file.</p>
+
+<h3 id=labels>Service labels</h3>
+<p>Previously, service labels such as <code>u:object_r:atfwd_service:s0</code>
+were defined in a <code>service.te</code> file. Example:</p>
+
+<pre class="prettyprint">type atfwd_service, service_manager_type;</pre>
+
+<p>In Android O, you must change the type to
+<code>vndservice_manager_type</code> and move the rule to the
+<code>vndservice.te</code> file. Example:</p>
+
+<pre class="prettyprint">type atfwd_service, vndservice_manager_type;</pre>
+
+<h3 id=rules>Servicemanager rules</h3>
+<p>Previously, rules granted domains access to add or find services from
+<code>servicemanager</code>. Example:</p>
+
+<pre class="prettyprint">
+allow atfwd atfwd_service:service_manager find;
+allow some_vendor_app atfwd_service:service_manager add;
+</pre>
+
+<p>In Android O, such rules can stay in place and use the same class. Example:
+</p>
+
+<pre class="prettyprint">
+allow atfwd atfwd_service:service_manager find;
+allow some_vendor_app atfwd_service:service_manager add;
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/code-style.html b/en/devices/architecture/hidl/code-style.html
new file mode 100644
index 00000000..0746ff36
--- /dev/null
+++ b/en/devices/architecture/hidl/code-style.html
@@ -0,0 +1,718 @@
+<html devsite>
+ <head>
+ <title>Code Style Guide</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>The HIDL code style resembles C++ code in the Android framework, with 4-space
+indents and mixed-case filenames. Package declarations, imports, and docstrings
+are similar to those in Java, with slight modifications.</p>
+
+<p>The following examples for <code>IFoo.hal</code> and <code>types.hal</code>
+illustrate HIDL code styles and provide quick links to details on each style
+(<code>IFooClientCallback.hal</code>, <code>IBar.hal</code>, and
+<code>IBaz.hal</code> have been omitted).</p>
+
+<table>
+<tr><th><code>hardware/interfaces/foo/1.0/IFoo.hal</code></th></tr>
+<tr><td><pre class="prettyprint">
+/*
+ * (License Notice)
+ */
+
+<a href="#package-names">package</a> android.hardware.foo@<a href="#versions">1.0</a>;
+
+<a href="#imports">import</a> android.hardware.bar@1.0::IBar;
+
+import IBaz;
+import IFooClientCallback;
+
+/**
+ * IFoo is an interface that&#8230;
+ */
+interface <a href="#interface-names">IFoo</a> {
+
+ /**
+ * This is a <a href="#comments">multiline docstring</a>.
+ * <a href="#return">@return</a> result 0 if successful, nonzero otherwise.
+ */
+ <a href="#function-declarations">foo() generates (FooStatus result);</a>
+
+ /**
+ * Restart controller by power cycle.
+ * <a href="#param">@param</a> bar callback interface that&#8230;
+ * @return result 0 if successful, nonzero otherwise.
+ */
+ <a href="#functions">powerCycle</a>(IBar bar) generates (FooStatus <a href="#functions">result</a>);
+
+ /** <a href="#comments">Single line docstring</a>. */
+ baz();
+
+
+ /**
+ * The bar function.
+ * <a href="#param">@param</a> <a href="#functions">clientCallback</a> callback after function is called
+ * @param baz related baz object
+ * @param data input data blob
+ */
+ bar(IFooClientCallback clientCallback,
+ IBaz baz,
+ FooData data);
+
+};
+</pre>
+</td></tr></table>
+
+<table>
+<tr><th><code>hardware/interfaces/foo/1.0/types.hal</code></th></tr>
+<tr><td><pre class="prettyprint">
+/*
+ * (License Notice)
+ */
+
+package android.hardware.foo@1.0;
+
+<a href="#comments">/** Replied status. */</a>
+<a href="#enum-declarations">enum Status : int32_t</a> {
+ <a href="#enum-values">OK</a>,
+ ERR_ARG, <a href="#comments">// invalid arguments</a>
+ ERR_UNKNOWN = -1, // note, no transport related errors
+};
+
+<a href="#struct-declarations">struct ArgData</a> {
+ <a href="#array-declarations">int32_t[20] someArray;</a>
+ <a href="#vectors">vec&lt;uint8_t&gt; data;</a>
+};
+</pre>
+</td></tr></table>
+
+<h2 id=naming>Naming conventions</h2>
+<p>Function names, variable names, and filenames should be descriptive; avoid
+over-abbreviation. Treat acronyms as words (e.g., use <code>INfc</code> instead
+of <code>INFC</code>.</p>
+
+<h3 id=dir-structure>Directory structure and file naming</h3>
+<p>The directory structure should appear as follows:</p>
+<ul>
+<li><code><var>ROOT-DIRECTORY</var></code>
+ <ul>
+ <li><code><var>MODULE</var></code>
+ <ul>
+ <li><code><var>SUBMODULE</var></code> (optional, could be more than one
+ level)
+ <ul>
+ <li><code><var>VERSION</var></code>
+ <ul>
+ <li><code>Android.mk</code></li>
+ <li><code>I<var>INTERFACE_1</var>.hal</code></li>
+ <li><code>I<var>INTERFACE_2</var>.hal</code></li>
+ <li><code>&#8230;</code></li>
+ <li><code>I<var>INTERFACE_N</var>.hal</code></li>
+ <li><code>types.hal</code> (optional)</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+</li>
+</ul>
+
+<p>Where:</p>
+<ul>
+<li><code><var>ROOT-DIRECTORY</var></code> is:
+ <ul>
+ <li><code>hardware/interfaces</code> for core HIDL packages.</li>
+ <li><code>vendor/<var>VENDOR</var>/interfaces</code> for vendor packages,
+ where <code><var>VENDOR</var></code> refers to an SoC vendor or an
+ OEM/ODM.</li>
+ </ul>
+ </li>
+<li><code><var>MODULE</var></code> should be one lowercase word that describes
+the subsystem (e.g. <code>nfc</code>). If more than one word is needed, use
+nested <code><var>SUBMODULE</var></code>. There can be more than one level of
+nesting.</li>
+<li><code><var>VERSION</var></code> should be the exact same version
+(major.minor) as described in <a href="#versions">Versions</a>.</li>
+<li><code>I<var>INTERFACE_X</var></code> should be the interface name with
+<code>UpperCamelCase</code>/<code>PascalCase</code> (e.g. <code>INfc</code>)
+as described in <a href="#interface-names">Interface names</a>.</li>
+</ul>
+
+<p>Example:</p>
+<ul>
+<li><code>hardware/interfaces</code>
+ <ul>
+ <li><code>nfc</code>
+ <ul>
+ <li><code>1.0</code>
+ <ul>
+ <li><code>Android.mk</code></li>
+ <li><code>INfc.hal</code></li>
+ <li><code>INfcClientCallback.hal</code></li>
+ <li><code>types.hal</code></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> All files must have non-executable
+permissions (in Git).
+
+<h3 id=package-names>Package names</h3>
+<p>Package names must use the following <a href="#fqn">fully-qualified name
+(FQN)</a> format (referred to as <code><var>PACKAGE-NAME</var></code>):</p>
+
+<pre class="prettyprint">
+<var>PACKAGE</var>.<var>MODULE</var>[.<var>SUBMODULE</var>[.<var>SUBMODULE</var>[&#8230;]]]@<var>VERSION</var>
+</pre>
+
+<p>Where:</p>
+<ul>
+<li><code><var>PACKAGE</var></code> is the package that maps to the
+<code><var>ROOT-DIRECTORY</var></code>. In particular,
+<code><var>PACKAGE</var></code> is:
+ <ul>
+ <li><code>android.hardware</code> for core HIDL packages (mapping to
+ <code>hardware/interfaces</code>).</li>
+ <li><code>vendor.<var>VENDOR</var>.hardware</code> for vendor packages, where
+ <code><var>VENDOR</var></code> refers to an SoC vendor or an OEM/ODM (mapping
+ to <code>vendor/<var>VENDOR</var>/interfaces</code>).</li>
+ </ul>
+<li><code><var>MODULE</var>[.<var>SUBMODULE</var>[.<var>SUBMODULE</var>[&#8230;]]]@<var>VERSION</var></code>
+are the exact same folder names in the structure described in
+<a href="#dir-structure">Directory structure</a>.</li>
+<li>Package names should be lowercase. If they are more than one word long, the
+words should either be used as submodules or written in <code>snake_case</code>.
+</li>
+<li>No spaces are allowed.</li>
+</ul>
+
+<p>The FQN is always used in package declarations.</p>
+
+<h3 id=versions>Versions</h3>
+<p>
+Versions should have the following format:
+</p>
+
+<pre class="prettyprint"><var>MAJOR</var>.<var>MINOR</var></pre>
+
+<p>Both the <var>MAJOR</var> and the <var>MINOR</var> version should be a single
+integer. HIDL uses <a href="http://semver.org/" class="external">semantic
+versioning</a> rules.</p>
+
+<h3 id=imports>Imports</h3>
+<p>An import has one of the following three formats:</p>
+<ul>
+<li>Whole-package imports: <code>import <var>PACKAGE-NAME</var>;</code></li>
+<li>Partial imports: <code>import
+<var>PACKAGE-NAME</var>::<var>UDT</var>;</code> (or, if the imported
+type is in the same package,<code>import <var>UDT</var>;</code></li>
+<li>Types-only imports: <code>import <var>PACKAGE-NAME</var>::types;</code></li>
+</ul>
+
+<p>The <code><var>PACKAGE-NAME</var></code> follows the format in
+<a href="#package-names">Package names</a>. The current package's
+<code>types.hal</code> (if it exists) is automatically imported (do not import
+it explicitly).</p>
+
+<h4 id=fqn>Fully qualified names (FQNs)</h4>
+<p>Use fully qualified names for a user-defined type import only when necessary.
+Omit <code><var>PACKAGE-NAME</var></code> if the import type is in the same
+package. An FQN must not contain spaces. Example of a fully qualified name:</p>
+
+<pre class="prettyprint">android.hardware.nfc@1.0::INfcClientCallback</pre>
+
+<p>In another file under <code>android.hardware.nfc@1.0</code>, refer to the
+above interface as <code>INfcClientCallback</code>. Otherwise, use only the
+fully qualified name.</p>
+
+<h4 id=grouping>Grouping and ordering imports</h4>
+<p>Use an empty line after package declaration (before the imports). Each import
+should occupy a single line and should not be indented. Group imports in the
+following order:</p>
+
+<ol>
+<li>Other <code>android.hardware</code> packages (use fully qualified names).
+</li>
+<li>Other <code>vendor.<var>VENDOR</var></code> packages (use fully qualified
+names).
+ <ul>
+ <li>Each vendor should be a group.</li>
+ <li>Order vendors alphabetically.</li>
+ </ul>
+ </li>
+<li>Imports from other interfaces in the same package (use simple names).</li>
+</ol>
+
+<p>Use an empty line between groups. Inside each group, sort imports
+alphabetically. Example:</p>
+
+<pre class="prettyprint">
+import android.hardware.nfc@1.0::INfc;
+import android.hardware.nfc@1.0::INfcClientCallback;
+
+// Importing the whole module.
+import vendor.barvendor.bar@3.1;
+
+import vendor.foovendor.foo@2.2::IFooBar;
+import vendor.foovendor.foo@2.2::IFooFoo;
+
+import IBar;
+import IFoo;
+</pre>
+
+<h3 id=interface-names>Interface names</h3>
+<p>Interface names must start with an <code>I</code>, followed by an
+<code>UpperCamelCase</code>/<code>PascalCase</code> name. An interface with name
+<code>IFoo</code> must be defined in the file <code>IFoo.hal</code>. This file
+can contain definitions only for the <code>IFoo</code> interface (the interface
+<code>I<var>NAME</var></code> should be in <code>I<var>NAME</var>.hal</code> ).
+</p>
+
+<h3 id=functions>Functions</h3>
+<p>For function names, arguments, and return variable names, use
+<code>lowerCamelCase</code>. Example:</p>
+
+<pre class="prettyprint">
+open(INfcClientCallback clientCallback) generates (int32_t retVal);
+oneway pingAlive(IFooCallback cb);
+</pre>
+
+<h3 id=struct-union>Struct/union field names</h3>
+<p>For struct/union field names, use <code>lowerCamelCase</code>. Example:</p>
+
+<pre class="prettyprint">
+struct FooReply {
+ vec&lt;uint8_t&gt; replyData;
+}
+</pre>
+
+<h3 id=type-names>Type names</h3>
+<p>Type names refer to struct/union definitions, enum type definitions, and
+<code>typedef</code>s. For these name, use
+<code>UpperCamelCase</code>/<code>PascalCase</code>. Examples:</p>
+
+<pre class="prettyprint">
+enum NfcStatus : int32_t {
+ /*...*/
+};
+struct NfcData {
+ /*...*/
+};
+</pre>
+
+<h3 id=enum-values>Enum values</h3>
+<p>Enum values should be <code>UPPER_CASE_WITH_UNDERSCORES</code>. When passing
+enum values as function arguments and returning them as function returns, use
+the actual enum type (not the underlying integer type). Example:</p>
+
+<pre class="prettyprint">
+enum NfcStatus : int32_t {
+ HAL_NFC_STATUS_OK = 0,
+ HAL_NFC_STATUS_FAILED = 1,
+ HAL_NFC_STATUS_ERR_TRANSPORT = 2,
+ HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 3,
+ HAL_NFC_STATUS_REFUSED = 4
+};
+</pre>
+
+<p class="note"><strong>Note:</strong> The underlying type of an enum type is
+explicitly declared after the colon. As it is not compiler dependent, using the
+actual enum type is clearer.</p>
+
+<p>For fully qualified names for enum values, a <strong>colon</strong> is used
+between the enum type name and the enum value name:</p>
+
+<pre class="prettyprint">
+<var>PACKAGE-NAME</var>::<var>UDT</var>[.<var>UDT</var>[.<var>UDT</var>[&#8230;]]:<var>ENUM_VALUE_NAME</var>
+</pre>
+
+<p>There must not be spaces inside a fully qualified name. Use a fully qualified
+name only when necessary and omit unnecessary parts. Example:</p>
+
+<pre class="prettyprint">
+android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK
+</pre>
+
+<h2 id=comments>Comments</h2>
+<p>For a single line comment, both <code>// </code>and <code>/** */</code> are
+fine.</p>
+<pre class="prettyprint">
+// This is a single line comment
+/* This is also single line comment */
+/** This is documentation comment */
+</pre>
+
+<ul>
+<li>Use <code>//</code> mainly for:
+ <ul>
+ <li>trailing comments</li>
+ <li>Comments that will not be used for generated documentation</li>
+ <li>TODOs</li>
+ </ul>
+</li>
+<li>Use <code>/** */</code> mainly for Function documents/"docstrings" used for
+generated documentation. Example:
+<pre class="prettyprint">
+/** Replied status */
+enum FooStatus {
+ OK = 0, // no error
+ ERR_TRANSPORT = 1, // transport level error
+ ERR_ARG = 2 // invalid args
+}
+</pre>
+<li>Multi-line comments should start a new line with <code>/**</code>, use
+<code>*</code> at the beginning of each line, and place <code>*/</code> on the
+last line all on its own (asterisks should align). Example:
+<pre class="prettyprint">
+/**
+ * My multi-line
+ * comment
+ */
+</pre>
+</li>
+<li>Licensing notice and changelogs should start a new line with <code>/*</code>
+(a single asterisk), use <code>*</code> at the beginning of each line, and place
+<code>*/</code> on the last line all on its own (asterisks should align).
+Example:
+<pre class="prettyprint">
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * ...
+ */
+
+/*
+ * Changelog:
+ * ...
+ */
+</pre>
+</li>
+</ul>
+
+<h3 id=file-comments>File comments</h3>
+<p>Start each file with the appropriate licensing notice. For core HALs, this
+should be the AOSP Apache license in
+<a href="https://android.googlesource.com/platform/development/+/master/docs/copyright-templates/c.txt" class="external"><code>development/docs/copyright-templates/c.txt</code></a>.
+Remember to update the year and use <code>/* */</code> style multi-line comments
+as explained above.</p>
+
+<p>You can optionally place an empty line after the license notice, followed
+by a changelog/versioning information. Use <code>/* */</code> style
+multi-line comments as explained above, place the empty line after the
+changelog, then follow with the package declaration.</p>
+
+<h3 id=todo-comments>TODO comments</h3>
+<p>TODOs should include the string <code>TODO</code> in all caps followed by a
+colon. Example:</p>
+<pre>// TODO: remove this code before foo is checked in.</pre>
+
+<p class="alert">TODO comments are allowed only during development; they must
+not exist in published interfaces.</p>
+
+<h3 id=docstrings>Interface/Function comments (docstrings)</h3>
+<p>Use <code>/** */</code> for multi-line and single line docstrings. Do not use
+<code>//</code> for docstrings.</p>
+
+<p>Docstrings for interfaces should describe general mechanisms of the
+interface, design rationale, purpose, etc. Docstrings for functions should be
+specific to the function (package-level documentation goes in a README file in
+the package directory).</p>
+
+<pre class="prettyprint">
+/**
+ * IFooController is the controller for foos.
+ */
+interface IFooController {
+ /**
+ * Opens the controller.
+ * @return status HAL_FOO_OK if successful.
+ */
+ open() generates (FooStatus status);
+
+ /** Close the controller. */
+ close();
+};
+</pre>
+
+<p>You must add <code>@param</code>s and <code>@return</code>s for each
+parameter/return value:</p>
+
+<ul>
+<li id=param><code>@param</code> must be added for each parameter. It should be
+followed by the name of the parameter then the docstring.</li>
+<li id=return><code>@return</code> must be added for each return value. It
+should be followed by the name of the return value then the docstring.</li>
+</ul>
+<p>Example:</p>
+
+<pre class="prettyprint">
+/**
+ * Explain what foo does.
+ * @param arg1 explain what arg1 is
+ * @param arg2 explain what arg2 is
+ * @return ret1 explain what ret1 is
+ * @return ret2 explain what ret2 is
+ */
+foo(T arg1, T arg2) generates (S ret1, S ret2);
+</pre>
+
+<h2>Formatting</h2>
+<p>General formatting rules include:</p>
+<ul>
+<li><strong>Line length</strong>. Each line of text should be at most
+<strong>80</strong> columns long.</li>
+<li><strong>Whitespaces</strong>. No trailing whitespace on lines; empty lines
+must not contain whitespaces.</li>
+<li><strong>Spaces vs. tabs</strong>. Use only spaces.</li>
+<li><strong>Indent size</strong>. Use <strong>4</strong> spaces for blocks and
+<strong>8</strong> spaces for line wraps</li>
+<li><strong>Bracing</strong>. Except for <a href="#annotations">annotation
+values</a>, an <strong>open</strong> brace goes on the same line as preceding
+code but a <strong>close</strong> brace and the following semicolon occupies
+the entire line. Example:
+<pre class="prettyprint">
+interface INfc {
+ close();
+};
+</pre>
+</li>
+</ul>
+
+<h3 id=package-declarations>Package declaration</h3>
+<p>Package declaration should be at the top of the file after the license
+notice, should occupy the entire line, and should not be indented. Packages are
+declared using the following format (for name formatting, see
+<a href="#package-names">Package names</a>):</p>
+
+<pre class="prettyprint">
+package <var>PACKAGE-NAME</var>;
+</pre>
+
+<p>Example:</p>
+
+<pre class="prettyprint">
+package android.hardware.nfc@1.0;
+</pre>
+
+<h3 id=function-declarations>Function declarations</h3>
+<p>Function name, parameters, <code>generates</code>, and return values should
+be on the same line if they fit. Example:</p>
+<pre class="prettyprint">
+interface IFoo {
+ /** ... */
+ easyMethod(int32_t data) generates (int32_t result);
+};
+</pre>
+
+<p>If they don't fit on the same line, attempt to put parameters and return
+values in the same indent level and distinguish <code>generate</code> to help
+the reader quickly see the parameters and return values. Example:</p>
+
+<pre class="prettyprint">
+interface IFoo {
+ suchALongMethodThatCannotFitInOneLine(int32_t theFirstVeryLongParameter,
+ int32_t anotherVeryLongParameter);
+ anEvenLongerMethodThatCannotFitInOneLine(int32_t theFirstLongParameter,
+ int32_t anotherVeryLongParameter)
+ generates (int32_t theFirstReturnValue,
+ int32_t anotherReturnValue);
+ superSuperSuperSuperSuperSuperSuperLongMethodThatYouWillHateToType(
+ int32_t theFirstVeryLongParameter, // 8 spaces
+ int32_t anotherVeryLongParameter
+ ) generates (
+ int32_t theFirstReturnValue,
+ int32_t anotherReturnValue
+ );
+ // method name is even shorter than 'generates'
+ foobar(AReallyReallyLongType aReallyReallyLongParameter,
+ AReallyReallyLongType anotherReallyReallyLongParameter)
+ generates (ASuperLongType aSuperLongReturnValue, // 4 spaces
+ ASuperLongType anotherSuperLongReturnValue);
+}
+</pre>
+
+<p>Additional details:</p>
+<ul>
+<li>An open parenthesis is always on the same line as the function name.</li>
+<li>No spaces between the function name and the open parenthesis.</li>
+<li>No spaces between the parentheses and parameters <em>except</em> when there
+are line feeds between them.</li>
+<li>If <code>generates</code> is on the same line as the previous closing
+parenthesis, use a preceding space. If <code>generates</code> is on the same
+line as the next open parenthesis, follow with a space.</li>
+<li>Align all parameters and return values (if possible).</li>
+<li>Default indentation is 4 spaces.</li>
+<li>Wrapped parameters are aligned to the first parameters on the previous line,
+otherwise they have an 8-space indent.</li>
+</ul>
+
+<h3 id=annotations>Annotations</h3>
+<p>Use the following format for annotations:</p>
+
+<pre class="prettyprint">
+@annotate(keyword = value, keyword = {value, value, value})
+</pre>
+
+<p>Sort annotations in alphabetical order, and use spaces around equal signs.
+Example:</p>
+
+<pre class="prettyprint">
+@callflow(key = value)
+@entry
+@exit
+</pre>
+
+<p>Ensure an annotation occupies the entire line. Examples:</p>
+<pre class="prettyprint">
+// Good
+@entry
+@exit
+
+// Bad
+@entry @exit
+</pre>
+
+<p>If annotations cannot fit on the same line, indent with 8 spaces.
+Example:</p>
+
+<pre class="prettyprint">
+@annotate(
+ keyword = value,
+ keyword = {
+ value,
+ value
+ },
+ keyword = value)
+</pre>
+
+<p>If the entire value array cannot fit in the same line, put line breaks after
+open braces <code>{</code> and after each comma inside the array. Place closing
+parenthesis immediately after the last value. Do not put the braces if there is
+only one value.</p>
+
+<p>If the entire value array can fit in the same line, do not use spaces after
+open braces and before closing braces and use one space after each comma.
+Examples:</p>
+
+<pre class="prettyprint">
+// Good
+@callflow(key = {"val", "val"})
+
+// Bad
+@callflow(key = { "val","val" })
+</pre>
+
+<p>There must NOT be empty lines between annotations and the function
+declaration. Examples:</p>
+<pre class="prettyprint">
+// Good
+@entry
+foo();
+
+// Bad
+@entry
+
+foo();
+</pre>
+
+<h3 id=enum-declarations>Enum declarations</h3>
+<p>Use the following rules for enum declarations:</p>
+<ul>
+<li>If enum declarations are shared with another package, put the declarations
+in <code>types.hal</code> rather than embedding inside an interface.</li>
+<li>Use a space before and after the colon, and space after the underlying type
+before the open brace.</li>
+<li>The last enum value may or may not have an extra comma.</li>
+</ul>
+
+<h3 id=struct-declarations>Struct declarations</h3>
+<p>Use the following rules for struct declarations:</p>
+<ul>
+<li>If struct declarations are shared with another package, put the declarations
+in <code>types.hal</code> rather than embedding inside an interface.</li>
+<li>Use a space after the struct type name before the open brace.</li>
+<li>Align field names (optional). Example:
+<pre class="prettyprint">
+struct MyStruct {
+ vec&lt;uint8_t&gt; data;
+ int32_t someInt;
+}
+</pre>
+</li>
+</ul>
+
+<h3 id=array-declarations>Array declarations</h3>
+<p>Do not put spaces between the following:</p>
+<ul>
+<li>Element type and open square bracket.</li>
+<li>Open square bracket and array size.</li>
+<li>Array size and close square bracket.</li>
+<li>Close square bracket and the next open square bracket, if more than one
+dimension exists.</li>
+</ul>
+
+<p>Examples:</p>
+<pre class="prettyprint">
+// Good
+int32_t[5] array;
+
+// Good
+int32_t[5][6] multiDimArray;
+
+// Bad
+int32_t [ 5 ] [ 6 ] array;
+</pre>
+
+<h3 id=vectors>Vectors</h3>
+<p>Do not put spaces between the following:</p>
+<ul>
+<li><code>vec</code> and open angle bracket.</li>
+<li>Open angle bracket and element type (<em>Exception: element type is also a
+<code>vec</code></em>).</li>
+<li>Element type and close angle bracket (<em>Exception: element type is also a
+<code>vec</code>)</em>.</li>
+</ul>
+
+<p>Examples:</p>
+<pre class="prettyprint">
+// Good
+vec&lt;int32_t&gt; array;
+
+// Good
+vec&lt;vec&lt;int32_t&gt;&gt; array;
+
+// Good
+vec&lt; vec&lt;int32_t&gt; &gt; array;
+
+// Bad
+vec &lt; int32_t &gt; array;
+
+// Bad
+vec &lt; vec &lt; int32_t &gt; &gt; array;
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/converting.html b/en/devices/architecture/hidl/converting.html
new file mode 100644
index 00000000..d4dbacea
--- /dev/null
+++ b/en/devices/architecture/hidl/converting.html
@@ -0,0 +1,87 @@
+<html devsite>
+ <head>
+ <title>Converting HAL Modules</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 update pre-existing HAL modules to HIDL HAL modules by converting the
+header in <code>hardware/libhardware/include/hardware</code>.</p>
+
+<h2 id=c2hal>Using c2hal</h2>
+<p>The
+<code><a href="https://android.googlesource.com/platform/system/tools/hidl/+/master/c2hal/">c2hal</code></a>
+tool handles most of the conversion work, reducing the number of required manual
+changes. For example, to generate a HIDL <code>.hal</code> file for the NFC
+HAL:</p>
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">make c2hal</code>
+c2hal -r android.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport -p android.hardware.nfc@1.0 hardware/libhardware/include/hardware/nfc.h
+</pre>
+
+<p>These commands add files in <code>hardware/interfaces/nfc/1.0/</code>. Running
+<code>hardware/interfaces/update-makefiles.sh</code> from the $ANDROID_BUILD_TOP
+directory will also add the required makefile to the HAL. From here, you can
+make manual changes to fully convert the HAL.</p>
+
+<h2 id=activities>c2hal activities</h2>
+<p>When you run <code>c2hal</code>, everything in the header file is transferred
+to <code>.hal</code> files.</p>
+
+<p><code>c2hal</code> identifies structs that contain function pointers in the
+provided header file and converts each struct into a separate interface file.
+For example, <code>alloc_device_t</code> is converted to the
+<code>IAllocDevice</code> HAL module (in the file
+<code>IAllocDevice.hal</code>).</p>
+
+<p>All other data types are copied over into a <code>types.hal</code> file.
+Pound-defines are moved into enums, and items not a part of HIDL or not
+convertible (such as static-function declarations) are copied into comments
+marked with the text "<code>NOTE</code>".</p>
+
+<h2 id=manual>Manual activities</h2>
+<p>The <code>c2hal</code> tool does not know what to do when it encounters
+certain constructs. For example, HIDL has no concept of raw pointers; because of
+this, when <code>c2hal</code> encounters a pointer in header files, it doesn't
+know whether the pointer should be interpreted as an array or as a reference to
+another object. Void pointers are also similarly opaque.</p>
+
+<p>Field such as <code>int reserved[7]</code> must be manually removed during
+the transition to HIDL. Items such as the name of the return value should be
+updated to something more meaningful; for example, converting the return
+parameter of methods such as <code>write</code> in NFC from the autogenerated
+<code>int32_t write_ret</code> to <code>Status status</code> (where
+<code>Status</code> is a new enum containing possible NFC statuses).</p>
+
+<h2 id=implement>Implementing the HAL</h2>
+<p>After you have created <code>.hal</code> files to represent your HAL, you
+must generate the makefiles (Make or Soong) that create the language support in
+C++ and Java (unless the HAL uses a feature unsupported in Java). The
+<code>./hardware/interfaces/update-makefiles.sh</code> script can automatically
+generate makefiles for HALs located in the <code>hardware/interfaces</code>
+directory (for HALs in other locations, simply update the script).</p>
+
+<p>When the makefiles are up to date, you are ready to generate header files and
+implement methods. For details on implementing the generated interface, see
+<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (for C++
+implementations) or <a href="/devices/architecture/hidl-java/index.html">HIDL
+Java</a> (for Java implementations).</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/fmq.html b/en/devices/architecture/hidl/fmq.html
new file mode 100644
index 00000000..c09fd1cc
--- /dev/null
+++ b/en/devices/architecture/hidl/fmq.html
@@ -0,0 +1,424 @@
+<html devsite>
+ <head>
+ <title>Fast Message Queue (FMQ)</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>HIDL's remote procedure call (RPC) infrastructure uses Binder mechanisms,
+meaning calls involve overhead, require kernel operations, and may trigger
+scheduler action. However, for cases where data must be transferred between
+processes with less overhead and no kernel involvement, the Fast Message Queue
+(FMQ) system is used.</p>
+
+<p>FMQ creates message queues with the desired properties. An
+<code>MQDescriptorSync</code> or <code>MQDescriptorUnsync</code> object can be
+sent over a HIDL RPC call and used by the receiving process to access the
+message queue.</p>
+
+<p class="caution">Fast Message Queues are supported only in C++.</p>
+
+<h2 id=flavors>MessageQueue types</h2>
+<p>Android supports two queue types:</p>
+<ul>
+<li><em>Unsynchronized</em> queues are allowed to overflow, and can have many
+readers; each reader must read data in time or lose it.
+<li><em>Synchronized</em> queues are not allowed to overflow, and can have only
+one reader.</li>
+</ul>
+
+<p>Both queue types are not allowed to underflow (read from an empty queue will
+fail) and can only have one writer.</p>
+
+<h3 id=unsync>Unsynchronized</h3>
+<p>An unsynchronized queue has only one writer, but can have any number of
+readers. There is one write position for the queue; however, each reader keeps
+track of its own independent read position.</p>
+
+<p>Writes to the queue always succeed (are not checked for overflow) as long as
+they are no larger than the configured queue capacity (writes larger than the
+queue capacity fail immediately). As each reader may have a different read
+position, rather than waiting for every reader to read every piece of data, data
+is allowed to fall off the queue whenever new writes need the space.</p>
+
+<p>Reads are responsible for retrieving data before it falls off the end of
+the queue. A read that attempts to read more data than is available either
+fails immediately (if nonblocking) or waits for enough data to be available (if
+blocking). A read that attempts to read more data than the queue capacity always
+fails immediately.</p>
+
+<p>If a reader fails to keep up with the writer, so that the amount of data
+written and not yet read by that reader is larger than the queue capacity, the
+next read does not return data; instead, it resets the readers read
+position to equal the latest write position then returns failure. If the
+data available to read is checked after overflow but before the next read, it
+shows more data available to read than the queue capacity, indicating
+overflow has occurred. (If the queue overflows between checking available data
+and attempting to read that data, the only indication of overflow is that the
+read fails.)</p>
+
+<h3 id=sync>Synchronized</h3>
+<p>A synchronized queue has one writer and one reader with a single write
+position and a single read position. It is impossible to write more data than
+the queue has space for or read more data than the queue currently holds.
+Depending on whether the blocking or nonblocking write or read function is
+called, attempts to exceed available space or data either return failure
+immediately or block until the desired operation can be completed. Attempts to
+read or write more data than the queue capacity will always fail immediately.
+</p>
+
+<h2 id=setup>Setting up an FMQ</h2>
+<p>A message queue requires multiple <code>MessageQueue</code> objects: one to
+be written to, and one or more to be read from. There is no explicit
+configuration of which object is used for writing or reading; it is up to the
+user to ensure that no object is used for both reading and writing, that there
+is at most one writer, and, for synchronized queues, that there is at most one
+reader.</p>
+
+<h3 id=first-object>Creating the first MessageQueue object</h3>
+<p>A message queue is created and configured with a single call:</p>
+
+<pre class="prettyprint">
+#include &lt;fmq/MessageQueue.h&gt;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::kUnsynchronizedWrite;
+using android::hardware::MQDescriptorSync;
+using android::hardware::MQDescriptorUnsync;
+using android::hardware::MessageQueue;
+....
+// For a synchronized non-blocking FMQ
+mFmqSynchronized =
+ new (std::nothrow) MessageQueue&lt;uint16_t, kSynchronizedReadWrite&gt;
+ (kNumElementsInQueue);
+// For an unsynchronized FMQ that supports blocking
+mFmqUnsynchronizedBlocking =
+ new (std::nothrow) MessageQueue&lt;uint16_t, kUnsynchronizedWrite&gt;
+ (kNumElementsInQueue, true /* enable blocking operations */);
+</pre>
+
+<ul>
+<li>The <code>MessageQueue&lt;T, flavor&gt;(numElements)</code> initializer
+creates and initializes an object that supports the message queue functionality.
+</li>
+<li>The <code>MessageQueue&lt;T, flavor&gt;(numElements,
+configureEventFlagWord)</code> initializer creates and initializes an object
+that supports the message queue functionality with blocking.</li>
+<li><code>flavor</code> can be either <code>kSynchronizedReadWrite</code> for a
+synchronized queue or <code>kUnsynchronizedWrite</code> for an unsynchronized
+queue.</li>
+<li><code>uint16_t</code> (in this example) can be any
+<a href="/devices/architecture/hidl-cpp/types.html">HIDL-defined type</a> that
+does not involve nested buffers (no <code>string</code> or <code>vec</code>
+types), handles, or interfaces.</li>
+<li><code>kNumElementsInQueue</code> indicates the size of queue in number of
+entries; it determines the size of shared memory buffer that will be allocated
+for the queue.</li>
+</ul>
+
+<h3 id=second-object>Creating the second MessageQueue object</h3>
+<p>The second side of the message queue is created using an
+<code>MQDescriptor</code> object obtained from the first side. The
+<code>MQDescriptor</code> object is sent over a HIDL RPC call to the process
+that will hold the second end of the message queue. The
+<code>MQDescriptor</code> contains information about the queue:</p>
+
+<ul>
+<li>Information to map the buffer and write pointer.</li>
+<li>If the queue is synchronized, information to map the read pointer.</li>
+<li>If the queue is blocking, information to map the event flag word.</li>
+<li>The object type is made into a template with the HIDL-defined type of queue
+elements and the flavor (synchronized or unsynchronized).</li>
+</ul>
+
+<p>The <code>MQDescriptor</code> object can be used to construct a
+<code>MessageQueue</code> object:</p>
+
+<pre class="prettyprint">
+MessageQueue&lt;T, flavor&gt;::MessageQueue(const MQDescriptor&lt;T, flavor&gt;&amp; Desc, bool resetPointers)
+</pre>
+
+<p>The <code>resetPointers</code> parameter indicates whether to reset the read
+and write positions to 0 while creating this <code>MessageQueue</code> object.
+In an unsynchronized queue, the read position (which is local to each
+<code>MessageQueue</code> object in unsynchronized queues) is always set to 0
+during creation. Typically, the <code>MQDescriptor</code> is initialized during
+creation of the first message queue object. For extra control over the shared
+memory, you can set up the <code>MQDescriptor</code> manually
+(<code>MQDescriptor</code> is defined in
+<a href="https://android.googlesource.com/platform/system/libhidl/+/master/base/include/hidl/MQDescriptor.h" class="external"><code>system/libhidl/base/include/hidl/MQDescriptor.h</code></a>)
+then create every <code>MessageQueue</code> object as described in this section.
+</p>
+
+<h3 id=blocking>Blocking queues and event flags</h3>
+<p>By default, queues do not support blocking reads/writes. There are two kinds
+of blocking read/write calls:</p>
+<ul>
+<li><em>Short form</em>, with three parameters (data pointer, number of items,
+timeout). Supports blocking on individual read/write operations on a single
+queue. When using this form, the queue will handle the event flag and bitmasks
+internally, and the first message queue object must be initialized with a
+second parameter of <code>true</code>.</li>
+<li><em>Long form</em>, with six parameters (includes event flag and bitmasks).
+Supports using a shared <code>EventFlag</code> object between multiple queues
+and allows specifying the notification bit masks to be used. In this case, the
+event flag and bitmasks must be supplied to each read and write call.</li>
+</ul>
+
+<p>For the long form, the <code>EventFlag</code> can be supplied explicitly in
+each <code>blockingRead()</code> and <code>blockingWrite()</code> call. One of
+the queues may be initialized with an internal event flag, which must then be
+extracted from that queue's <code>MessageQueue</code> objects using
+<code>getEventFlagWord()</code> and used to create <code>EventFlag</code>
+objects in each process for use with other FMQs. Alternatively, the
+<code>EventFlag</code> objects can be initialized with any suitable shared
+memory.</p>
+
+<p>In general, each queue should use only one of non-blocking, short-form
+blocking, or long-form blocking. It is not an error to mix them, but careful
+programming is required to get the desired result.</p>
+
+<h2 id=using>Using the MessageQueue</h2>
+<p>The public API of the <code>MessageQueue</code> object is:</p>
+
+<pre class="prettyprint">
+size_t availableToWrite() // Space available (number of elements).
+size_t availableToRead() // Number of elements available.
+size_t getQuantumSize() // Size of type T in bytes.
+size_t getQuantumCount() // Number of items of type T that fit in the FMQ.
+bool isValid() // Whether the FMQ is configured correctly.
+const MQDescriptor&lt;T, flavor&gt;* getDesc() // Return info to send to other process.
+
+bool write(const T* data) // Write one T to FMQ; true if successful.
+bool write(const T* data, size_t count) // Write count T's; no partial writes.
+
+bool read(T* data); // read one T from FMQ; true if successful.
+bool read(T* data, size_t count); // Read count T's; no partial reads.
+
+bool writeBlocking(const T* data, size_t count, int64_t timeOutNanos = 0);
+bool readBlocking(T* data, size_t count, int64_t timeOutNanos = 0);
+
+// Allows multiple queues to share a single event flag word
+std::atomic&lt;uint32_t&gt;* getEventFlagWord();
+
+bool writeBlocking(const T* data, size_t count, uint32_t readNotification,
+uint32_t writeNotification, int64_t timeOutNanos = 0,
+android::hardware::EventFlag* evFlag = nullptr); // Blocking write operation for count Ts.
+
+bool readBlocking(T* data, size_t count, uint32_t readNotification,
+uint32_t writeNotification, int64_t timeOutNanos = 0,
+android::hardware::EventFlag* evFlag = nullptr) // Blocking read operation for count Ts;
+
+//APIs to allow zero copy read/write operations
+bool beginWrite(size_t nMessages, MemTransaction* memTx) const;
+bool commitWrite(size_t nMessages);
+bool beginRead(size_t nMessages, MemTransaction* memTx) const;
+bool commitRead(size_t nMessages);
+</pre>
+
+<p><code>availableToWrite()</code> and <code>availableToRead()</code> can be used
+to determine how much data can be transferred in a single operation. In an
+unsynchronized queue:</p>
+
+<ul>
+<li><code>availableToWrite()</code> always returns the capacity of the queue.
+<li>Each reader has its own read position and does its own calculation for
+<code>availableToRead()</code>.</li>
+<li>From the point of view of a slow reader, the queue is allowed to overflow;
+this may result in <code>availableToRead()</code> returning a value larger than
+the size of the queue. The first read after an overflow will fail and result in
+the read position for that reader being set equal to the current write pointer,
+whether or not the overflow was reported through
+<code>availableToRead()</code>.</li>
+</ul>
+
+<p>The <code>read()</code> and <code>write()</code> methods return
+<code>true</code> if all requested data could be (and was) transferred to/from
+the queue. These methods do not block; they either succeed (and return
+<code>true</code>), or return failure (<code>false</code>) immediately.</p>
+
+<p>The <code>readBlocking()</code> and <code>writeBlocking()</code> methods wait
+until the requested operation can be completed, or until they timeout (a
+<code>timeOutNanos</code> value of 0 means never timeout).</p>
+
+<p>Blocking operations are implemented using an event flag word. By default,
+each queue creates and uses its own flag word to support the short form of
+<code>readBlocking()</code> and <code>writeBlocking()</code>. It is possible for
+multiple queues to share a single word, so that a process can wait on writes or
+reads to any of the queues. A pointer to a queue's event flag word can be
+obtained by calling <code>getEventFlagWord()</code>, and that pointer (or any
+pointer to a suitable shared memory location) can be used to create an
+<code>EventFlag</code> object to pass into the long form of
+<code>readBlocking()</code> and <code>writeBlocking()</code>for a different
+queue. The <code>readNotification</code> and <code>writeNotification</code>
+parameters tell which bits in the event flag should be used to signal reads and
+writes on that queue. <code>readNotification</code> and
+<code>writeNotification</code> are 32-bit bitmasks.</p>
+
+<p><code>readBlocking()</code> waits on the <code>writeNotification</code> bits;
+if that parameter is 0, the call always fails. If the
+<code>readNotification</code> value is 0, the call will not fail, but a
+successful read will not set any notification bits. In a synchronized queue,
+this would mean that the corresponding <code>writeBlocking()</code> call will
+never wake up unless the bit is set elsewhere. In an unsynchronized queue,
+<code>writeBlocking()</code> will not wait (it should still be used to set the
+write notification bit), and it is appropriate for reads to not set any
+notification bits. Similarly, <code>writeblocking()</code> will fail if
+<code>readNotification</code> is 0, and a successful write sets the specified
+<code>writeNotification</code> bits.</p>
+
+<p>To wait on multiple queues at once, use an <code>EventFlag</code> object's
+<code>wait()</code> method to wait on a bitmask of notifications. The
+<code>wait()</code> method returns a status word with the bits that caused the
+wake up set. Using the information, the user can then check the corresponding
+queue to see whether it has enough space or data for the desired write or read
+operation and perform a nonblocking <code>read()</code>/<code>write()</code>
+followed by a call to the <code>EventFlag</code>'s <code>wake()</code> method if
+a notification is desired after the same. For a definition of the
+<code>EventFlag</code> abstraction, refer to
+<a href="https://android.googlesource.com/platform/system/libfmq/+/master/include/fmq/EventFlag.h" class="external"><code>system/libfmq/include/fmq/EventFlag.h</code></a>.
+</p>
+
+<h2 id=zero>Zero copy operations</h2>
+<p>The
+<code>read</code>/<code>write</code>/<code>readBlocking</code>/<code>writeBlocking()</code>
+APIs take a pointer to an input/output buffer as an argument and use
+<code>memcpy()</code> calls internally to copy data between the same and the
+FMQ ring buffer. To improve performance, Android O includes a set of APIs that
+provide direct pointer access into the ring buffer, eliminating the need to use
+<code>memcpy</code> calls.</p>
+
+<p>Use the following public APIs for zero copy FMQ operations:</p>
+
+<pre class="prettyprint">
+bool beginWrite(size_t nMessages, MemTransaction* memTx) const;
+bool commitWrite(size_t nMessages);
+
+bool beginRead(size_t nMessages, MemTransaction* memTx) const;
+bool commitRead(size_t nMessages);
+</pre>
+
+<ul>
+<li>The <code>beginWrite</code> method provides base pointers into the FMQ ring
+buffer. After the data is written, commit it using <code>commitWrite()</code>.
+The<code>beginRead</code>/<code>commitRead</code> methods act the same way.</li>
+<li>The <code>beginRead</code>/<code>Write</code> methods take as input the
+number of messages to be read/written and return a boolean indicating if the
+read/write is possible. If the read or write is possible the <code>memTx</code>
+struct is populated with base pointers that can be used for direct pointer
+access into the ring buffer shared memory.</li>
+<li>The <code>MemRegion</code> struct contains details about a block of memory,
+i.e. a base pointer and length in terms of <code>T</code>(where the FMQ is
+templatized to <code>T</code>).</li>
+<li>The <code>MemTransaction</code> struct contains two <code>MemRegion</code>
+structs, <code>first</code> and <code>second</code> as a read or write into
+the ring buffer may require a wrap around to the beginning of the queue. This
+would mean that two base pointers are needed to read/write data into the FMQ
+ring buffer.</li>
+</ul>
+
+<p>To get the base address and length from a <code>MemRegion</code> struct:</p>
+
+<pre class="prettyprint">
+T* getAddress(); // gets the base address
+size_t getLength(); // gets the length of the memory region in terms of T
+size_t getLengthInBytes(); // gets the length of the memory region in bytes
+</pre>
+
+<p>To get references to the first and second <code>MemRegion</code>s within a
+<code>MemTransaction</code> object:</p>
+
+<pre class="prettyprint">
+const MemRegion&amp; getFirstRegion(); // get a reference to the first MemRegion
+const MemRegion&amp; getSecondRegion(); // get a reference to the second MemRegion
+</pre>
+
+<p>Example write to the FMQ using zero copy APIs:</p>
+
+<pre class="prettyprint">
+MessageQueueSync::MemTransaction tx;
+if (mQueue->beginRead(dataLen, &amp;tx)) {
+auto first = tx.getFirstRegion();
+auto second = tx.getSecondRegion();
+
+foo(first.getAddress(), first.getLength()); // method that performs the data write
+foo(second.getAddress(), second.getLength()); // method that performs the data write
+
+if(commitWrite(dataLen) == false) {
+//report error
+}
+} else {
+//report error
+}
+</pre>
+
+<p>The following helper methods are also part of <code>MemTransaction</code>:
+</p>
+
+<ul>
+<li><code>T* getSlot(size_t idx);</code>
+<br>Returns a pointer to slot <code>idx</code> within the
+<code>MemRegions</code> that are part of this <code>MemTransaction</code>
+object. If the <code>MemTransaction</code> object is representing the memory
+regions to read/write N items of type T, then the valid range of
+<code>idx</code> is between 0 and N-1.</li>
+<li><code>bool copyTo(const T* data, size_t startIdx, size_t nMessages = 1);</code>
+<br>Write <code>nMessages</code>' items of type T into the memory regions
+described by the object, starting from index <code>startIdx</code>. This method
+uses <code>memcpy()</code> and is not to meant to be used for a zero copy
+operation. If the <code>MemTransaction</code> object represents memory to
+read/write N items of type T, then the valid range of <code>idx</code> is
+between 0 and N-1.</li>
+<li><code>bool copyFrom(T* data, size_t startIdx, size_t nMessages = 1);</code>
+<br>Helper method to read <code>nMessages</code>' items of type T from the
+memory regions described by the object starting from <code>startIdx</code>. This
+method uses <code>memcpy()</code> and is not meant to be used for a zero copy
+operation.</li>
+</ul>
+
+<h2 id=sending>Sending the queue over HIDL</h2>
+<p>On the creating side:</p>
+<ol>
+<li>Create message queue object as described above.</li>
+<li>Verify the object is valid with <code>isValid()</code>.</li>
+<li>If you will be waiting on multiple queues by passing an
+<code>EventFlag</code> into the long form of
+<code>readBlocking()</code>/<code>writeBlocking()</code>, you can extract the
+event flag pointer (using <code>getEventFlagWord()</code>) from a
+<code>MessageQueue</code> object that was initialized to create the flag, and
+use that flag to create the necessary <code>EventFlag</code> object.</li>
+<li>Use the <code>MessageQueue</code> <code>getDesc()</code> method to get a
+descriptor object.</li>
+<li>In the <code>.hal</code> file, give a method a parameter of type
+<code>fmq_sync<T></code> or <code>fmq_unsync<T></code> where <code>T</code> is a
+suitable HIDL-defined type. Use this to send the object returned by
+<code>getDesc()</code> to the receiving process.</li>
+</ol>
+
+<p>On the receiving side:</p>
+<ol>
+<li>Use the descriptor object to create a <code>MessageQueue</code> object. Be
+sure to use the same queue flavor and data type, or the template will fail to
+compile.</li>
+<li>If you extracted an event flag, extract the flag from the corresponding
+<code>MessageQueue</code> object in the receiving process.</li>
+<li>Use the <code>MessageQueue</code> object to transfer data.</li>
+</ol>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/hashing.html b/en/devices/architecture/hidl/hashing.html
new file mode 100644
index 00000000..e083fd4c
--- /dev/null
+++ b/en/devices/architecture/hidl/hashing.html
@@ -0,0 +1,165 @@
+<html devsite>
+ <head>
+ <title>Interface Hashing</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>This document describes HIDL interface hashing, a mechanism to prevent
+accidental interface changes and ensure interface changes are thoroughly vetted.
+This mechanism is required because HIDL interfaces are versioned, which means
+that after an interface is released it must not be changed except in an
+Application Binary Interface (ABI) preserving manner (such as a comment
+correction).</p>
+
+<h2 id=layout>Layout</h2>
+<p>Every package root directory (i.e. <code>android.hardware</code> mapping to
+<code>hardware/interfaces</code> or <code>vendor.foo</code> mapping to
+<code>vendor/foo/hardware/interfaces</code>) must contain a
+<code>current.txt</code> file that lists all released HIDL interface files.</p>
+
+<pre class="prettyprint">
+# current.txt files support comments starting with a ‘#' character
+# this file, for instance, would be vendor/foo/hardware/interfaces/current.txt
+
+# Each line has a SHA-256 hash followed by the name of an interface.
+# They have been shortened in this doc for brevity but they are
+# 64 characters in length in an actual current.txt file.
+d4ed2f0e...995f9ec4 vendor.awesome.foo@1.0::IFoo # comments can also go here
+
+# types.hal files are also noted in types.hal files
+c84da9f5...f8ea2648 vendor.awesome.foo@1.0::types
+
+# Multiple hashes can be in the file for the same interface. This can be used
+# to note how ABI sustaining changes were made to the interface.
+# For instance, here is another hash for IFoo:
+
+# Fixes type where "FooCallback" was misspelled in comment on "FooStruct"
+822998d7...74d63b8c vendor.awesome.foo@1.0::IFoo
+</pre>
+
+<p class=note><strong>Note:</strong> To help keep track of which hashes come
+from where, Google separates HIDL <code>current.txt</code> files into different
+sections: The first section is <em>Released in Android O</em>; the next section
+will be <em>Released in Android O MR1</em>. We strongly recommend using a
+similar layout in your <code>current.txt</code> file.</p>
+
+<h2 id=hidl-gen>Hashing with hidl-gen</h2>
+<p>You can add a hash to a <code>current.txt</code> file manually or by
+using <code>hidl-gen</code>. The following code snippet provides examples of
+commands you can use with <code>hidl-gen</code> to manage a
+<code>current.txt</code> file (hashes have been shortened):</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::types</code>
+9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types
+<code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::INfc</code>
+07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc
+<code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0</code>
+9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types
+07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc
+f2fe5442...72655de6 vendor.awesome.nfc@1.0::INfcClientCallback
+<code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0 &gt;&gt; vendor/awesome/hardware/interfaces/current.txt</code>
+</pre>
+
+<p class="warning"><strong>Warning:</strong> Do not replace a hash for a
+previously-released interface. When changing such an interface, add a new hash
+to the end of the <code>current.txt</code> file. For details, refer to
+<a href="#abi-stability">ABI stability</a>.</p>
+
+<p>Every interface definition library generated by <code>hidl-gen</code>
+includes hashes, which can be retrieved by calling
+<code>IBase::getHashChain</code>. When <code>hidl-gen</code> is compiling an
+interface, it checks the <code>current.txt</code> file in the root directory of
+the HAL package to see if the HAL has been changed:</p>
+
+<ul>
+<li>If no hash for the HAL is found, the interface is considered unreleased (in
+development) and compilation proceeds.</li>
+<li>If hashes are found, they are checked against the current interface:
+<ul>
+<li>If the interface does match the hash, compilation proceeds.</li>
+<li>If the interface does not match a hash, compilation is halted as this means a previously-released interface is being changed.
+<ul>
+<li>For an ABI-preserving change (see
+<a href="#abi-stability">ABI stability</a>), the <code>current.txt</code> file
+must be modified before compilation can proceed.</li>
+<li>All other changes should be made in a minor or major version upgrade of the
+interface.</li>
+</ul></li></ul></li></ul>
+
+<h2 id=abi-stability>ABI stability</h2>
+<aside class="key-point"><strong>Key Point:</strong> Please read and understand
+this section carefully.</aside>
+
+<p>An Application Binary Interface (ABI) includes the binary
+linkages/calling conventions/etc. If the ABI/API changes, the interface no
+longer works with a generic <code>system.img</code> that was compiled with
+official interfaces.</p>
+
+<p>Making sure that interfaces are versioned and ABI stable is
+<strong>crucial</strong> for several reasons:</p>
+
+<ul>
+<li>It ensures your implementation can pass the Vendor Test Suite (VTS), which
+puts you on track to being able to do framework-only OTAs.</li>
+<li>As an OEM, it enables you to provide a Board Support Package (BSP) that is
+straightforward to use and compliant.</li>
+<li>It helps you keep track of what interfaces can be released. Consider
+<code>current.txt</code> a map of an interfaces directory that allows you to see
+the history and state of all interfaces being provided in a package root.</li>
+</ul>
+
+<p>When adding a new hash for an interface that already has an entry in
+<code>current.txt</code>, make sure to add only the hashes that represent
+interfaces which maintain ABI stability. Review the following types of changes:
+</p>
+
+<table>
+<tbody>
+
+<tr>
+<th>Changes allowed</th>
+<td>
+<ul>
+<li>Changing a comment (unless this changes the meaning of a method).</li>
+<li>Changing the name of a parameter.</li>
+<li>Changing the name of a return parameter.</li>
+<li>Changing annotations.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<th>Changes not allowed</th>
+<td>
+<ul>
+<li>Reordering arguments, methods, etc…</li>
+<li>Adding a method/struct field/etc… anywhere in the interface.</li>
+<li>Anything that would break a C++ vtable.</li>
+<li>etc..</li>
+</ul>
+</td>
+</tr>
+
+</tbody>
+</table>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/index.html b/en/devices/architecture/hidl/index.html
new file mode 100644
index 00000000..20f4a607
--- /dev/null
+++ b/en/devices/architecture/hidl/index.html
@@ -0,0 +1,337 @@
+<html devsite>
+ <head>
+ <title>HIDL</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>HAL interface definition language or HIDL (pronounced "hide-l") is an
+interface description language (IDL) to specify the interface between a HAL and
+its users. It allows specifying types and method calls, collected into
+interfaces and packages. More broadly, HIDL is a system for communicating
+between codebases that may be compiled independently.</p>
+
+<p>HIDL is intended to be used for inter-process communication (IPC).
+Communication between processes is referred to as
+<a href="/devices/architecture/hidl/binder-ipc"><em>Binderized</em></a>. For
+libraries that must be linked to a process, a <a href="#passthrough">passthough
+mode</a> is also available (not supported in Java).</p>
+
+<p>HIDL specifies data structures and method signatures, organized in interfaces
+(similar to a class) that are collected into packages. The syntax of HIDL will
+look familiar to C++ and Java programmers, though with a different set of
+keywords. HIDL also uses Java-style annotations.</p>
+
+<h2 id=design>HIDL design</h2>
+<p>The goal of HIDL is that the framework can be replaced without having to
+rebuild HALs. HALs will be built by vendors or SOC makers and put in a
+<code>/vendor</code> partition on the device, enabling the framework, in its own
+partition, to be replaced with an OTA without recompiling the HALs.</p>
+
+<p>HIDL design balances the following concerns:</p>
+<ul>
+<li><strong>Interoperability</strong>. Create reliably interoperable interfaces
+between processes which may be compiled with various architectures, toolchains,
+and build configurations. HIDL interfaces are versioned and cannot be changed
+after they are published.</li>
+<li><strong>Efficiency</strong>. HIDL tries to minimize the number of copy
+operations. HIDL-defined data is delivered to C++ code in C++ standard layout
+data structures that can be used without unpacking. HIDL also provides shared
+memory interfaces and, as RPCs are inherently somewhat slow, HIDL supports two
+ways to transfer data without using an RPC call: shared memory and a Fast
+Message Queue (FMQ).</li>
+<li><strong>Intuitive</strong>. HIDL avoids thorny issues of memory ownership by
+using only <code>in</code> parameters for RPC (see
+<a href="https://developer.android.com/guide/components/aidl.html" class="external">Android
+Interface Definition Language (AIDL)</a>); values that cannot be efficiently
+returned from methods are returned via callback functions. Neither passing data
+into HIDL for transfer nor receiving data from HIDL changes the ownership of the
+data&mdash;ownership always remains with the calling function. Data needs to
+persist only for the duration of the called function and may be destroyed
+immediately after the called function returns.</li>
+</ul>
+
+<h2 id=passthrough>Using passthrough mode</h2>
+<p>To update devices running earlier versions of Android to Android O, you can
+wrap both conventional (and legacy) HALs in a new HIDL interface that serves the
+HAL in binderized and same-process (passthrough) modes. This wrapping is
+transparent to both the HAL and the Android framework.</p>
+
+<p>Passthrough mode is available only for C++ clients and implementations.
+Devices running earlier versions of Android do not have HALs written in Java, so
+Java HALs are inherently binderized.</p>
+
+<h3 id=header>Passthrough header files</h3>
+<p>When a <code>.hal</code> file is compiled, <code>hidl-gen</code> produces an
+extra passthrough header file <code>BsFoo.h</code> in addition to the headers
+used for binder communication; this header defines functions to be
+<code>dlopen</code>ed. As passthrough HALs run in the same process in which
+they are called, in most cases passthrough methods are invoked by direct
+function call (same thread). <code>oneway</code> methods run in their own thread
+as they are not intended to wait for the HAL to process them (this means any HAL
+that uses <code>oneway</code> methods in passthrough mode must be thread-safe).
+</p>
+
+<p>Given an <code>IFoo.hal</code>, <code>BsFoo.h</code> wraps the HIDL-generated
+methods to provide additional features (such as making <code>oneway</code>
+transactions run in another thread). This file is similar to
+<code>BpFoo.h</code>, however instead of passing on calls IPC using binder, the
+desired functions are directly invoked. Future implementations of HALs
+<strong>may provide</strong> multiple implementations, such as FooFast HAL and a
+FooAccurate HAL. In such cases, a file for each additional implementation would
+be created (e.g., <code>PTFooFast.cpp</code> and
+<code>PTFooAccurate.cpp</code>).</p>
+
+<h3 id=binderized>Binderizing passthrough HALs</h3>
+<p>You can binderize HAL implementations that support passthrough mode. Given a
+HAL interface <code>a.b.c.d@M.N::IFoo</code>, two packages are created:</p>
+
+<ul>
+<li><code>a.b.c.d@M.N::IFoo-impl</code>. Contains the implementation of the HAL
+and exposes function <code>IFoo* HIDL_FETCH_IFoo(const char* name)</code>. On
+legacy devices, this package is <code>dlopen</code>ed and the implementation is
+instantiated using <code>HIDL_FETCH_IFoo</code>. You can generate the base code
+using <code>hidl-gen</code> and <code>-Lc++-impl</code> and
+<code>-Landroidbp-impl</code>.</li>
+<li><code>a.b.c.d@M.N::IFoo-service</code>. Opens the passthrough HAL and
+registers itself as a binderized service, enabling the same HAL implementation
+to be used as both passthrough and binderized.</li>
+</ul>
+
+<p>Given the type <code>IFoo</code>, you can call <code>sp&lt;IFoo&gt;
+IFoo::getService(string name, bool getStub)</code> to get access to an instance
+of <code>IFoo</code>. If <code>getStub</code> is true, <code>getService</code>
+attempts to open the HAL only in passthrough mode. If <code>getStub</code> is
+false, <code>getService</code> attempts to find a binderized service; if that
+fails, it then tries to find the passthrough service. The <code>getStub</code>
+parameter should never be used except in
+<code>defaultPassthroughServiceImplementation</code>. (Devices launching with
+Android O are fully binderized devices, so opening a service in passthrough mode
+is disallowed.)</p>
+
+<h2 id=grammar>HIDL grammar</h2>
+<p>By design, the HIDL language is similar to C (but does not use the C
+preprocessor). All punctuation not described below (aside from the obvious use
+of <code>=</code> and <code>|</code>) is part of the grammar.</p>
+
+<p class=note><strong>Note:</strong> For details on HIDL code style, see the
+<a href="code-style.html">Code Style Guide</a>.</p>
+
+<ul>
+<li><code>/** */</code> indicates a documentation comment.</li>
+<li><code>/* */</code> indicates a multiline comment.</li>
+<li><code>//</code> indicates a comment to end of line. Aside from
+<code>//</code>, newlines are the same as any other whitespace. </li>
+<li>In the example grammar below, text from <code>//</code> to the end of the
+line is not part of the grammar but is instead a comment on the grammar.</li>
+<li><code>[empty]</code> means that the term may be empty. </li>
+<li><code>?</code> following a literal or term means it is optional.</li>
+<li><code>...</code> indicates sequence containing zero or more items with
+separating punctuation as indicated. There are no variadic arguments in HIDL.</li>
+<li>Commas separate sequence elements.</li>
+<li>Semicolons terminate each element, including the last element.</li>
+<li>UPPERCASE is a nonterminal.</li>
+<li><code><em>italics</code></em> is a token family such as
+<code><em>integer</code></em> or <code><em>identifier</code></em> (standard C
+parsing rules).</li>
+<li><code><em>constexpr</em> </code>is a C style constant expression (such as
+<code>1 + 1</code> and <code>1L &lt;&lt; 3</code>).</li>
+<li><code><em>import_name</code></em> is a package or interface name, qualified
+as described in <a href="/devices/architecture/hidl/versioning.html"> HIDL
+Versioning</a>.</li>
+<li>Lowercase <code>words</code> are literal tokens.</li>
+</ul>
+<p>Example:</p>
+<pre class="prettyprint">
+ROOT =
+ PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... } // not for types.hal
+ PREAMBLE = interface identifier EXTENDS
+ | PACKAGE IMPORTS ITEM ITEM... // only for types.hal; no method definitions
+
+ITEM =
+ ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
+ | struct identifier { SFIELD; SFIELD; ...}; // Note - no forward declarations
+ | union identifier { UFIELD; UFIELD; ...};
+ | enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
+ | typedef TYPE identifier;
+
+VERSION = integer.integer;
+
+PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;
+
+PREAMBLE = interface identifier EXTENDS
+
+EXTENDS = &lt;empty&gt; | extends import_name // must be interface, not package
+
+GENERATES = generates (FIELD, FIELD ...)
+
+// allows the Binder interface to be used as a type
+// (similar to typedef'ing the final identifier)
+IMPORTS =
+ [empty]
+ | IMPORTS import import_name;
+
+TYPE =
+ uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
+ float | double | bool | string
+| identifier // must have been previously typedef'd
+ // or defined with struct, union, enum, or import
+| memory
+| pointer
+| vec&lt;TYPE&gt;
+| bitfield&lt;TYPE&gt; // TYPE is user-defined enum
+| fmq_sync&lt;TYPE&gt;
+| fmq_unsync&lt;TYPE&gt;
+| TYPE[SIZE]
+
+FIELD =
+ TYPE identifier
+
+UFIELD =
+ TYPE identifier
+ | struct identifier { FIELD; FIELD; ...} identifier;
+ | union identifier { FIELD; FIELD; ...} identifier;
+
+SFIELD =
+ TYPE identifier
+ | struct identifier { FIELD; FIELD; ...};
+ | union identifier { FIELD; FIELD; ...};
+ | struct identifier { FIELD; FIELD; ...} identifier;
+ | union identifier { FIELD; FIELD; ...} identifier;
+
+SIZE = // Must be greater than zero
+ constexpr
+
+ANNOTATIONS =
+ [empty]
+ | ANNOTATIONS ANNOTATION
+
+ANNOTATION =
+ | @identifier
+ | @identifier(VALUE)
+ | @identifier(ANNO_ENTRY, ANNO_ENTRY ...)
+
+ANNO_ENTRY =
+ identifier=VALUE
+
+VALUE =
+ "any text including \" and other escapes"
+ | constexpr
+ | {VALUE, VALUE ...} // only in annotations
+
+ENUM_ENTRY =
+ identifier
+ | identifier = constexpr
+</pre>
+
+<h2 id=terms>Terminology</h2>
+<p>This section uses the following HIDL-related terms:</p>
+
+<table>
+<tbody>
+
+<tr>
+<th>binderized</th>
+<td>Indicates HIDL is being used for remote procedure calls between processes,
+implemented over a Binder-like mechanism. See also <em>passthrough</em>.</td>
+</tr>
+
+<tr>
+<th>callback, asynchronous</th>
+<td>Interface served by a HAL user, passed to the HAL (via a HIDL method), and
+called by the HAL to return data at any time.</td>
+</tr>
+
+<tr>
+<th>callback, synchronous</th>
+<td>Returns data from a server's HIDL method implementation to the client.
+Unused for methods that return void or a single primitive value.</td>
+</tr>
+
+<tr>
+<th>client</th>
+<td>Process that calls methods of a particular interface. A HAL or framework
+process may be a client of one interface and a server of another. See also
+<em>passthrough</em>.</td>
+</tr>
+
+<tr>
+<th>extends</th>
+<td>Indicates an interface that adds methods and/or types to another interface.
+An interface can extend only one other interface. Can be used for a minor
+version increment in the same package name or for a new package (e.g. a vendor
+extension) to build on an older package.</td>
+</tr>
+
+<tr>
+<th>generates</th>
+<td>Indicates an interface method that returns values to the client. To return
+one non-primitive value, or more than one value, a synchronous callback function
+is generated.</td>
+</tr>
+
+<tr>
+<th>interface</th>
+<td>Collection of methods and types. Translated into a class in C++ or Java. All
+methods in an interface are called in the same direction: a client process
+invokes methods implemented by a server process.</td>
+</tr>
+
+<tr>
+<th>oneway</th>
+<td>When applied to a HIDL method, indicates the method returns no values and
+does not block.</td>
+</tr>
+
+<tr>
+<th>package</th>
+<td>Collection of interfaces and data types sharing a version.</td>
+</tr>
+
+<tr>
+<th>passthrough</th>
+<td>Mode of HIDL in which the server is a shared library, <code>dlopen</code>ed
+by the client. In passthrough mode, client and server are the same process but
+separate codebases. Used only to bring legacy codebases into the HIDL model.
+See also <em>Binderized</em>.</td>
+</tr>
+
+<tr>
+<th>server</th>
+<td>Process that implements methods of an interface. See also
+<em>passthrough</em>.</td>
+</tr>
+
+<tr>
+<th>transport</th>
+<td>HIDL infrastructure that moves data between the server and client.</td>
+</tr>
+
+<tr>
+<th>version</th>
+<td>Version of a package. Consists of two integers, major and minor. Minor
+version increments may add (but not change) types and methods.</td>
+</tr>
+
+</tbody>
+</table>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/interfaces.html b/en/devices/architecture/hidl/interfaces.html
new file mode 100644
index 00000000..a044abde
--- /dev/null
+++ b/en/devices/architecture/hidl/interfaces.html
@@ -0,0 +1,228 @@
+<html devsite>
+ <head>
+ <title>Interfaces &amp; Packages</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>HIDL is built around interfaces, an abstract type used in object-oriented
+languages to define behaviors. Each interface is part of a package.</p>
+
+<h2 id=packages>Packages</h2>
+
+<p>Package names can have sublevels such as <code>package.subpackage</code>. The
+root directory for published HIDL packages is <code>hardware/interfaces</code>
+or <code>vendor/vendorName</code> (e.g. <code>vendor/google</code> for Pixel
+devices). The package name forms one or more subdirectories under the root
+directory; all files defining a package are in the same directory. For example,
+<code>package android.hardware.example.extension.light@2.0</code> could be found
+under <code>hardware/interfaces/example/extension/light/2.0</code>.</p>
+
+<p>The following table lists package prefixes and locations:</p>
+<table>
+<tbody>
+
+<tr>
+<th>Package Prefix</th>
+<th>Location</th>
+</tr>
+
+<tr>
+<td><code>android.hardware.*</code></td>
+<td><code>hardware/interfaces/*</code></td>
+</tr>
+
+<tr>
+<td><code>android.frameworks.*</code></td>
+<td><code>frameworks/hardware/interfaces/*</code></td>
+</tr>
+
+<tr>
+<td><code>android.system.*</code></td>
+<td><code>system/hardware/interfaces/*</code></td>
+</tr>
+
+<tr>
+<td><code>android.hidl.*</code></td>
+<td><code>system/libhidl/transport/*</code></td>
+</tr>
+
+</tbody>
+</table>
+
+<p>The package directory contains files with extension <code>.hal</code>. Every
+file must contain a <code>package</code> statement naming the package and
+version the file is part of. The file <code>types.hal</code>, if present, does
+not define an interface but instead defines data types accessible to every
+interface in the package.</p>
+
+<h2 id=interface-def>Interface definition</h2>
+<p>Aside from <code>types.hal</code>, every other <code>.hal</code> file defines
+an interface. For example, an interface is typically defined as follows:</p>
+
+<pre class="prettyprint">
+interface IBar extends IFoo { // IFoo is another interface
+ // embedded types
+ struct MyStruct {/*...*/};
+
+ // interface methods
+ create(int32_t id) generates (MyStruct s);
+ close();
+};
+</pre>
+
+<p>An interface without an explicit <code>extends</code> declaration implicitly
+extends from <code>android.hidl.base@1.0::IBase</code> (similar to
+<code>java.lang.Object</code> in Java.) The IBase interface, implicitly
+imported, declares several reserved methods that should not and cannot be
+redeclared in user-defined interfaces or used otherwise. These methods
+include:</p>
+
+<ul>
+<li><code>ping</code></li>
+<li><code>interfaceChain</code></li>
+<li><code>interfaceDescriptor</code></li>
+<li><code>notifySyspropsChanged</code></li>
+<li><code>linkToDeath</code></li>
+<li><code>unlinkToDeath</code></li
+<li><code>setHALInstrumentation</code></li>
+<li><code>getDebugInfo</code></li>
+<li><code>debug</code></li>
+<li><code>getHashChain</code></li>
+</ul>
+
+<h2 id=import>Importing</h2>
+<p>The <code>import</code> statement is HIDL mechanism to access package
+interfaces and types in another package. An <code>import</code> statement
+concerns itself with two entities:</p>
+
+<ul>
+<li>The import<em>ing</em> entity, which can be either a package or an
+interface; and</li>
+<li>The import<em>ed</em> entity, which too can be either a package or an
+interface.</li>
+</ul>
+
+<p>The importing entity is determined by the location of the
+<code>import</code> statement. When the statement is inside a package's
+<code>types.hal</code>, what is being imported is visible by the entire package;
+this is a <em>package-level</em> import. When the statement is inside an
+interface file, the importing entity is the interface itself; this is an
+<em>interface-level</em> import.</p>
+
+<p>The imported entity is determined by the value after the <code>import</code>
+keyword. The value need not be a fully-qualified name; if a component is
+omitted, it is automatically filled with information from the current package.
+For fully-qualified values, the following import cases are supported:</p>
+
+<ul>
+<li><strong>Whole-package imports</strong>. If the value is a package name and a
+version (syntax described below), then the entire package is imported into the
+importing entity.</li>
+<li><strong>Partial imports</strong>.
+<ul>
+<li>If the value is an interface, the package's <code>types.hal</code> and that
+interface are imported into the importing entity.</li>
+<li>If the value is an UDT defined in <code>types.hal</code>, then only that UDT
+is imported into the importing entity (other types in <code>types.hal</code> are
+not imported).</li>
+</ul>
+<li><strong>Types-only imports</strong>. If the value uses the syntax of a
+partial import described above, but with the keyword <code>types</code> instead
+of an Interface name, only the UDTs in <code>types.hal</code> of the designated
+package are imported.</li>
+</ul>
+
+<p>The importing entity gets access to a combination of:</p>
+<ul>
+<li>The imported package's common UDTs defined in <code>types.hal</code>;</li>
+<li>The imported package's interfaces (for a whole-package import) or specified
+interface (for a partial import) for the purposes of invoking them, passing
+handles to them and/or inheriting from them.</li>
+</ul>
+
+<p>The import statement uses the fully-qualified-type-name syntax to provide the
+name and version of the package or interface being imported:</p>
+
+<pre class="prettyprint">
+import android.hardware.nfc@1.0; // import a whole package
+import android.hardware.example@1.0::IQuux; // import an interface and types.hal
+import android.hardware.example@1.0::types; // import just types.hal
+</pre>
+
+<h2 id=inheritance>Interface inheritance</h2>
+
+<p>An interface can be an extension of a previously-defined interface.
+Extensions can be one of the following three types:</p>
+<ul>
+<li>Interface can add functionality to another one, incorporating its API
+unchanged.</li>
+<li>Package can add functionality to another one, incorporating its API
+unchanged.</li>
+<li>Interface can import types from a package or from a specific interface.</li>
+</ul>
+
+<p>An interface can extend only one other interface (no multiple inheritance).
+Each interface in a package with a non-zero minor version number must extend an
+interface in the previous version of the package. For example, if an interface
+<code>IBar</code> in version 4.0 of package <code>derivative</code> is based on
+(extends) an interface <code>IFoo</code> in version 1.2 of package
+<code>original</code>, and a version 1.3 of package <code>original</code> is
+created, <code>IBar</code> version 4.1 cannot extend version 1.3 of
+<code>IFoo</code>. Instead, <code>IBar</code> version 4.1 must extend
+<code>IBar</code> version 4.0, which is tied to <code>IFoo</code> version 1.2.
+<code>IBar</code> version 5.0 could extend <code>IFoo</code> version 1.3, if
+desired.</p>
+
+<p>Interface extensions do not imply library dependence or cross-HAL inclusion
+in the generated code&mdash;they simply import the data structure and method
+definitions at the HIDL level. Every method in a HAL must be implemented in that
+HAL.</p>
+
+<h2 id=vendor-ext>Vendor extensions</h2>
+<p>In some cases, vendor extensions will be implemented as a subclass of the
+base object that represents the core interface they extend. The same object will
+be registered under the base HAL name and version, and under the extension's
+(vendor) HAL name and version.</p>
+
+
+<h2 id=version>Versioning</h2>
+<p>Packages are versioned, and interfaces have the version of their package.
+Versions are expressed in two integers, <em>major</em>.<em>minor</em>.</p>
+<ul>
+<li><strong>Major</strong> versions are not backwards compatible. Incrementing
+the major version number resets the minor version to 0.</li>
+<li><strong>Minor</strong> versions are backwards compatible. Incrementing the
+minor number indicates the newer version is fully backward compatible with the
+previous version. New data structures and methods can be added, but no existing
+data structures or method signatures may be changed.</li>
+</ul>
+
+<p>For broader compatibility with frameworks, multiple major versions of a HAL
+can be present on a device simultaneously. While multiple minor versions can
+also be present on a device, as minor versions are backwards compatible no
+reason exists to support more than the latest minor version for each major
+version.</p>
+
+<p>For more details on versioning and vendor extensions, see
+<a href="/devices/architecture/hidl/versioning">HIDL Versioning</a>.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/network-stack.html b/en/devices/architecture/hidl/network-stack.html
new file mode 100644
index 00000000..88377324
--- /dev/null
+++ b/en/devices/architecture/hidl/network-stack.html
@@ -0,0 +1,176 @@
+<html devsite>
+ <head>
+ <title>Network Stack Configuration Tools</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>The Android operating system contains standard Linux networking utilities
+such as <code>ifconfig</code>, <code>ip</code>, and <code>ip6tables</code>.
+These utilities reside on the system image and enable configuration of the
+entire Linux networking stack. On devices running Android 7.x and earlier,
+vendor code is allowed to call these binaries directly, which presents the
+following problems:</p>
+
+<ul>
+<li>Because network utilities are updated in the system image, they do not
+provide a stable implementation.</li>
+<li>The scope of the networking utilities is so broad it is difficult to evolve
+the system image while guaranteeing predictable behaviour.</li>
+</ul>
+
+<p>On devices running Android 8.0, the vendor partition can remain the same
+while the system partition receives an update. To achieve this, Android 8.0
+provides the ability to define a stable, versioned interface while also using
+SELinux restrictions to keep the interdependency of vendor and system image to a
+known good set.</p>
+
+<p>Vendors can use the platform-provided network configuration utilities to
+configure the Linux networking stack, but these utilities do not yet include a
+HIDL interface wrapper. To define such an interface, Android 8.0 includes the
+<code>netutils-wrapper-1.0</code> tool.
+</p>
+
+<h2 id="netutils-wrapper">Netutils wrapper</h2>
+<p>The <code>netutils</code> wrapper utility provides a subset of the Linux
+network stack configuration that is not affected by system partition updates.
+Android 8.0 contains version 1.0 of the wrappers, which allows you to pass the
+same arguments as the wrapped utilities, installed in the system partition at
+<code>/system/bin</code> as follows:</p>
+
+<pre class="prettyprint">
+u:object_r:system_file:s0 /system/bin/ip-wrapper-1.0 -> netutils-wrapper-1.0
+u:object_r:system_file:s0 /system/bin/ip6tables-wrapper-1.0 -> netutils-wrapper-1.0
+u:object_r:system_file:s0 /system/bin/iptables-wrapper-1.0 -> netutils-wrapper-1.0
+u:object_r:system_file:s0 /system/bin/ndc-wrapper-1.0 -> netutils-wrapper-1.0
+u:object_r:netutils_wrapper_exec:s0 /system/bin/netutils-wrapper-1.0
+u:object_r:system_file:s0 /system/bin/tc-wrapper-1.0 -> netutils-wrapper-1.0
+</pre>
+
+<p>Symlinks show the networking utilities wrapped by the <code>netutils</code>
+wrapper, which include:</p>
+<ul>
+<li><code>ip</code></li>
+<li><code>iptables</code></li>
+<li><code>ip6tables</code></li>
+<li><code>ndc</code></li>
+<li><code>tc</code></li>
+</ul>
+
+<p>To use these utilities in Android 8.0 and later, vendor implementations must
+adhere to the following rules:</p>
+<ul>
+<li>Vendor processes must not execute
+<code>/system/bin/netutils-wrapper-1.0</code> directly; attempts to do so will
+result in error.</li>
+<li>All utilities wrapped by <code>netutils-wrapper-1.0</code> must be launched
+using their symlinks. For example, change the vendor code that did this before
+(<code>/system/bin/ip &lt;FOO&gt; &lt;BAR&gt;</code>) to
+<code>/system/bin/ip-wrapper-1.0 &lt;FOO&gt; &lt;BAR&gt;</code>.</li>
+<li>Executing the wrappers without domain transition is prohibited in platform
+SELinux policy. This rule must not be changed and is tested against in the
+<a href="/compatibility/cts.html">Android Compatibility Test Suite (CTS)</a>.
+</li>
+<li>Executing the utilities directly (e.g.,
+<code>/system/bin/ip &lt;FOO&gt; &lt;BAR&gt;</code>) from the vendor processes
+is also prohibited in the platform SELinux policies. This rule must not be
+changed and is tested against in CTS.</li>
+<li>Any vendor domain (process) that needs to launch a wrapper must add the
+following domain transition rule in the SELinux policy:
+<code>domain_auto_trans(<var>VENDOR-DOMAIN-NAME</var>, netutils_wrapper_exec,
+netutils_wrapper)</code>.</li>
+</ul>
+
+<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>
+
+<h2 id="netutils-wrapper-filters">Netutils wrapper filters</h2>
+<p>Wrapped utilities can be used to configure almost any aspect of the Linux
+networking stack. However, to ensure it is possible to maintain a stable
+interface and allow updates to the system partition, only certain combinations
+of command line arguments are allowed; other commands will be rejected.</p>
+
+<h3 id="vendor-interfaces-and-chains">Vendor interfaces and chains</h3>
+<p>The wrapper has a concept of <em>vendor interfaces</em>. These are interfaces
+typically managed by vendor code, such as cellular data interfaces. Typically,
+other types of interfaces (such as Wi-Fi) are managed by the HALs and the
+framework. The wrapper recognizes vendor interfaces by name (using a regular
+expression) and allows vendor code to perform many operations on them.
+Currently, vendor interfaces are:</p>
+<ul>
+<li>Interfaces whose names end in "oem" followed by a number, such as
+<code>oem0</code> or <code>r_oem1234</code>.</li>
+<li>Interfaces used by current SOC and OEM implementations, such as
+<code>rmnet_data[0-9]</code>.</li>
+</ul>
+
+<p>Names of interfaces that are typically managed by the framework (such as
+<code>wlan0</code>) are never vendor interfaces.</p>
+
+<p>The wrapper has a similar concept of <em>vendor chains</em>. These are used
+in <code>iptables</code> commands and are also recognized by name. Currently,
+vendor chains:</p>
+<ul>
+<li>Start with <code>oem_</code>.</li>
+<li>Are used by current SOC and OEM implementations, e.g., chains starting in
+<code>nm_</code> or <code>qcom_</code>.</li>
+</ul>
+
+<h3 id="allowed-commands">Allowed commands</h3>
+<p>Currently allowed commands are listed below. Restrictions are implemented via
+a set of regular expressions on the executed command lines. For details, refer
+to <code>system/netd/netutils_wrappers/NetUtilsWrapper-1.0.cpp</code>.</p>
+
+<h4 id="ip">ip</h4>
+<p>The <code>ip</code> command is used to configure IP addresses, routing, IPsec
+encryption, and a number of other network parameters. The wrapper allows the
+following commands:</p>
+<ul>
+<li>Add and remove IP addresses from vendor-managed interfaces.</li>
+<li>Configure IPsec encryption.</li>
+</ul>
+
+<h4 id="iptables-ip6tables">iptables/ip6tables</h4>
+<p>The <code>iptables</code> and <code>ip6tables</code> commands are used to
+configure firewalling, packet mangling, NAT, and other per-packet processing.
+The wrapper allows the following commands:</p>
+<ul>
+<li>Add and delete vendor chains.</li>
+<li>Add and delete rules in any chain that refers to packets going into
+(<code>-i</code>) or out of (<code>-o</code>) a vendor interface.</li>
+<li>Jump to a vendor chain from any point in any other chain.</li>
+</ul>
+
+<h4 id="ndc">ndc</h4>
+<p><code>ndc</code> is used to communicate to the <code>netd</code> daemon that
+performs most network configuration on Android. The wrapper allows the following
+commands:</p>
+<ul>
+<li>Create and destroy OEM networks (<code>oemXX</code>).</li>
+<li>Add vendor-managed interfaces to OEM networks.</li>
+<li>Add routes to OEM networks.</li>
+<li>Enable or disable IP forwarding globally and on vendor interfaces.</li>
+</ul>
+
+<h4 id="tc">tc</h4>
+<p>The <code>tc</code> command is used to configure traffic queueing and shaping
+on vendor interfaces.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/services.html b/en/devices/architecture/hidl/services.html
new file mode 100644
index 00000000..647555b7
--- /dev/null
+++ b/en/devices/architecture/hidl/services.html
@@ -0,0 +1,219 @@
+<html devsite>
+ <head>
+ <title>Services &amp; Data Transfer</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>This section describes how to register and discover services and how to send
+data to a service by calling methods defined in interfaces in <code>.hal</code>
+files.</p>
+
+<h2 id=register>Registering services</h2>
+<p>HIDL interface servers (objects implementing the interface) can be registered
+as named services. The registered name need not be related to the interface or
+package name. If no name is specified, the name "default" is used; this should
+be used for HALs that do not need to register two implementations of the same
+interface. For example, the C++ call for service registration defined in each
+interface is:</p>
+
+<pre class="prettyprint">
+registerAsService();
+registerAsService("another_foo_service"); // if needed
+</pre>
+
+<p>The version of a HIDL interface is included in the interface itself. It is
+automatically associated with service registration and can be retrieved via a
+method call (<code>android::hardware::IInterface::getInterfaceVersion()</code>)
+on every HIDL interface. Server objects need not be registered and can be passed
+via HIDL method parameters to another process that will make HIDL method calls
+into the server.</p>
+
+<h2 id=discover>Discovering services</h2>
+<p>Requests by client code are made for a given interface by name and by
+version, calling <code>getService</code> on the desired HAL class:</p>
+
+<pre class="prettyprint">
+sp&lt;V1_1::IFooService&gt; service = V1_1::IFooService::getService();
+sp&lt;V1_1::IFooService&gt; alternateService = 1_1::IFooService::getService("another_foo_service");
+</pre>
+
+<p>Each version of a HIDL interface is treated as a separate interface. Thus,
+<code>IFooService</code> version 1.1 and <code>IFooService</code> version 2.2
+can both be registered as "foo_service" and
+<code>getService("foo_service")</code> on either interface gets the registered
+service for that interface. This is why, in most cases, no name parameter needs
+to be supplied for registration or discovery (meaning name "default").</p>
+
+<p>The Vendor Interface Object also plays a part in the transport method of the
+returned interface. For an interface <code>IFoo</code> in package
+<code>android.hardware.foo@1.0</code>, the returned interface by
+<code>IFoo::getService</code> always use the transport method declared for
+<code>android.hardware.foo</code> in the device manifest if the entry exists;
+and if the transport method is not available, nullptr is returned.</p>
+
+<h2 id=death>Service death notifications</h2>
+<p>Clients who want to be notified when a service dies can receive death
+notifications delivered by the framework. To receive notifications, the client
+must:</p>
+<ol>
+<li>Subclass the HIDL class/interface <code>hidl_death_recipient</code> (in C++
+code, not in HIDL).</li>
+<li>Override its <code>serviceDied()</code> method.</li>
+<li>Instantiate an object of the <code>hidl_death_recipient</code> subclass.
+</li>
+<li>Call the <code>linkToDeath()</code> method on the service to monitor,
+passing in the <code>IDeathRecipient</code>'s interface object.</li>
+</ol>
+
+<p>A pseudocode example (C++ and Java are similar):</p>
+
+<pre class="prettyprint">
+class IMyDeathReceiver : hidl_death_recipient {
+ virtual void serviceDied(uint64_t cookie,
+ wp&lt;IBase&gt;&amp; service) override {
+ log("RIP service %d!", cookie); // Cookie should be 42
+ }
+};
+....
+IMyDeathReceiver deathReceiver = new IMyDeathReceiver();
+m_importantService-&gt;linkToDeath(deathReceiver, 42);
+</pre>
+
+<p>The same death recipient may be registered on multiple different services.
+</p>
+
+<h2 id=data-transwer>Data transfer</h2>
+<p>Data may be sent to a service by calling methods defined in interfaces in
+<code>.hal</code> files. There are two kinds of methods:</p>
+
+<ul>
+<li><strong>Blocking</strong> methods wait until the server has produced a
+result.</li>
+<li><strong>Oneway</strong> methods send data in only one direction and do not
+block. If the amount of data in-flight in RPC calls exceeds implementation
+limits, the calls may either block or return an error indication (behavior is
+not yet determined).</li>
+</ul>
+
+<p>A method that does not return a value but is not declared as
+<code>oneway</code> is still blocking.</p>
+
+<p>All methods declared in a HIDL interface are called in a single direction,
+either from the HAL or into the HAL. The interface does not specify which
+direction it will be called in. Architectures that need calls to originate from
+the HAL should provide two (or more) interfaces in the HAL package and serve the
+appropriate interface from each process. The words <em>client</em> and
+<em>server</em> are used with respect to the calling direction of the interface
+(i.e. the HAL can be a server of one interface and a client of another
+interface).</p>
+
+<h3 id=callbacks>Callbacks</h3>
+<p>The word <em>callback</em> refers to two different concepts, distinguished by
+<em>synchronous callback</em> and <em>asynchronous callback</em>.</p>
+
+<p><em>Synchronous callbacks</em> are used in some HIDL methods that return
+data. A HIDL method that returns more than one value (or returns one value of
+non-primitive type) returns its results via a callback function. If only one
+value is returned and it is a primitive type, a callback is not used and the
+value is returned from the method. The server implements the HIDL methods and
+the client implements the callbacks.</p>
+
+<p><em>Asynchronous callbacks</em> allow the server of a HIDL interface to
+originate calls. This is done by passing an instance of a second interface
+through the first interface. The client of the first interface must act as the
+server of the second. The server of the first interface can call methods on the
+second interface object. For example, a HAL implementation may send information
+asynchronously back to the process that is using it by calling methods on an
+interface object created and served by that process. Methods in interfaces used
+for asynchronous callback may be blocking (and may return values to the caller)
+or <code>oneway</code>. For an example, see "Asynchronous callbacks" in
+<a href="/devices/architecture/hidl-cpp/interfaces.html">HIDL C++</a>.</p>
+
+<p>To simplify memory ownership, method calls and callbacks take only
+<code>in</code> parameters and do not support <code>out</code> or
+<code>inout</code> parameters.</p>
+
+<h3 id=limits>Per-transaction limits</h3>
+<p>Per-transaction limits may be imposed on the amount of data sent in HIDL
+methods and callbacks. The limits are yet to be determined but may be as small
+as 4K. Calls exceeding these limits return failure immediately. Another
+limitation is the resources available to the HIDL infrastructure to handle
+multiple simultaneous transactions. Multiple transactions can be in-flight
+simultaneously due to multiple threads or processes sending calls to a process
+or multiple <code>oneway</code> calls that are not handled quickly by the
+receiving process.</p>
+
+<p>In a well-designed interface, exceeding these resource limitations should not
+happen; if it does, the call which exceeded them may either block until
+resources become available or signal a transport error. Each occurrence of
+exceeding per-transaction limits or overflowing HIDL implementation resources by
+aggregate in-flight transactions is logged to facilitate debugging.</p>
+
+<h3 id=method-implement>Method implementations</h3>
+<p>HIDL generates header files declaring the necessary types, methods, and
+callbacks in the target language (C++ or Java). The prototype of HIDL-defined
+methods and callbacks is the same for both client and server code. The HIDL
+system provides <strong>proxy</strong> implementations of the methods on the
+caller side that organize the data for IPC transport, and <strong>stub</strong>
+code on the callee side that passes the data into developer implementations of
+the methods.</p>
+
+<p>The caller of a function (HIDL method or callback) has ownership of the data
+structures passed into the function, and retains ownership after the call; in
+all cases the callee does not need to free or release the storage.</p>
+
+<ul>
+<li>In C++, the data may be read-only (attempts to write to it may cause a
+segmentation fault) and are valid for the duration of the call. The client can
+deep-copy the data to propagate it beyond the call.</li>
+<li>In Java, the code receives a local copy of the data (a normal Java object),
+which it may keep and modify or allow to be garbage-collected.</li>
+</ul>
+
+<h3 id=non-rpc>Non-RPC data transfer</h3>
+<p>HIDL has two ways to transfer data without using an RPC call: shared
+memory and a Fast Message Queue (FMQ), both supported only in C++.</p>
+
+<ul>
+<li><strong>Shared memory</strong>. The built-in HIDL type <code>memory</code>
+is used to pass an object representing shared memory that has been allocated.
+Can be used in a receiving process to map the shared memory.</li>
+<li><strong>Fast Message Queue (FMQ)</strong>. HIDL provides a templated message
+queue type that implements no-wait message-passing. It does not use the kernel
+or scheduler in passthrough or binderized mode (inter-device communication will
+not have these properties). Typically, the HAL sets up its end of the queue,
+creating an object that can be passed through RPC via a parameter of built-in
+HIDL type <code>MQDescriptorSync</code> or <code>MQDescriptorUnsync</code>. This
+object can be used by the receiving process to set up the other end of the queue.
+<ul>
+<li><em>Sync</em> queues are not allowed to overflow, and can only have one
+reader.</li>
+<li><em>Unsync</em> queues are allowed to overflow, and can have many readers,
+each of which must read data in time or lose it.</li>
+</ul>
+Neither type is allowed to underflow (read from an empty queue will fail), and
+each type can only have one writer.</li></ul>
+
+<p>For more details on FMQ, see
+<a href="/devices/architecture/hidl/fmq.html">Fast Message Queue (FMQ)</a>.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/threading.html b/en/devices/architecture/hidl/threading.html
new file mode 100644
index 00000000..059b61d4
--- /dev/null
+++ b/en/devices/architecture/hidl/threading.html
@@ -0,0 +1,156 @@
+<html devsite>
+ <head>
+ <title>Threading Models</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>Methods marked as <code>oneway</code> do not block. For methods not marked as
+<code>oneway</code>, a client's method call will block until the server has
+completed execution or called a synchronous callback (whichever comes first).
+Server method implementations may call at most one synchronous callback; extra
+callback calls are discarded and logged as errors. If a method is supposed to
+return values via callback and does not call its callback, this is logged as an
+error and reported as a transport error to the client.</p>
+
+<h2 id=passthrough>Threads in passthrough mode</h2>
+<p>In passthrough mode, most calls are synchronous. However, to preserve the
+intended behavior that <code>oneway</code> calls do not block the client, a
+thread is created for each process. For details, see the
+<a href="/devices/architecture/hidl/index.html#passthrough">HIDL overview</a>.
+</p>
+
+<h2 id=binderized>Threads in binderized HALs</h2>
+<p>To serve incoming RPC calls (including asynchronous callbacks from HALs to
+HAL users) and death notifications, a threadpool is associated with each process
+that uses HIDL. If a single process implements multiple HIDL interfaces and/or
+death notification handlers, its threadpool is shared between all of them. When
+a process receives an incoming method call from a client, it picks a free thread
+from the threadpool and executes the call on that thread. If no free thread is
+available, it blocks until one is available.</p>
+
+<p>If the server has only one thread, then calls into the server are completed
+in order. A server with more than one thread may complete calls out of order
+even if the client has only one thread. As <code>oneway</code> calls do not
+block the client, multiple <code>oneway</code> calls may be processed
+simultaneously or out of order by a server with more than one thread, and
+<code>oneway</code> calls may be processed concurrently with a subsequent
+blocking call.</p>
+
+<h2 id=model>Server threading model</h2>
+<p>Except for passthrough mode, server implementations of HIDL interfaces live
+in a different process than the client and need one or more threads waiting for
+incoming method calls. These threads are the server's threadpool; the server may
+decide how many threads it wants running in its threadpool, and can use a
+threadpool size of one to serialize all calls on its interfaces. If the server
+has more than one thread in the threadpool, it can receive concurrent incoming
+calls on any of its interfaces (in C++, this means that shared data must be
+carefully locked).</p>
+
+<p>Oneway calls into the same interface are serialized. If a multi-threaded
+client calls <code>method1</code> and <code>method2</code> on interface
+<code>IFoo</code>, and <code>method3</code> on interface <code>IBar</code>,
+<code>method1</code> and <code>method2</code> will always be serialized, but
+<code>method3</code> may run in parallel with <code>method1</code> and
+<code>method2</code>.</p>
+
+<p>A single client thread of execution can cause concurrent execution on a
+server with multiple threads in two ways:</p>
+
+<ul>
+<li><code>oneway</code> calls do not block. If a <code>oneway</code> call is
+executed and then a non-<code>oneway</code> is called, the server may execute
+the <code>oneway</code> call and the non-<code>oneway</code> call
+simultaneously.</li>
+<li>Server methods that pass data back with synchronous callbacks can unblock
+the client as soon as the callback is called from the server.</li>
+</ul>
+
+<p>For the second way, any code in the server function that executes after the
+callback is called may execute concurrently, with the server handling subsequent
+calls from the client. This includes code in the server function and automatic
+destructors that execute at the end of the function. If the server has more than
+one thread in its threadpool, concurrency issues arise even if calls are coming
+in from only one single client thread. (If any HAL served by a process needs
+multiple threads, all HALs will have multiple threads because the threadpool is
+shared per-process.)</p>
+
+<p>As soon as the server calls the provided callback, the transport can call the
+implemented callback on the client and unblock the client. The client proceeds
+in parallel with whatever the server implementation does after it calls the
+callback (which may include running destructors). Code in the server function
+after the callback is no longer blocking the client (as long as the server
+threadpool has enough threads to handle incoming calls), but may be executed
+concurrently with future calls from the client (unless the server threadpool has
+only one thread).</p>
+
+<p>In addition to synchronous callbacks, <code>oneway</code> calls from a
+single-threadedclient may be handled concurrently by a server with multiple
+threads in its threadpool, but only if those <code>oneway</code> calls are
+executed on different interfaces. <code>oneway</code> calls on the same
+interface are always serialized.</p>
+
+<p class=note><strong>Note:</strong> We strongly encourage server functions to
+return as soon as they have called the callback function.</p>
+
+<p>For example (in C++):</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);
+ // At this point, the client's callback will be called,
+ // and the client will resume execution.
+ ...
+ return Void(); // is basically a no-op
+};
+</pre>
+
+<h2 id=client>Client threading model</h2>
+<p>The threading model on the client differs between non-blocking calls
+(functions that are marked with the <code>oneway</code> keyword) and blocking
+calls (functions that do not have the <code>oneway</code> keyword specified).</p>
+
+<h3 id=block>Blocking calls</h3>
+<p>For blocking calls, the client blocks until one of the following happens:</p>
+
+<ul>
+<li>Transport error occurs; the <code>Return</code> object contains an error
+state that can be retrieved with <code>Return::isOk()</code>.</li>
+<li>Server implementation calls the callback (if there was one).</li>
+<li>Server implementation returns a value (if there was no callback parameter).
+</li>
+</ul>
+
+<p>In case of success, the callback function the client passes as an argument is
+always called by the server before the function itself returns. The callback is
+executed on the same thread that the function call is made on, so implementers
+must be careful with holding locks during function calls (and avoid them
+altogether when possible). A function without a <code>generates</code> statement
+or a <code>oneway</code> keyword is still blocking; the client blocks until the
+server returns a <code>Return&lt;void&gt;</code> object.</p>
+
+<h3 id=oneway>Oneway calls</h3>
+<p>When a function is marked <code>oneway</code>, the client returns immediately
+and does not wait for the server to complete its function call invocation.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/types.html b/en/devices/architecture/hidl/types.html
new file mode 100644
index 00000000..1f36262d
--- /dev/null
+++ b/en/devices/architecture/hidl/types.html
@@ -0,0 +1,408 @@
+<html devsite>
+ <head>
+ <title>Data Types</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>This section describes HIDL data types. For implementation details, see
+<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (for C++
+implementations) or <a href="/devices/architecture/hidl-java/index.html">HIDL
+Java</a> (for Java implementations).</p>
+
+<p>Similarities to C++ include:</p>
+<ul>
+<li><code>structs</code> use C++ syntax; <code>unions</code> support C++ syntax
+by default. Both must be named; anonymous structs and unions are not supported.
+</li>
+<li>Typedefs are allowed in HIDL (as they are in C++).</li>
+<li>C++-style comments are allowed and are copied to the generated header file.
+</li>
+</ul>
+
+<p>Similarities to Java include:</p>
+<ul>
+<li>For each file, HIDL defines a Java-style namespace that must begin with
+<code>android.hardware.</code>. The generated C++ namespace is
+<code>::android::hardware::&#8230;</code>.</li>
+<li>All definitions of the file are contained within a Java-style
+<code>interface</code> wrapper.</li>
+<li>HIDL array declarations follow the Java style, not the C++ style. Example:
+<pre class="prettyprint">
+struct Point {
+ int32_t x;
+ int32_t y;
+};
+Point[3] triangle; // sized array
+</pre>
+</li>
+<li>Comments are similiar to the javadoc format.</li>
+</ul>
+
+<h2 id=represent>Data representation</h2>
+<p>A <code>struct</code> or <code>union</code> composed of
+<a href="http://en.cppreference.com/w/cpp/language/data_members#Standard_layout">Standard-Layout</a>
+(a subset of the requirement of plain-old-data types) has a consistent memory
+layout in generated C++ code, enforced with explicit alignment attributes on
+<code>struct</code> and <code>union</code> members.</p>
+
+<p>Primitive HIDL types, as well as <code>enum</code> and <code>bitfield</code>
+types (which always derive from primitive types), map to standard C++ types
+such as <code>std::uint32_t</code> from
+<a href="http://en.cppreference.com/w/cpp/types/integer">cstdint</a>.</p>
+
+<p>As Java does not support unsigned types, unsigned HIDL types are mapped to
+the corresponding signed Java type. <em>Structs</em> map to Java classes;
+<em>arrays</em> map to Java arrays; <em>unions</em> are not currently supported
+in Java. <em>Strings</em> are stored internally as UTF8. Since Java supports
+only UTF16 strings, string values sent to or from a Java implementation are
+translated, and may not be identical on re-translation as the character sets do
+not always map smoothly.</p>
+
+<p>Data received over IPC in C++ is marked <code>const</code> and is in
+read-only memory that persists only for the duration of the function call. Data
+received over IPC in Java has already been copied into Java objects, so it can
+be retained without additional copying (and may be modified).</p>
+
+<h2 id=annotations>Annotations</h2>
+<p>Java-style annotations may be added to type declarations. Annotations are
+parsed by the Vendor Test Suite (VTS) backend of the HIDL compiler but none of
+such parsed annotations are actually understood by the HIDL compiler. Instead,
+parsed VTS annotations are handled by the VTS Compiler (VTSC).</p>
+
+<p>Annotations use Java syntax: <code>@annotation</code> or
+<code>@annotation(value)</code> or <code>@annotation(id=value, id=value…)</code>
+where value may be either a constant expression, a string, or a list of values
+inside <code>{}</code>, just as in Java. Multiple annotations of the same name
+can be attached to the same item.</p>
+
+<h2 id=forward>Forward declarations</h2>
+<p>In HIDL, structs may not be forward-declared, making user-defined,
+self-referential data types impossible (e.g., you cannot describe a linked list
+or a tree in HIDL). Most existing (pre-Android O) HALs have limited use of
+forward declarations, which can be removed by rearranging data structure
+declarations.</p>
+
+<p>This restriction allows data structures to be copied by-value with a simple
+deep-copy, rather than keeping track of pointer values that may occur multiple
+times in a self-referential data structure. If the same data is passed twice,
+such as with two method parameters or <code>vec&lt;T&gt;</code>'s that point to
+the same data, two separate copies are made and delivered.</p>
+
+<h2 id=nested>Nested declarations</h2>
+<p>HIDL supports nested declarations to as many levels as desired (with one
+exception noted below). For example:</p>
+
+<pre class="prettyprint">
+interface IFoo {
+ uint32_t[3][4][5][6] multidimArray;
+
+ vec&lt;vec&lt;vec&lt;int8_t&gt;&gt;&gt; multidimVector;
+
+ vec&lt;bool[4]&gt; arrayVec;
+
+ struct foo {
+ struct bar {
+ uint32_t val;
+ };
+ bar b;
+ }
+ struct baz {
+ foo f;
+ foo.bar fb; // HIDL uses dots to access nested type names
+ }
+ …
+</pre>
+
+<p>The exception is that interface types can only be embedded in
+<code>vec&lt;T&gt;</code> and only one level deep (no
+<code>vec&lt;vec&lt;IFoo&gt;&gt;</code>).</p>
+
+<h2 id=raw-pointer>Raw pointer syntax</h2>
+<p>The HIDL language does not use <strong>*</strong> and does not support the
+full flexibility of C/C++ raw pointers. For details on how HIDL encapsulates
+pointers and arrays/vectors, see <a href="#vec">vec&lt;T&gt; template</a>.</p>
+
+<h2 id=interfaces>Interfaces</h2>
+<p>The <code>interface</code> keyword has two usages.</p>
+
+<ul>
+<li>It opens the definition of an interface in a .hal file.</li>
+<li>It can be used as a special type in struct/union fields, method parameters,
+and returns. It is viewed as a general interface and synonym to
+<code>android.hidl.base@1.0::IBase</code>.</li>
+</ul>
+
+<p>For example, <code>IServiceManager</code> has the following method:</p>
+<pre class="prettyprint">
+get(string fqName, string name) generates (interface service);
+</pre>
+
+<p>The method promises to lookup <em>some interface</em> by name. It is also
+identical to replace interface with <code>android.hidl.base@1.0::IBase</code>.
+</p>
+
+<p>Interfaces can be only passed in two ways: as top-level parameters, or as
+members of a <code>vec&lt;IMyInterface&gt;</code>. They cannot be members of
+nested vecs, structs, arrays, or unions.</p>
+
+<h2 id=mqdescriptor>MQDescriptorSync &amp; MQDescriptorUnsync</h2>
+<p>The <code>MQDescriptorSync</code> and <code>MQDescriptorUnsync</code> types
+pass a synchronized or unsynchronized Fast Message Queue (FMQ) descriptors
+across a HIDL interface. For details, see
+<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (FMQs are not
+supported in Java).</p>
+
+<h2 id=memory>memory type</h2>
+<p>The <code>memory</code> type is used to represent unmapped shared memory in
+HIDL. It is only supported in C++. A value of this type can be used on the
+receiving end to initialize an <code>IMemory</code> object, mapping the memory
+and making it usable. For details, see
+<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a>.</p>
+
+<p class=warning><strong>Warning:</strong> Structured data placed in shared
+memory MUST be a type whose format will never change for the lifetime of the
+interface version passing the <code>memory</code>. Otherwise, HALs may suffer
+fatal compatibility problems.</p>
+
+<h2 id=pointer>pointer type</h2>
+<p>The <code>pointer</code> type is for HIDL internal use only.</p>
+
+<h2 id=bitfield>bitfield&lt;T&gt; type template</h2>
+<p><code>bitfield&lt;T&gt;</code> in which <code>T</code> is a
+<a href="#enum">user-defined enum</a> suggests the value is a bitwise-OR of the
+enum values defined in <code>T</code>. In generated code,
+<code>bitfield&lt;T&gt;</code> appears as the underlying type of T. For
+example:</p>
+
+<pre class="prettyprint">
+enum Flag : uint8_t {
+ HAS_FOO = 1 &lt;&lt; 0,
+ HAS_BAR = 1 &lt;&lt; 1,
+ HAS_BAZ = 1 &lt;&lt; 2
+};
+typedef bitfield&lt;Flag&gt; Flags;
+setFlags(Flags flags) generates (bool success);
+</pre>
+
+<p>The compiler handles the type Flags the same as <code>uint8_t</code>.</p>
+
+<p>Why not use
+<code>(u)int8_t</code>/<code>(u)int16_t</code>/<code>(u)int32_t</code>/<code>(u)int64_t</code>?
+Using <code>bitfield</code> provides additional HAL information to the reader,
+who now knows that <code>setFlags</code> takes a bitwise-OR value of Flag (i.e.
+knows that calling <code>setFlags</code> with 16 is invalid). Without
+<code>bitfield</code>, this information is conveyed only via documentation. In
+addition, VTS can actually check if the value of flags is a bitwise-OR of Flag.
+</p>
+
+<h2 id=handle-primitive>handle primitive type</h2>
+
+<p class=warning><strong>WARNING:</strong> Addresses of any kind (even physical
+device addresses) must never be part of a native handle. Passing this
+information between processes is dangerous and makes them susceptible to attack.
+Any values passed between processes must be validated before they are used to
+look up allocated memory within a process. Otherwise, bad handles may cause bad
+memory access or memory corruption.</p>
+
+<p>HIDL semantics are copy-by-value, which implies that parameters are copied.
+Any large pieces of data, or data that needs to be shared between processes
+(such as a sync fence), are handled by passing around file descriptors pointing
+to persistent objects: <code>ashmem</code> for shared memory, actual files, or
+anything else that can hide behind a file descriptor. The binder driver
+duplicates the file descriptor into the other process.</p>
+
+<h3 id=handle_t>native_handle_t</h3>
+<p>Android supports <code>native_handle_t</code>, a general handle concept
+defined in <code>libcutils</code>.</p>
+
+<pre class="prettyprint">
+typedef struct native_handle
+{
+ int version; /* sizeof(native_handle_t) */
+ int numFds; /* number of file-descriptors at &amp;data[0] */
+ int numInts; /* number of ints at &amp;data[numFds] */
+ int data[0]; /* numFds + numInts ints */
+} native_handle_t;
+</pre>
+
+<p>A native handle is a collection of ints and file descriptors that gets passed
+around by value. A single file descriptor can be stored in a native handle with
+no ints and a single file descriptor. Passing handles using native handles
+encapsulated with the <code>handle</code> primitive type ensures that native
+handles are directly included in HIDL.</p>
+
+<p>As a <code>native_handle_t</code> has variable size, it cannot be included
+directly in a struct. A handle field generates a pointer to a separately
+allocated <code>native_handle_t</code>.</p>
+
+<p>In earlier versions of Android, native handles were created using the same
+functions present in
+<a href="https://android.googlesource.com/platform/system/core/+/master/libcutils/native_handle.c">libcutils</a>.
+In Android O, these functions are now copied to the
+<code>android::hardware::hidl</code> namespace or moved to the NDK. HIDL
+autogenerated code serializes and deserializes these functions automatically,
+without involvement from user-written code.</p>
+
+<h3 id=ownership>Handle and file descriptor ownership</h3>
+<p>When you call a HIDL interface method that passes (or returns) a
+<code>hidl_handle</code> object (either top-level or part of a compound type),
+the ownership of the file descriptors contained in it is as follows:</p>
+
+<ul>
+<li>When passing a <code>hidl_handle</code> object as an argument, the caller
+retains ownership of the file descriptors contained in the
+<code>native_handle_t</code> it wraps, and must close them when it is done with
+them. Likewise, when returning a <code>hidl_handle</code> object (by passing it
+into a <code>_cb</code> function), the process returning it retains ownership of
+the file descriptors contained in the <code>native_handle_t</code> it wraps, and
+must close them when it is done with them.</li>
+<li>When receiving a <code>hidl_handle</code> object, the
+<strong>transport</strong> owns the file descriptors inside the
+<code>native_handle_t</code> it wraps; the receiver can use them as-is during
+the transaction callback, but must clone the native handle if it wants to keep
+using its file descriptors beyond the callback. The transport will automatically
+<code>close()</code> the file descriptors when the transaction is done.</li>
+</ul>
+
+<p>HIDL does not support handles in Java (as Java doesn't support handles at
+all).</p>
+
+<h2 id=sized-arrays>Sized arrays</h2>
+<p>For sized arrays in HIDL structs, their elements can be of any type a struct
+can contain:</p>
+
+<pre class="prettyprint">
+struct foo {
+uint32_t[3] x; // array is contained in foo
+};
+</pre>
+
+<h2 id=strings>Strings</h2>
+<p>Strings appear differently in C++ and Java, but the underlying transport
+storage type is a C++ structure. For details, see
+<a href="/devices/architecture/hidl-cpp/types.html">HIDL C++ Data Types</a> or
+<a href="/devices/architecture/hidl-java/types.html">HIDL Java Data Types</a>.
+</p>
+
+<p class=note><strong>Note:</strong> Passing a string to or from Java through a
+HIDL interface (including Java to Java) will cause character set conversions
+that may not exactly preserve the original encoding.</p>
+
+<h2 id=vec>vec&lt;T&gt; type template</h2>
+<p>The <code>vec&lt;T&gt;</code> template represents a variable-sized buffer
+containing instances of <code>T</code>. <code>T</code> can be any HIDL-provided
+or user-defined type except handle. (A <code>vec&lt;&gt;</code> of
+<code>vec&lt;T&gt;</code> will point to an array of the
+<code>vec&lt;T&gt;</code> structs, not an array of the inner T buffers.)</p>
+
+<p><code>T</code> can be one of the following:</p>
+<ul>
+<li>Primitive types (e.g. uint32_t)</li>
+<li>Strings</li>
+<li>User-defined enums</li>
+<li>User-defined structs</li>
+<li>Interfaces, or the <code>interface</code> keyword
+(<code>vec&lt;IFoo&gt;</code>, <code>vec&lt;interface&gt;</code> is supported
+only as a top-level parameter)</li>
+<li>Handles</li>
+<li>bitfield&lt;U&gt;</li>
+<li>vec&lt;U&gt;, where U is in this list except interface (e.g.
+<code>vec&lt;vec&lt;IFoo&gt;&gt;</code> is not supported)</li>
+<li>U[] (sized array of U), where U is in this list except interface</li>
+</ul>
+
+<h2 id=user>User-defined types</h2>
+<p>This section describes user-defined types.</p>
+
+<h3 id=enum>Enum</h3>
+<p>HIDL does not support anonymous enums. Otherside, enums in HIDL are similar
+to C++11:</p>
+<pre class="prettyprint">
+enum name : type { enumerator , enumerator = constexpr , … }
+</pre>
+
+<p>Enums are defined in terms of one of the primitive types in HIDL, or as an
+extension of other enums. For example:</p>
+<pre class="prettyprint">
+enum Color : uint32_t { RED = 0, GREEN, BLUE = 2 } // GREEN == 1
+</pre>
+
+<p>Values of enums are referred to with the colon syntax (not dot syntax as
+nested types). The syntax is <code>Type:VALUE_NAME</code>. No need to specify
+type if the value is referred in the same enum type or child types. Example:</p>
+<pre class="prettyprint">
+enum Grayscale : uint32_t { BLACK = 0, WHITE = BLACK + 1 };
+enum Color : Grayscale { RED = WHITE + 1 };
+enum Unrelated : uint32_t { FOO = Color:RED + 1 };
+</pre>
+
+<h3 id=struct>Struct</h3>
+<p>HIDL does not support anonymous structs. Otherwise, structs in HIDL are very
+similar to C.</p>
+
+<p>HIDL does not support variable-length data structures contained wholly within
+a struct. This includes the indefinite-length array that is sometimes used as
+the last field of a struct in C/C++ (sometimes seen with a size of
+<code>[0]</code>). HIDL <code>vec&lt;T&gt;</code> represents dynamically-sized
+arrays with the data stored in a separate buffer; such instances are represented
+with an instance of the <code>vec&lt;T&gt;</code> in the <code>struct</code>.
+</p>
+
+<p>Similarly, <code>string</code> can be contained in a <code>struct</code>
+(associated buffers are separate). In the generated C++, instances of the HIDL
+handle type are represented via a pointer to the actual native handle as
+instances of the underlying data type are variable-length.</p>
+
+<h3 id=union>Union</h3>
+<p>HIDL does not support anonymous unions. Otherwise, unions are similar to C.
+</p>
+
+<p>Unions cannot contain fix-up types (pointers, file descriptors, binder
+objects, etc.). They do not need special fields or associated types and are
+simply copied via <code>memcpy()</code> or equivalent. An union may not directly
+contain (or contain via other data structures) anything that requires setting
+binder offsets (i.e., handle or binder-interface references). For example:</p>
+
+<pre class="prettyprint">
+union UnionType {
+uint32_t a;
+// vec&lt;uint32_t&gt; r; // Error: can't contain a vec&lt;T&gt;
+uint8_t b;1
+};
+fun8(UnionType info); // Legal
+</pre>
+
+<p>Unions can also be declared inside of structs. For example:</p>
+<pre class="prettyprint">
+struct MyStruct {
+ union MyUnion {
+ uint32_t a;
+ uint8_t b;
+ }; // declares type but not member
+
+ union MyUnion2 {
+ uint32_t a;
+ uint8_t b;
+ } data; // declares type but not member
+ }
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/hidl/versioning.html b/en/devices/architecture/hidl/versioning.html
new file mode 100644
index 00000000..aed6f9fe
--- /dev/null
+++ b/en/devices/architecture/hidl/versioning.html
@@ -0,0 +1,655 @@
+<html devsite>
+ <head>
+ <title>Versioning</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>HIDL requires every interface written in HIDL be versioned. After a HAL
+interface is published, it is frozen and any further changes must be made to a
+new version of that interface. While a given published interface may not be
+modified, it can be extended by another interface.</p>
+
+<h2 id=code-structure>HIDL code structure</h2>
+
+<p>
+<a href="/reference/hidl/index.html">HIDL code is organized</a> in user-defined
+types, interfaces, and packages:</p>
+
+<ul>
+<li><strong>User-defined types (UDTs)</strong>. HIDL provides access to a set of
+primitive data types that can be used to compose more complex types via
+structures, unions, and enumerations</a>. UDTs are passed to methods of
+interfaces, and can be defined at the level of a package (common to all
+interfaces) or locally to an interface.</li>
+<li><strong>Interfaces</strong>. As a basic building block of HIDL, an interface
+consists of UDT and method declarations. Interfaces can also inherit from
+another interface.</li>
+<li><strong>Packages</strong>. Organizes related HIDL interfaces and the data
+types on which they operate. A package is identified by a name and a version and
+includes the following:
+<ul>
+ <li>Data-type definition file called <code>types.hal</code>.</li>
+ <li>Zero or more interfaces, each in their own <code>.hal</code> file.</li>
+</ul>
+</li>
+</ul>
+
+<p>The data-type definition file <code>types.hal</code> contains only UDTs (all
+package-level UDTs are kept in a single file). Representations in the target
+language are available to all interfaces in the package.</p>
+
+<h2 id=philosophy>Versioning philosophy</h2>
+<p>A HIDL package (such as <code>android.hardware.nfc</code>), after being
+published for a given version (such as <code>1.0</code>), is immutable; it
+cannot be changed. Modifications to the interfaces in the package or any
+changes to its UDTs can take place only in <em>another</em> package.</p>
+
+<p>In HIDL, versioning applies at the package level, not at the interface level,
+and all interfaces and UDTs in a package share the same version. Package
+versions follow <a href="http://semver.org/" class="external">semantic
+versioning</a> without the patch level and build-metadata components. Within a
+given package, a <strong>minor version</strong> bump implies the new version of
+the package is backwards-compatible with the old package and a <strong>major
+version</strong> bump implies the new version of the package is not
+backwards-compatible with the old package.</p>
+
+<p>Conceptually, a package can relate to another package in one of several ways:
+</p>
+
+<ul>
+<li><strong>Not at all</strong>.</li>
+<li><strong>Package-level backwards-compatible extensibility</strong>. This
+occurs for new minor-version uprevs (next incremented revision) of a package;
+the new package has the same name and major version as the old package, but a
+higher minor version. Functionally, the new package is a superset of the old
+package, meaning:
+<ul>
+ <li>Top-level interfaces of the parent package are present in the new package,
+ though the interfaces may have new methods, new interface-local UDTs (the
+ interface-level extension described below), and new UDTs in
+ <code>types.hal</code>.</li>
+ <li>New interfaces may also be added to the new package.</li>
+ <li>All data types of the parent package are present in the new package and
+ can be handled by the (possibly reimplemented) methods from the old package.
+ </li>
+ <li>New data types may also be added for use by either new methods of uprev'ed
+ existing interfaces, or by new interfaces.</li>
+</ul>
+</li>
+
+<li><strong>Interface-level backwards-compatible extensibility</strong>. The new
+package can also extend the original package by consisting of logically separate
+interfaces that simply provide additional functionality, and not the core one.
+For this purpose, the following may be desirable:
+<ul>
+ <li>Interfaces in the new package need recourse to the data types of the old
+ package.</li>
+ <li>Interfaces in new package may extend interfaces of one or more old
+ packages.</li>
+</ul>
+</li>
+<li><strong>Extend the original backwards-incompatibility</strong>. This is a
+major-version uprev of the package and there need not be any correlation between
+the two. To the extent that there is, it can be expressed with a combination of
+types from the older version of the package, and inheritance of a subset of
+old-package interfaces.</li>
+</ul>
+
+<h2 id=code-layout>HIDL code layout</h2>
+<p>HIDL includes core and vendor packages.</p>
+
+<p>Core HIDL interfaces are those specified by Google. The packages they belong
+to start with <code>android.hardware.</code> and are named by subsystem,
+potentially with nested levels of naming. For example, the NFC package is named
+<code>android.hardware.nfc</code> and the camera package is
+<code>android.hardware.camera</code>. In general, a core package has the name
+<code>android.hardware.</code>[<code>name1</code>].[<code>name2</code>]&#8230;.
+HIDL packages have a version in addition to their name. For example, the package
+<code>android.hardware.camera</code> may be at version <code>3.4</code>; this is
+important, as the version of a package affects its placement in the source tree.
+</p>
+
+<p>All core packages are placed under <code>hardware/interfaces/</code> in the
+build system. The package
+<code>android.hardware.</code>[<code>name1</code>].[<code>name2</code>]&#8230;
+at version <code>$m.$n</code> is under
+<code>hardware/interfaces/name1/name2/</code>…<code>/$m.$n/</code>; package
+<code>android.hardware.camera</code> version <code>3.4</code> is in directory
+<code>hardware/interfaces/camera/3.4/.</code> A hard-coded mapping exists
+between the package prefix <code>android.hardware.</code> and the path
+<code>hardware/interfaces/</code>.</p>
+
+<p>Non-core (vendor) packages are those produced by the SoC vendor or ODM. The
+prefix for non-core packages is <code>vendor.$(VENDOR).hardware.</code> where
+<code>$(VENDOR)</code>refers to an SoC vendor or OEM/ODM. This maps to the path
+<code>vendor/$(VENDOR)/interfaces</code> in the tree (this mapping is also
+hard-coded).</p>
+
+<h2 id=fqn>Fully-qualified user-defined-type names</h2>
+<p>In HIDL, every UDT has a fully-qualified name that consists of the UDT name,
+the package name where the UDT is defined, and the package version. The
+fully-qualified name is used only when instances of the type are declared and
+not where the type itself is defined. For example, assume package
+<code>android.hardware.nfc,</code> version <code>1.0</code> defines a struct
+named <code>NfcData</code>. At the site of the declaration (whether in
+<code>types.hal</code> or within an interface's declaration), the declaration
+simply states:</p>
+
+<pre class="prettyprint">
+struct NfcData {
+ vec&lt;uint8_t&gt; data;
+};
+</pre>
+
+<p>When declaring an instance of this type (whether within a data structure or
+as a method parameter), use the fully-qualified type name:</p>
+
+<pre class="prettyprint">android.hardware.nfc@1.0::NfcData</pre>
+
+<p>The general syntax is
+<code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var></code>, where:</p>
+
+<ul>
+<li><code><var>PACKAGE</var></code> is the dot-separated name of a HIDL package
+(e.g., <code>android.hardware.nfc</code>).</li>
+<li><code><var>VERSION</var></code> is the dot-separated major.minor-version
+format of the package (e.g., <code>1.0</code>).</li>
+<li><code><var>UDT</var></code> is the the dot-separated name of a HIDL UDT.
+Since HIDL supports nested UDTs and HIDL interfaces can contain UDTs (a type of
+nested declaration), dots are used to access the names.</li>
+</ul>
+
+<p>For example, if the following nested declaration was defined in the common
+types file in package <code>android.hardware.example</code> version
+<code>1.0</code>:</p>
+
+<pre class="prettyprint">
+// types.hal
+package android.hardware.example@1.0;
+struct Foo {
+ struct Bar {
+ // …
+ };
+ Bar cheers;
+};
+</pre>
+
+<p>The fully-qualified name for <code>Bar</code> is
+<code>android.hardware.example@1.0::Foo.Bar</code>. If, in addition to being in
+the above package, the nested declaration were in an interface called
+<code>IQuux</code>:</p>
+
+<pre class="prettyprint">
+// IQuux.hal
+package android.hardware.example@1.0;
+interface IQuux {
+ struct Foo {
+ struct Bar {
+ // …
+ };
+ Bar cheers;
+ };
+ doSomething(Foo f) generates (Foo.Bar fb);
+};
+</pre>
+
+<p>The fully-qualified name for <code>Bar</code> is
+<code>android.hardware.example@1.0::IQuux.Foo.Bar</code>.</p>
+
+<p>In both cases, <code>Bar</code> can be referred to as <code>Bar</code> only
+within the scope of the declaration of <code>Foo</code>. At the package or
+interface level, you must refer to <code>Bar</code> via <code>Foo</code>:
+<code>Foo.Bar</code>, as in the declaration of method <code>doSomething</code>
+above. Alternatively, you could declare the method more verbosely as:</p>
+
+<pre class="prettyprint">
+// IQuux.hal
+doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);
+</pre>
+
+<h2 id=enumeration>Fully-qualified enumeration values</h2>
+<p>If a UDT is an enum type, then each value of the enum type has a
+fully-qualified name that starts with the fully-qualified name of the enum type,
+followed by a colon, then followed by the name of the enum value. For example,
+assume package <code>android.hardware.nfc,</code> version <code>1.0</code>
+defines an enum type <code>NfcStatus</code>:</p>
+
+<pre class="prettyprint">
+enum NfcStatus {
+ STATUS_OK,
+ STATUS_FAILED
+};
+</pre>
+
+<p>When referring to <code>STATUS_OK</code>, the fully qualified name is:</p>
+
+<pre class="prettyprint">android.hardware.nfc@1.0::NfcStatus:STATUS_OK</pre>
+
+<p>The general syntax is
+<code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var>:<var>VALUE</var></code>,
+where:
+
+<ul>
+<li><code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var></code> is the
+exact same fully qualified name for the enum type.</li>
+<li><code><var>VALUE</var></code> is the value's name.</li>
+</ul>
+
+<h2 id=auto-interference>Auto-inference rules</h2>
+<p>A fully-qualified UDT name does not need to be specified. A UDT name can
+safely omit the following:</p>
+<ul>
+<li>The package, e.g. <code>@1.0::IFoo.Type</code></li>
+<li>Both package and version, e.g. <code>IFoo.Type</code></li>
+</ul>
+
+<aside class="caution"><strong>Caution:</strong> UDT names missing a version but
+specifying a package present are not allowed.</aside>
+
+<p>HIDL attempts to complete the name using auto-interference rules (lower rule
+number means higher priority).</p>
+
+<h3 id=rule1>Rule 1</h3>
+<p>If no package and version is provided, a local name lookup is attempted.
+Example:</p>
+
+<pre class="prettyprint">
+interface Nfc {
+ typedef string NfcErrorMessage;
+ send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m);
+};
+</pre>
+
+<p><code>NfcErrorMessage</code> is looked up locally, and the <code>typedef</code>
+above it is found. <code>NfcData</code> is also looked up locally, but as it is
+not defined locally, rule 2 and 3 are used. <code>@1.0::NfcStatus</code>
+provides a version, so rule 1 does not apply.</p>
+
+<h3 id=rule2>Rule 2</h3>
+<p>If rule 1 fails and a component of the fully-qualified name is missing
+(package, version, or package and version), the component is autofilled with
+information from the current package. The HIDL compiler then looks in the
+current file (and all imports) to find the autofilled fully-qualified name.
+Using the example above, assume the declaration of <code>ExtendedNfcData</code>
+was made in the same package (<code>android.hardware.nfc</code>) at the same
+version (<code>1.0</code>) as <code>NfcData</code>, as follows:</p>
+
+<pre class="prettyprint">
+struct ExtendedNfcData {
+ NfcData base;
+ // … additional members
+};
+</pre>
+
+<p>The HIDL compiler fills out the package name and version name from the
+current package to produce the fully-qualified UDT name
+<code>android.hardware.nfc@1.0::NfcData</code>. As the name exists in the
+current package (assuming it is imported properly), it is used for the
+declaration.</p>
+
+<p>A name in the current package is imported only if one of the following is
+true:</p>
+<ul>
+<li>It is imported explicitly with an <code>import</code> statement.</li>
+<li>It is defined in <code>types.hal</code> in the current package</li>
+</ul>
+
+<p>The same process is followed if <code>NfcData</code> was qualified by only
+the version number:</p>
+
+<pre class="prettyprint">
+struct ExtendedNfcData {
+ // autofill the current package name (android.hardware.nfc)
+ @1.0::NfcData base;
+ // … additional members
+};
+</pre>
+
+<h3 id=rule3>Rule 3</h3>
+<p>If rule 2 fails to produce a match (the UDT is not defined in the current
+package), the HIDL compiler scans for a match within all imported packages.
+Using the above example, assume <code>ExtendedNfcData</code> is declared in
+version <code>1.1</code> of package <code>android.hardware.nfc</code>,
+<code>1.1</code> imports <code>1.0</code> as it should (see
+<a href="#package-ext">Package-Level Extensions</a>), and the definition
+specifies only the UDT name:</p>
+
+<pre class="prettyprint">
+struct ExtendedNfcData {
+ NfcData base;
+ // … additional members
+};
+</pre>
+
+<p>The compiler looks for any UDT named <code>NfcData</code> and finds one in
+<code>android.hardware.nfc</code> at version <code>1.0</code>, resulting in a
+fully-qualified UDT of <code>android.hardware.nfc@1.0::NfcData</code>. If more
+than one match is found for a given partially-qualified UDT, the HIDL compiler
+throws an error.</p>
+
+<h3 id=rule-example>Example</h3>
+<p>Using rule 2, an imported type defined in the current package is favored over
+an imported type from another package:</p>
+
+<pre class="prettyprint">
+// hardware/interfaces/foo/1.0/types.hal
+package android.hardware.foo@1.0;
+struct S {};
+
+// hardware/interfaces/foo/1.0/IFooCallback.hal
+package android.hardware.foo@1.0;
+interface IFooCallback {};
+
+// hardware/interfaces/bar/1.0/types.hal
+package android.hardware.bar@1.0;
+typedef string S;
+
+// hardware/interfaces/bar/1.0/IFooCallback.hal
+package android.hardware.bar@1.0;
+interface IFooCallback {};
+
+// hardware/interfaces/bar/1.0/IBar.hal
+package android.hardware.bar@1.0;
+import android.hardware.foo@1.0;
+interface IBar {
+ baz1(S s); // android.hardware.bar@1.0::S
+ baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback
+};
+</pre>
+
+<ul>
+<li><strong><code>S</code></strong> is interpolated as
+<code>android.hardware.bar@1.0::S</code>, and is found in
+<code>bar/1.0/types.hal</code> (because <code>types.hal</code> is automatically
+imported).</li>
+<li><strong><code>IFooCallback</code></strong> is interpolated as
+<code>android.hardware.bar@1.0::IFooCallback</code> using rule 2, but it
+cannot be found because <code>bar/1.0/IFooCallback.hal</code> is not imported
+automatically (as <code>types.hal</code> is). Thus, rule 3 resolves it to
+<code>android.hardware.foo@1.0::IFooCallback</code> instead, which is imported
+via <code>import android.hardware.foo@1.0;</code>).</li>
+</ul>
+
+<h2 id=types>types.hal</h2>
+<p>Every HIDL package contains a <code>types.hal</code> file with UDTs share
+among all interfaces participating in that package. HIDL types are always
+public; regardless of whether a UDT is declared in <code>types.hal</code> or
+within an interface declaration, these types are accessible outside of the scope
+where they are defined. <code>types.hal</code> is not meant to describe the
+public API of a package, but rather to host UDTs used by all interfaces within
+the package. Due to the nature of HIDL, all UDTs are a part of the interface.
+</p>
+
+<p><code>types.hal</code> consists of UDTs and <code>import</code> statements.
+Because <code>types.hal</code> is made available to every interface of the
+package (it is an implicit import), these <code>import</code> statements are
+package-level by definition. UDTs in <code>types.hal</code> may also incorporate
+UDTs and interfaces thus imported.</p>
+
+<p>For example, for an <code>IFoo.hal</code>:</p>
+
+<pre class="prettyprint">
+package android.hardware.foo@1.0;
+// whole package import
+import android.hardware.bar@1.0;
+// types only import
+import android.hardware.baz@1.0::types;
+// partial imports
+import android.hardware.qux@1.0::IQux.Quux;
+// partial imports
+import android.hardware.quuz@1.0::Quuz;
+</pre>
+
+<p>The following are imported:</p>
+<ul>
+<li><code>android.hidl.base@1.0::IBase</code> (implicitly)</li>
+<li><code>android.hardware.foo@1.0::types</code> (implicitly)</li>
+<li>Everything in <code>android.hardware.bar@1.0</code> (including all
+interfaces and its <code>types.hal</code>)</li>
+<li><code>types.hal</code> from <code>android.hardware.baz@1.0::types</code>
+(interfaces in <code>android.hardware.baz@1.0</code> are not imported)</li>
+<li><code>IQux.hal</code> and <code>types.hal</code> from
+<code>android.hardware.qux@1.0</code></li>
+<li><code>Quuz</code> from <code>android.hardware.quuz@1.0</code> (assuming
+<code>Quuz</code> is defined in <code>types.hal</code>, the entire
+<code>types.hal</code> file is parsed, but types other than <code>Quuz</code>
+are not imported).</li>
+</ul>
+
+<h2 id=interface-version>Interface-level versioning</h2>
+<p>Each interface within a package resides in its own file. The package the
+interface belongs to is declared at the top of the interface using the
+<code>package</code> statement. Following the package declaration, zero or more
+interface-level imports (partial or whole-package) may be listed. For example:
+</p>
+
+<pre class="prettyprint">package android.hardware.nfc@1.0;</pre>
+
+<p>In HIDL, interfaces can inherit from other interfaces using the
+<code>extends</code> keyword. For an interface to extend another interface, it
+must have access to it via an <code>import</code> statement. The name of the
+interface being extended (the base interface) follows the rules for type-name
+qualification explained above. An interface may inherit only from one interface;
+HIDL does not support multiple inheritance.</p>
+
+<p>The uprev versioning examples below use the following package:</p>
+
+<pre class="prettyprint">
+// types.hal
+package android.hardware.example@1.0
+struct Foo {
+ struct Bar {
+ vec&lt;uint32_t&gt; val;
+ };
+};
+
+// IQuux.hal
+package android.hardware.example@1.0
+interface IQuux {
+ fromFooToBar(Foo f) generates (Foo.Bar b);
+}
+</pre>
+
+<h3 id=rules>Uprev rules</h3>
+<p>To define a package <code>package@major.minor</code>, either A or all of B
+must be true:</p>
+
+<table>
+<tr>
+<th width="10%">Rule A</th>
+<td>"Is a start minor version": All previous minor versions,
+<code>package@major.0</code>, <code>package@major.1</code>, &#8230;,
+<code>package@major.(minor-1)</code> must not be defined.
+</td>
+</tr>
+</table>
+
+<strong>OR</strong>
+
+<table>
+<tr>
+<th width="10%">Rule B</th>
+<td><p>All of the following is true:</p>
+
+<ol>
+<li>"Previous minor version is valid": <code>package@major.(minor-1)</code>
+must be defined and follow the same rule A (none of
+<code>package@major.0</code> through <code>package@major.(major-2)</code>
+are defined) or rule B (if it is an uprev from <code>@major.(major-2)</code>);
+<br><br>
+AND
+<br><br>
+</li>
+<li>"Inherit at least one interface with the same name": There exists an
+interface <code>package@major.minor::IFoo</code> that extends
+<code>package@major.(minor-1)::IFoo</code>;
+<br><br>
+AND
+<br><br>
+</li>
+<li>"No inherited interface with a different name": There must not exist
+<code>package@major.minor::IBar</code> that extends
+<code>package@major.(minor-1)::IBaz</code>, where <code>IBar</code> and
+<code>IBaz</code> are two different names. If there is an interface with the
+same name, <code>package@major.minor::IBar</code> must extend
+<code>package@major.(minor-k)::IBar</code> such that no IBar exists with a
+smaller k.</li>
+</ol>
+</td>
+</tr>
+</table>
+
+<p>Because of rule A:</p>
+<ul>
+<li>The package can start with any minor version number (for example,
+<code>android.hardware.biometrics.fingerprint</code> starts at
+<code>@2.1</code>.)</li>
+<li>The requirement "<code>android.hardware.foo@1.0</code> is not defined" means
+the directory <code>hardware/interfaces/foo/1.0</code> should not even exist.
+</li>
+</ul>
+
+<p>However, rule A does not affect a package with the same package name but a
+different <em>major</em> version (for example,
+<code>android.hardware.camera.device</code> has both <code>@1.0</code> and
+<code>@3.2</code> defined; <code>@3.2</code> doesn't need to interact with
+<code>@1.0</code>.) Hence, <code>@3.2::IExtFoo</code> can extend
+<code>@1.0::IFoo</code>.</p>
+
+<p>Provided the package name is different,
+<code>package@major.minor::IBar</code> may extend from an interface with a
+different name (for example, <code>android.hardware.bar@1.0::IBar</code> can
+extend <code>android.hardware.baz@2.2::IBaz</code>). If an interface does not
+explicitly declare a super type with the <code>extend</code> keyword, it will
+extend <code>android.hidl.base@1.0::IBase</code> (except <code>IBase</code>
+itself).</p>
+
+<p>B.2 and B.3 must be followed at the same time. For example, even if
+<code>android.hardware.foo@1.1::IFoo</code> extends
+<code>android.hardware.foo@1.0::IFoo</code> to pass rule B.2, if an
+<code>android.hardware.foo@1.1::IExtBar</code> extends
+<code>android.hardware.foo@1.0::IBar</code>, this is still not a valid uprev.
+</p>
+
+<h3 id=uprev>Upreving interfaces</h3>
+<p>To uprev <code>android.hardware.example@1.0</code> (defined above) to
+<code>@1.1</code>:</p>
+
+<pre class="prettyprint">
+// types.hal
+package android.hardware.example@1.1;
+<strong>import android.hardware.example@1.0;</strong>
+
+// IQuux.hal
+package android.hardware.example@1.1
+interface IQuux <strong>extends @1.0::IQuux</strong> {
+ <strong>fromBarToFoo(Foo.Bar b) generates (Foo f);</strong>
+}
+</pre>
+
+<p>This is a package-level <code>import</code> of version <code>1.0</code> of
+<code>android.hardware.example</code> in <code>types.hal</code>. While no new
+UDTs are added in version <code>1.1</code> of the package, references to UDTs in
+version <code>1.0</code> are still needed, hence the package-level import
+in <code>types.hal</code>. (The same effect could have been achieved with an
+interface-level import in <code>IQuux.hal</code>.)</p>
+
+<p>In <code>extends @1.0::IQuux</code> in the declaration of
+<code>IQuux</code>, we specified the version of <code>IQuux</code> that is being
+inherited (disambiguation is required because <code>IQuux</code> is used to
+declare an interface and to inherit from an interface). As declarations are
+simply names that inherit all package and version attributes at the site of the
+declaration, the disambiguation must be in the name of the base interface; we
+could have used the fully-qualified UDT as well, but that would have been
+redundant.</p>
+
+<p>The new interface <code>IQuux</code> does not re-declare method
+<code>fromFooToBar()</code> it inherits from <code>@1.0::IQuux</code>; it simply
+lists the new method it adds <code>fromBarToFoo()</code>. In HIDL, inherited
+methods may <strong>not</strong> be declared again in the child interfaces, so
+for <code>IQuux</code> it would not be an option to declare
+<code>fromFooToBar()</code> explicitly.</p>
+
+<aside class="key-point"><strong>Key Point:</strong> In HIDL, every inherited
+method from a base class must be explicitly implemented in the inheriting class.
+If a method implementation needs to fall back to that of the base, the fallback
+must be in the implementation.</aside>
+
+<h3 id=conventions>Uprev conventions</h3>
+<p>Sometimes interface names must rename the extending interface. We recommend
+that enum extensions, structs, and unions have the same name as what they extend
+unless they are sufficiently different to warrant a new name. Examples:</p>
+
+<pre class="prettyprint">
+// in parent hal file
+enum Brightness : uint32_t { NONE, WHITE };
+
+// in child hal file extending the existing set with additional similar values
+enum Brightness : @1.0::Brightness { AUTOMATIC };
+
+// extending the existing set with values that require a new, more descriptive name:
+enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };
+</pre>
+
+<p>Unless a method warrants a new name, it should be named similarly to what it
+is extending. For example, the method <code>foo_1_1</code> in
+<code>@1.1::IFoo</code> may replace the functionality of the <code>foo</code>
+method in <code>@1.0::IFoo</code>.</p>
+
+<h2 id=package-ext>Package-level versioning</h2>
+<p>HIDL versioning occurs at the package level; after a package is published, it
+is immutable (its set of interfaces and UDTs cannot be changed). Packages can
+relate to each other in several ways, all of which are expressible via a
+combination of interface-level inheritance and building of UDTs by composition.
+</p>
+
+<p>However, one type of relationship is strictly-defined and must be enforced:
+<em>Package-level backwards-compatible inheritance</em>. In this scenario, the
+<em>parent</em> package is the package being inherited from and the
+<em>child</em> package is the one extending the parent. Package-level
+backwards-compatible inheritance rules are as follows:</p>
+
+<ol>
+<li>All interfaces of the parent package are inherited from by interfaces in the
+child package.</li>
+<li>All data types of the parent package are present in the new package and can
+be handled by the (possibly reimplemented) methods from the old package.</li>
+<li>New interfaces may also be added the new package (no restrictions about
+relationships to other interfaces in other packages).</li>
+<li>New data types may also be added for use by either new methods of uprev'ed
+existing interfaces, or by new interfaces.</li>
+</ol>
+
+<p>These rules can be implemented using HIDL interface-level inheritance and UDT
+composition, but require meta-level knowledge to know these relationships
+constitute a backwards-compatible package extension. This knowledge is inferred
+as follows:</p>
+
+<aside class="key-point"><strong>Key Point:</strong> For package
+<code>package</code> at version <code>major.minor</code>, if a
+<code>package</code> exists at <code>major.(minor-1)</code>, then
+<code>package@major.minor</code> is a minor uprev, and must follow the rules for
+backwards-compatibility.</aside>
+
+<p>If a package meets this requirement, <code>hidl-gen</code> enforces
+backwards-compatibility rules.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/images/treble_configstore_design.png b/en/devices/architecture/images/treble_configstore_design.png
new file mode 100644
index 00000000..c51f7ef2
--- /dev/null
+++ b/en/devices/architecture/images/treble_configstore_design.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_cpp_compiler_generated_files.png b/en/devices/architecture/images/treble_cpp_compiler_generated_files.png
new file mode 100644
index 00000000..7d9de250
--- /dev/null
+++ b/en/devices/architecture/images/treble_cpp_compiler_generated_files.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_cpp_legacy_hal_progression.png b/en/devices/architecture/images/treble_cpp_legacy_hal_progression.png
new file mode 100644
index 00000000..bf2bb65e
--- /dev/null
+++ b/en/devices/architecture/images/treble_cpp_legacy_hal_progression.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_appending.png b/en/devices/architecture/images/treble_dto_appending.png
new file mode 100644
index 00000000..7c9fbfc4
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_appending.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_bootloader.png b/en/devices/architecture/images/treble_dto_bootloader.png
new file mode 100644
index 00000000..eab12e26
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_bootloader.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo.png b/en/devices/architecture/images/treble_dto_dtbo.png
new file mode 100644
index 00000000..7e4b4a88
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_ab.png b/en/devices/architecture/images/treble_dto_dtbo_ab.png
new file mode 100644
index 00000000..64263d7c
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_ab.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_ab_1.png b/en/devices/architecture/images/treble_dto_dtbo_ab_1.png
new file mode 100644
index 00000000..606b81b5
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_ab_1.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_ab_2.png b/en/devices/architecture/images/treble_dto_dtbo_ab_2.png
new file mode 100644
index 00000000..307ff61c
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_ab_2.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_multiple.png b/en/devices/architecture/images/treble_dto_dtbo_multiple.png
new file mode 100644
index 00000000..6fd63b99
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_multiple.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_partition_1.png b/en/devices/architecture/images/treble_dto_dtbo_partition_1.png
new file mode 100644
index 00000000..58b5a20e
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_partition_1.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_dtbo_partition_2.png b/en/devices/architecture/images/treble_dto_dtbo_partition_2.png
new file mode 100644
index 00000000..5b84c909
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_dtbo_partition_2.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_multiple_dt.png b/en/devices/architecture/images/treble_dto_multiple_dt.png
new file mode 100644
index 00000000..038c2c97
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_multiple_dt.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_multiple_dt_runtime.png b/en/devices/architecture/images/treble_dto_multiple_dt_runtime.png
new file mode 100644
index 00000000..0d47b4fb
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_multiple_dt_runtime.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_overriding.png b/en/devices/architecture/images/treble_dto_overriding.png
new file mode 100644
index 00000000..d838cec4
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_overriding.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_partition_1.png b/en/devices/architecture/images/treble_dto_partition_1.png
new file mode 100644
index 00000000..3585fa6a
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_partition_1.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_partition_2.png b/en/devices/architecture/images/treble_dto_partition_2.png
new file mode 100644
index 00000000..fa53dde9
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_partition_2.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_partition_layout.png b/en/devices/architecture/images/treble_dto_partition_layout.png
new file mode 100644
index 00000000..5519ab31
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_partition_layout.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_dto_simulate.png b/en/devices/architecture/images/treble_dto_simulate.png
new file mode 100644
index 00000000..c61e05da
--- /dev/null
+++ b/en/devices/architecture/images/treble_dto_simulate.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_kernel_current.png b/en/devices/architecture/images/treble_kernel_current.png
new file mode 100644
index 00000000..5870b8b8
--- /dev/null
+++ b/en/devices/architecture/images/treble_kernel_current.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_kernel_treble.png b/en/devices/architecture/images/treble_kernel_treble.png
new file mode 100644
index 00000000..3be5bb03
--- /dev/null
+++ b/en/devices/architecture/images/treble_kernel_treble.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_bcc_plugin_new.png b/en/devices/architecture/images/treble_rs_bcc_plugin_new.png
new file mode 100644
index 00000000..dc58bfdf
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_bcc_plugin_new.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_bcc_plugin_old.png b/en/devices/architecture/images/treble_rs_bcc_plugin_old.png
new file mode 100644
index 00000000..b621ba39
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_bcc_plugin_old.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_cpu_fallback.png b/en/devices/architecture/images/treble_rs_cpu_fallback.png
new file mode 100644
index 00000000..b9fd07aa
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_cpu_fallback.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_gpu_fallback.png b/en/devices/architecture/images/treble_rs_gpu_fallback.png
new file mode 100644
index 00000000..4fbcbedd
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_gpu_fallback.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_linking.png b/en/devices/architecture/images/treble_rs_linking.png
new file mode 100644
index 00000000..984adeaa
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_linking.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_namespace.png b/en/devices/architecture/images/treble_rs_namespace.png
new file mode 100644
index 00000000..f3568121
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_namespace.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_rs_vendor_driver.png b/en/devices/architecture/images/treble_rs_vendor_driver.png
new file mode 100644
index 00000000..26861aa4
--- /dev/null
+++ b/en/devices/architecture/images/treble_rs_vendor_driver.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_vintf_avb_o_p.png b/en/devices/architecture/images/treble_vintf_avb_o_p.png
new file mode 100644
index 00000000..a92bfbf4
--- /dev/null
+++ b/en/devices/architecture/images/treble_vintf_avb_o_p.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_vintf_avb_p.png b/en/devices/architecture/images/treble_vintf_avb_p.png
new file mode 100644
index 00000000..82e6986d
--- /dev/null
+++ b/en/devices/architecture/images/treble_vintf_avb_p.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_vintf_mm.png b/en/devices/architecture/images/treble_vintf_mm.png
new file mode 100644
index 00000000..95339e1d
--- /dev/null
+++ b/en/devices/architecture/images/treble_vintf_mm.png
Binary files differ
diff --git a/en/devices/architecture/images/treble_vndk_design.png b/en/devices/architecture/images/treble_vndk_design.png
new file mode 100644
index 00000000..596aea27
--- /dev/null
+++ b/en/devices/architecture/images/treble_vndk_design.png
Binary files differ
diff --git a/en/devices/architecture/kernel/hardening.html b/en/devices/architecture/kernel/hardening.html
new file mode 100644
index 00000000..28b6d87e
--- /dev/null
+++ b/en/devices/architecture/kernel/hardening.html
@@ -0,0 +1,100 @@
+<html devsite>
+ <head>
+ <title>Kernel Hardening</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 8.0 added kernel hardening features to help mitigate kernel
+vulnerabilities and find bugs in kernel drivers. The features are in <a
+href="https://android.googlesource.com/kernel/common/">kernel/common</a> in
+branches android-3.18, android-4.4, and android-4.9.
+</p>
+<h2 id="implementation">Implementation</h2>
+<p>
+To acquire these features, device manufacturers and SOCs should merge all
+hardening patches from <code>kernel/common</code> to their kernel tree and
+enable the following kernel configuration options:
+</p>
+<ul>
+ <li>Hardened usercopy: <code>CONFIG_HARDENED_USERCOPY=y</code></li>
+ <li>PAN emulation - arm64: <code>CONFIG_ARM64_SW_TTBR0_PAN=y</code></li>
+ <li>PAN emulation - arm: <code>CONFIG_CPU_SW_DOMAIN_PAN=y</code></li>
+ <li>KASLR - 4.4 and later kernels:
+ <code>CONFIG_RANDOMIZE_BASE=y</code></li>
+</ul>
+<p>
+KASLR also requires bootloader support for passing hardware entropy through
+either the device tree node <code>/chosen/kaslr-seed</code> or by implementing
+<code>EFI_RNG_PROTOCOL</code>.
+</p>
+<p>
+Also ensure existing hardening features are enabled:
+</p>
+<ul>
+ <li>Stack buffer overflow mitigation:
+ <code>CONFIG_CC_STACKPROTECTOR_STRONG=y</code></li>
+ <li>Internal memory protection: <code>CONFIG_DEBUG_RODATA=y</code> or
+ <code>CONFIG_STRICT_KERNEL_RWX=y</code></li>
+ <li>Restrict user-space access from kernel - x86 (enabled by default):
+ <code>CONFIG_X86_SMAP=y</code></li>
+</ul>
+<h2 id="testing">Testing</h2>
+<p>
+To test your implementation, add <code>CONFIG_LKDTM=y</code> to the kernel
+configuration and confirm that each of the following commands lead to a kernel
+panic:
+</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal" data-terminal-prefix="# ">echo ACCESS_USERSPACE &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo EXEC_USERSPACE &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo WRITE_RO &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo WRITE_RO_AFTER_INIT &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo WRITE_KERN &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo EXEC_STACK &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo EXEC_RODATA &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo EXEC_KMALLOC &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo EXEC_VMALLOC &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo CORRUPT_STACK &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+</pre>
+<p>
+<strong>For android-4.9:</strong>
+</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal" data-terminal-prefix="# ">echo USERCOPY_HEAP_SIZE_TO &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+<code class="devsite-terminal" data-terminal-prefix="# ">echo USERCOPY_HEAP_SIZE_FROM &gt; /sys/kernel/debug/provoke-crash/DIRECT</code>
+</pre>
+
+<h2 id="common-issues">Common issues</h2>
+<p>
+These changes are likely to expose bugs in kernel drivers, which need to be
+fixed either by the device manufacturer or the owner of the kernel driver.
+</p>
+<ul>
+ <li>Hardened usercopy exposes incorrect bounds checking when copying data
+ to/from user space. These should be fixed like any other memory corruption bugs.</li>
+ <li>PAN emulation exposes direct user space access from the kernel, which is not
+ allowed. Drivers attempting to access user space memory need to be changed to
+ use the standard <code>copy_to_user()</code>/<code>copy_from_user()</code>
+ functions instead.</li>
+</ul>
+</body>
+</html>
diff --git a/en/devices/architecture/kernel/index.html b/en/devices/architecture/kernel/index.html
new file mode 100644
index 00000000..456662f7
--- /dev/null
+++ b/en/devices/architecture/kernel/index.html
@@ -0,0 +1,80 @@
+<html devsite>
+ <head>
+ <title>Kernel</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>The Linux kernel is an extremely important part of the software on nearly
+every Android device. This section describes Linux kernel development and
+release models (below),
+<a href="/devices/architecture/kernel/releases.html">stable and long-term
+supported (LTS) kernels</a> (including why all Android devices should use stable
+releases instead of cherry picking patches), kernel
+<a href="/devices/architecture/kernel/config.html">configuration</a> and
+<a href="/devices/architecture/kernel/hardening.html">hardening</a>,
+requirements for
+<a href="/devices/architecture/kernel/reqs-interfaces.html">interfaces</a> and
+the
+<a href="/devices/architecture/kernel/modular-kernels.html">modular kernels</a>
+(introduced in Android O), kernel
+<a href="/devices/architecture/kernel/lldb-debug.html">debugging</a> and
+<a href="/devices/architecture/kernel/network_tests.html">network testing</a>,
+and <a href="/devices/architecture/kernel/squashfs.html">SquashFS</a>.</p>
+
+<h2 id="linux-kernel-development">Linux kernel development</h2>
+<p>
+The Linux kernel is the largest collaborative software project ever. In 2016,
+over 4,000 different developers from over 450 different companies contributed to
+the project and there were 6 releases, each containing between 12,000 and 16,000
+different changes. At the end of 2016 the size of the Linux kernel was just over
+56 thousand files, consisting of 22 million lines of code, build scripts, and
+documentation (kernel release 4.9). (For full Linux development statistics,
+refer to
+<a href="https://kernelnewbies.org/DevelopmentStatistics" class="external">https://kernelnewbies.org/DevelopmentStatistics</a>.)
+</p>
+<p>
+While the Linux kernel contains code for all the different chip architectures
+and hardware drivers it supports, an individual system runs only a fraction of
+the codebase. An average laptop uses around 2 million lines of kernel code from
+5 thousand files to function properly, while the Pixel phone uses 3.2 million
+lines of kernel code from 6 thousand files (due to the increased complexity of
+an SoC).
+</p>
+
+<h2 id="linux-kernel-releases">Linux kernel releases</h2>
+<p>The Linux kernel uses a release model that differs substantially from
+standard AOSP releases. With the release of the 2.6 kernel in December of 2003,
+the kernel developer community switched from the previous model of having a
+separate development and stable kernel branch, and moved to a <em>stable
+only</em> branch model. In this model, a new release occurred every 2 to 3
+months, and that release was declared <em>stable</em> and recommended for all
+users to run. This change in development model was due to the very long
+release cycle prior to the 2.6 kernel (almost 3 years), and the struggle to
+maintain two different branches of the codebase at the same time.</p>
+
+<p>The numbering of the kernel releases began at 2.6.x, where x was an
+incrementing number that changed on every release (the value of the number has
+no meaning, other than it is newer than the previous kernel release). The kernel
+version since then has now moved to 4.x accounting for 2 major version changes.
+These version numbers are chosen by the maintainer(s) only to avoid confusion
+among users caused by higher minor release numbers.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/kernel/lldb-debug.html b/en/devices/architecture/kernel/lldb-debug.html
new file mode 100644
index 00000000..0c019fd5
--- /dev/null
+++ b/en/devices/architecture/kernel/lldb-debug.html
@@ -0,0 +1,110 @@
+ <html devsite>
+ <head>
+ <title>Kernel Enhancements to LLDB/C++ Debugging</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>
+The Android 8.0 release includes kernel enhancements that help developers create
+better applications by improving their debugging experience.
+</p>
+<p>
+The arm64 Android kernels support setting watchpoints on memory addresses that
+are not 4/8-byte aligned, and reporting all accesses to those addresses.
+</p>
+<h2 id="implementation">Implementation</h2>
+<p>
+The feature runs on any ARM 64-bit device. Adding the relevant support for
+32-bit hardware/kernels is optional. All necessary kernel modifications have
+already been done.
+</p>
+<p>
+This feature is included in the current 3.10, 3.18, 4.4, and 4.9 kernel branches.
+To add it to a kernel that does not already include it, cherry pick the
+necessary CLs into your kernel build. Choose the patchset according to the
+version your kernel is based on, as the patches required some adjustments due to
+the kernel codebase evolving over time:
+</p>
+
+<ul>
+ <li>branch android-3.10:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/bb42e87236d9defb511819991df21d464c1ef2eb">https://android.googlesource.com/kernel/common/+/bb42e87236d9defb511819991df21d464c1ef2eb</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/e8e0018306e1b9426dd70b44f057d1555c212ffb">https://android.googlesource.com/kernel/common/+/e8e0018306e1b9426dd70b44f057d1555c212ffb</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/fc0e9d5d77d9368ab15a06f7e61fff2ae2bc254d">https://android.googlesource.com/kernel/common/+/fc0e9d5d77d9368ab15a06f7e61fff2ae2bc254d</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/482ff2ca45737ee4bab3cf7221f6df1c9e14ea2c">https://android.googlesource.com/kernel/common/+/482ff2ca45737ee4bab3cf7221f6df1c9e14ea2c</a>
+ </ul>
+
+ <li>branch android-3.18:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/b14849ae202487251b91e9f89af7eda484a80489">https://android.googlesource.com/kernel/common/+/b14849ae202487251b91e9f89af7eda484a80489</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/58a9c1be1966ca89facba6343a5d8781154196b7">https://android.googlesource.com/kernel/common/+/58a9c1be1966ca89facba6343a5d8781154196b7</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/d34d016794f345c5f1dccf4060b1132439098699">https://android.googlesource.com/kernel/common/+/d34d016794f345c5f1dccf4060b1132439098699</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/c82e0fdadfba89cdb50c96af622c2c5ad6cb55eb">https://android.googlesource.com/kernel/common/+/c82e0fdadfba89cdb50c96af622c2c5ad6cb55eb</a>
+ </ul>
+
+ <li>branch android-4.4:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/91495bc622e9356dd63a7c77b98a21f0e2f5d2b2">https://android.googlesource.com/kernel/common/+/91495bc622e9356dd63a7c77b98a21f0e2f5d2b2</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/7409857a0717fa78dc936ea08099880be893156c">https://android.googlesource.com/kernel/common/+/7409857a0717fa78dc936ea08099880be893156c</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/b48318f371e8a8b98238deac868bc7af8ed8ba4b">https://android.googlesource.com/kernel/common/+/b48318f371e8a8b98238deac868bc7af8ed8ba4b</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/edc166a8714b012a3dd207e437c772ae2a264eca">https://android.googlesource.com/kernel/common/+/edc166a8714b012a3dd207e437c772ae2a264eca</a>
+ </ul>
+
+ <li>branch android-4.9:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/85c450ac7ac0a69aca4c6eb845e419ae092d8c86">https://android.googlesource.com/kernel/common/+/85c450ac7ac0a69aca4c6eb845e419ae092d8c86</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/67de4de5628a47fa794920745dc7869c97b558d3">https://android.googlesource.com/kernel/common/+/67de4de5628a47fa794920745dc7869c97b558d3</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/32649b0a393303a97fab6003c5757ff7b100331a">https://android.googlesource.com/kernel/common/+/32649b0a393303a97fab6003c5757ff7b100331a</a>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/d32793b6be517dffa29329a92ffcc688e74bc690">https://android.googlesource.com/kernel/common/+/d32793b6be517dffa29329a92ffcc688e74bc690</a></li>
+ </ul>
+</ul>
+
+<p>
+This feature implements an extension of the <code>ptrace</code> API to support
+writing a debugger.
+</p>
+<h2 id="validation">Validation</h2>
+<p>
+There is a kernel selftest in the upstream repository, a CTS test, and there
+are CTS tests added exercising the new kernel API:
+</p>
+<p>
+<a
+href="https://android.googlesource.com/platform/bionic/+/master/tests/sys_ptrace_test.cpp">https://android.googlesource.com/platform/bionic/+/master/tests/sys_ptrace_test.cpp</a>
+</p>
+</body>
+</html>
diff --git a/en/devices/architecture/kernel/modular-kernels.html b/en/devices/architecture/kernel/modular-kernels.html
new file mode 100644
index 00000000..98ac0528
--- /dev/null
+++ b/en/devices/architecture/kernel/modular-kernels.html
@@ -0,0 +1,751 @@
+<html devsite>
+ <head>
+ <title>Modular Kernel Requirements</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>In Android O, the device kernel splits into System-on-Chip (SoC), device, and
+board-specific deliverables. This sets up the kernel and Android such that
+Original Device Manufacturers (ODMs) and Original Equipment Manufacturers (OEMs)
+can work in isolated board–specific trees for board–specific features, drivers,
+etc., enabling them to override common kernel configuration, add new drivers in
+the form of kernel modules, etc.</p>
+
+<p>This page provides details on requirements for:</p>
+
+<ul>
+<li>Platform support for independent SoC and OEM/ODM kernel development. Android
+O recommends all board–specific code to be built and shipped as kernel modules
+in devices. As a result:
+ <ul>
+ <li>All platforms should support either
+ <a href="https://www.devicetree.org/" class="external">Device Tree</a> or
+ <a href="http://www.uefi.org/acpi/specs" class="external">Advanced
+ Configuration and Power Interface (ACPI)</a> to describe all non-discoverable
+ devices.</li>
+ <li>For device tree-based platforms, board–specific device nodes should be
+ added to the kernel device tree as
+ <a href="/devices/architecture/dto/index.html">overlays</a>.</li>
+ </ul>
+</li>
+<li>Application binary interface (ABI)/application programming interface (API)
+tests in <a href="/devices/tech/vts/index.html">Vendor Test Suite (VTS)</a> to
+ensure a given kernel can run the Android Open Source Project (AOSP)
+framework.</li>
+<li>Minimum kernel version per Android release and support for generating
+<a href="/devices/architecture/vintf/index.html">Android Vendor Interface
+(VINTF) kernel objects</a>.</li>
+</ul>
+
+<h2 id="loadable-kernel-modules">Loadable kernel modules</h2>
+<p>All SoC kernels should support loadable kernel modules. As a starting point,
+the following kernel-config options (or their kernel-version equivalent) have
+been added to
+<a href="https://android.googlesource.com/kernel/common/+/android-4.4/android/configs/android-base.cfg" class="external">android-base.cfg</a>
+in all common kernels and must be enabled in all device kernels:</p>
+
+<pre class="prettyprint">
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+</pre>
+
+<p>All kernel modules are subject to module load/unload testing to ensure the
+correctness of the driver/module.</p>
+
+<aside class="note"><strong>Note:</strong>
+<code>CONFIG_MODULE_SRCVERSION_ALL</code> is optional and will not be tested
+against.</aside>
+
+<h3 id="module-signing">Module signing</h3>
+<p>Optionally, ODMs can enable module signing in their own kernel configuration
+by enabling following kernel config options:</p>
+
+<pre class="prettyprint">
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
+</pre>
+
+<p>On devices required to support verified boot, Android requires the kernel
+modules to be in the partitions that have dm-verity enabled. Module signing is
+not mandatory and will not be tested against; however, if desired, an ODM can
+enable module signing as long as they have the key signing and other
+infrastructure required to ensure independent kernel and filesystem OTA updates
+in the future.</p>
+
+<h3 id="file-locations">File locations</h3>
+<p>While Android 7.x and earlier do not mandate against kernel modules (and
+include support for <code>insmod</code> and <code>rmmod</code>), Android O
+recommends the use of kernel modules in the ecosystem. The following table shows
+potential board–specific peripheral support required across three Android boot
+modes:</p>
+
+<table>
+<tr>
+<th>Boot Mode</th>
+<th>Storage</th>
+<th>Display</th>
+<th>Keypad</th>
+<th>Battery</th>
+<th>PMIC</th>
+<th>Touchscreen</th>
+<th>NFC, Wi-Fi,<br>Bluetooth</th>
+<th>Sensors</th>
+<th>Camera</th>
+</tr>
+<tr>
+<td>Recovery</td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-no"></span></td>
+<td><span class="compare-no"></span></td>
+<td><span class="compare-no"></span></td>>
+<td><span class="compare-no"></span></td>
+</tr>
+<tr>
+<td>Charger</td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-no"></span></td>
+<td><span class="compare-no"></span></td>
+<td><span class="compare-no"></span></td>
+<td><span class="compare-no"></span></td>
+</tr>
+<tr>
+<td>Android</td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+<td><span class="compare-yes"></span></td>
+</tr>
+</table>
+
+<p>In addition to availability in Android boot modes, kernel modules may also be
+categorized by who owns them (the SoC vendor or the ODM). If kernel modules are
+being used, requirements for their placement in filesystem are as follows:</p>
+
+<ul>
+<li>All kernels should have built-in support for booting and mounting partitions.
+</li>
+<li>Kernel modules should be loaded from a read-only partition.</li>
+<li>For devices required to have verified boot, kernel modules should be loaded
+from verified partitions.</li>
+<li>Kernel modules should not be located in <code>/system</code>.</li>
+<li>Kernel modules from the SoC vendor that are required for full Android or
+Charger modes should be located in <code>/vendor/lib/modules</code>.</li>
+<li>If an ODM partition exists, kernel modules from the ODM that are required
+for full Android or Charger modes should be located in
+<code>/odm/lib/modules</code>. Otherwise, these modules should be located in
+<code>/vendor/lib/modules</code>.</li>
+<li>Kernel modules from both the SoC vendor and ODM that are required for
+Recovery mode should be located in the recovery <code>ramfs</code> at
+<code>/lib/modules</code>.</li>
+<li>If a kernel module is required for both Recovery mode and full Android or
+Charger modes, it should exist both in the recovery <code>rootfs</code> and
+either the <code>/vendor</code> or <code>/odm<strong> </strong></code>partitions
+(as described above).</li>
+<li>Kernel modules used in Recovery mode should not depend on modules located
+only in <code>/vendor</code> or <code>/odm</code>, as those partitions are not
+mounted in Recovery mode.</li>
+<li>SoC vendor kernel modules should not depend on ODM kernel modules.</li>
+</ul>
+
+<p>In Android 7.x and earlier, <code>/vendor</code> and <code>/odm</code>
+partitions are <strong>not</strong> mounted early. In Android O, to make module
+loading from these partitions possible, provisions have been made to mount
+partitions early for both
+<a href="https://source.android.com/devices/tech/ota/ab_updates">non-A/B and A/B
+devices</a>. This also ensures the partitions are mounted in both Android and
+Charger modes.</p>
+
+<h3 id="android-build-system-support">Android build system support</h3>
+<p>In <code>BoardConfig.mk</code>, the Android build defines a
+<code>BOARD_VENDOR_KERNEL_MODULES</code> variable that provides a full list of
+the kernel modules intended for the vendor image. The modules listed in this
+variable are copied into the vendor image at <code>/lib/modules/</code>, and,
+after being mounted in Android, appear in <code>/vendor/lib/modules</code> (in
+accordance with the above requirements). Example configuration of the vendor
+kernel modules:</p>
+
+<pre class="prettyprint">
+vendor_lkm_dir := device/$(vendor)/lkm-4.x
+BOARD_VENDOR_KERNEL_MODULES := \
+ $(vendor_lkm_dir)/vendor_module_a.ko \
+ $(vendor_lkm_dir)/vendor_module_b.ko \
+ $(vendor_lkm_dir)/vendor_module_c.ko
+</pre>
+
+<p>… where a vendor kernel module pre-built repository is mapped into the
+Android build at the location listed above.</p>
+
+<p>The recovery image is likely to contain a subset of the vendor modules. The
+Android build defines the variable <code>BOARD_RECOVERY_KERNEL_MODULES</code>
+for these modules. Example:</p>
+
+<pre class="prettyprint">
+vendor_lkm_dir := device/$(vendor)/lkm-4.x
+BOARD_RECOVERY_KERNEL_MODULES := \
+ $(vendor_lkm_dir)/vendor_module_a.ko \
+ $(vendor_lkm_dir)/vendor_module_b.ko
+</pre>
+
+<p>The Android build takes care of running <code>depmod</code> to generate the
+required <code>modules.dep</code> files in <code>/vendor/lib/modules</code> and
+<code>/lib/modules</code> (<code>recovery ramfs</code>).</p>
+
+<h3 id="module-loading-&-versioning">Module loading &amp; versioning</h3>
+<p>We recommend loading all kernel modules in one pass from
+<code>init.rc*</code> by invoking <code>modprobe -a</code>. This avoids the
+overhead of repeatedly initializing the C runtime environment for the
+<code>modprobe</code> binary. The <code>early-init</code> event can be modified
+to invoke <code>modprobe</code>:</p>
+
+<pre class="prettyprint">
+on early-init
+ exec u:r:modprobe:s0 -- /vendor/bin/modprobe -a -d \
+ /vendor/lib/modules module_a module_b module_c ...
+</pre>
+
+<p>The kernel image may be updated separately from the vendor image, meaning
+that kernel modules may be used with kernels other than the one they were
+originally compiled against. To allow for this, and to protect against ABI
+breakages, module versioning is used. Module versioning is enabled by
+<code>CONFIG_MODVERSIONS=y</code> (one of the required kernel configuration
+options mentioned above) and is documented in the kernel tree at
+<code>Documentation/kbuild/modules.txt</code>.</p>
+
+<h2 id="mounting-partitions-early-first-stage-mount">Mounting partitions early
+(first stage mount)</h2>
+<font style="font-family: Roboto, Arial, Helvetica, sans-serif; background-color: green; color: white">&nbsp;REQUIRED&nbsp;</font>
+<p>All Treble-enabled devices must enable first stage mount to make sure
+<code>init</code> can load SELinux policy fragments that are spread across
+<code>system</code> and <code>vendor</code> partitions (this also enables
+loading of kernel modules as soon as possible after kernel boot).</p>
+
+<aside class="note"><strong>Note:</strong> For details on SELinux in Android
+8.0, see <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for
+Android 8.0</a>.</aside>
+
+<p>Android must have access to the filesystem(s) on which the modules reside. To
+enable, Android O supports mounting <code>/system</code>, <code>/vendor</code>,
+or <code>/odm</code> as early as <code>init</code>'s first stage (i.e before
+selinux is initialized). Device makers can use
+<a href="/devices/architecture/dto/index.html">device tree overlays</a> to
+specify <code>fstab</code> entries for early mounted partitions.</p>
+
+<aside class="key-point"><strong>Summary of AOSP early mount changes:</strong>
+<ul>
+<li>
+<a href="https://android-review.googlesource.com/#/q/topic:pre-early-mount" class="external">Pre-early
+mount v1</a> &amp;
+<a href="https://android-review.googlesource.com/#/q/status:merged+project:platform/system/core+branch:master+topic:pre-early-mount-2" class="external">v2</a></li>
+<li><a href="https://android-review.googlesource.com/#/c/339471/" class="external">Miscellaneous
+partition lookup removal</a></li>
+<li>
+<a href="https://android-review.googlesource.com/#/q/branch:master+topic:early-mount-support" class="external">Early
+mount support</a></li>
+<li>
+<a href="https://android-review.googlesource.com/#/q/branch:master+topic:early-mount-support" class="external">Early
+mount with VBoot 2.0 (AVB)</a></li>
+</ul>
+</aside>
+
+<h3 id="early-mounting-partitions-vboot-1-0">Early mounting partitions, VBoot
+1.0</h3>
+<p>Requirements to early mount partitions with vboot 1.0 include:</p>
+<ol>
+<li>Device node paths must use their <em>by-name</em> symlinks in
+<code>fstab</code> and device tree entries. For example, instead of specifying
+partitions using <code>/dev/block/mmcblk0pX</code>, ensure partitions are named
+and the device node is <code>/dev/block/…./by-name/{system,vendor,odm}</code>.
+</li>
+<li>Paths given for <code>PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION</code> and
+<code>CUSTOM_IMAGE_VERITY_BLOCK_DEVICE</code> in the device configuration for
+the product (i.e. in
+<code>device/<em>oem</em>/<em>project</em>/device.mk</code>) must match the
+corresponding block device nodes specified <em>by-name</em> in the
+<code>fstab</code>/device tree entries. Example:
+<pre class="prettyprint">
+PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/…./by-name/system
+PRODUCT_VENDOR_VERITY_PARTITION := /dev/block/…./by-name/vendor
+CUSTOM_IMAGE_VERITY_BLOCK_DEVICE := /dev/block/…./by-name/odm
+</pre>
+</li>
+<li>Entries provided via device tree overlays must not repeat in the
+<code>fstab</code> file fragments. For example, when specifying an entry to
+mount <code>/vendor</code> in the device tree, the <code>fstab</code> file must
+not repeat that entry.</li>
+<li>Only <code>/system</code>, <code>/odm</code>, or <code>/vendor</code> can be
+mounted early. Android does not include support to mount any other partitions in
+<code>init</code> first stage.</li>
+<li>Partitions requiring <code>verifyatboot</code> <strong>must not</strong> be
+early mounted (doing so is unsupported).</li>
+<li>The verity mode/state for verified partitions must be specified in kernel
+cmdline using <code>androidboot.veritymode</code> option (existing
+requirement).</li>
+</ol>
+
+<h3 id="early-mounting-device-tree-vboot-1-0">Early mounting device tree, VBoot
+1.0</h3>
+<p>In Android O, <code>init</code> parses the device tree and creates
+<code>fstab</code> entries to mount the partition early during its first stage.
+An fstab entry takes the form:</p>
+
+<pre class="prettyprint">src mnt_point type mnt_flags fs_mgr_flags</pre>
+
+<p>Device tree properties are defined to mimic that format:</p>
+
+<ul>
+<li><code>fstab</code>entries must be under <code>/firmware/android/fstab</code>
+in the device tree and must have compatible string set to
+<code>android,fstab</code>. </li>
+<li>Each node under <code>/firmware/android/fstab</code> is treated as a single
+early mount <code>fstab</code> entry. A node must have the following properties
+defined:
+ <ul>
+ <li><code>dev</code>. Must point to the device node representing the
+ partition <em>by-name</em>.</li>
+ <li><code>type</code>. Must be the filesystem type (as in the
+ <code>fstab</code> files).</li>
+ <li><code>mnt_flags</code>. Must be the comma-separated list of mount
+ flags (as in <code>fstab</code> files).</li>
+ <li><code>fsmgr_flags</code>. Must be the list of Android <code>fs_mgr
+ flags</code> (as in <code>fstab</code> files).
+ <ul>
+ <li>A/B partitions must have <code>slotselect fs_mgr</code>option.</li>
+ <li>dm-verity enabled partitions must have <code>verify fs_mgr</code> option.
+ </li>
+ </ul>
+ </li>
+ </ul>
+</li>
+</ul>
+
+<h4><strong>Example:</strong> /system and /vendor on N6P</h4>
+<p>The following example shows device tree early mount for <code>system</code>
+and <code>vendor</code> partitions on Nexus 6P:</p>
+
+<pre class="prettyprint">
+/ {
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait,verify";
+ };
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait";
+ };
+ };
+ };
+ };
+};
+</pre>
+
+<h4><strong>Example:</strong> /vendor on Pixel</h4>
+<p>The following example shows device tree early mount for
+<code>/vendor</code> on Pixel (remember to add <code>slotselect</code> for
+partitions subject to A/B):</p>
+
+<pre class="prettyprint">
+/ {
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,slotselect,verify";
+ };
+ };
+ };
+ };
+};
+</pre>
+
+<h3 id="early-mounting-partitions-vboot-2-0">Early mounting partitions, VBoot
+2.0</h3>
+<p>VBoot 2.0 is
+<a href="https://android.googlesource.com/platform/external/avb/" class="external">Android
+Verified Boot (AVB).</a> The requirements to early mount partitions with VBoot
+2.0 are:</p>
+<ol>
+<li>The device node paths must use their <em>by-name</em> symlinks in
+<code>fstab</code> and device tree entries. For example, instead of specifying
+partitions using <code>/dev/block/mmcblk0pX</code>, ensure the partitions are
+named and the device node is
+<code>/dev/block/…./by-name/{system,vendor,odm}</code>.</li>
+<li>Build system variables (such as
+<code>PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION</code> and
+<code>CUSTOM_IMAGE_VERITY_BLOCK_DEVICE</code>) used for VBoot 1.0 are NOT
+required for VBoot 2.0. Instead, new build variables introduced in VBoot 2.0
+(including <code>BOARD_AVB_ENABLE := true</code>) should be defined; for a full
+configuration, refer to
+<a href="https://android.googlesource.com/platform/external/avb/#Build-System-Integration" class="external">Build-System-Integration
+for AVB</a>.</li>
+<li>Entries provided via device tree overlays must not repeat in the
+<code>fstab</code> file fragments. For example, if you specify an entry to mount
+<code>/vendor</code> in the device tree, the <code>fstab</code> file must not
+repeat that entry.</li>
+<li>Only <code>/system</code>, <code>/odm</code>, or <code>/vendor</code> can be
+mounted early. Android does not include support to mount any other partitions in
+<code>init</code> first stage.</li>
+<li>VBoot 2.0 does not support <code>verifyatboot</code>, regardless of whether
+early mount is enabled or not.</li>
+<li>The verity mode/state for verified partitions must be specified in kernel
+cmdline using <code>androidboot.veritymode</code> option (existing requirement).
+Make sure to include the following fixes for AVB:
+ <ul>
+ <li>
+ <a href="https://android-review.googlesource.com/#/q/topic:libavb-api-rev-for-verity-modes+(status:open+OR+status:merged)" class="external">https://android-review.googlesource.com/#/q/topic:libavb-api-rev-for-verity-modes+(status:open+OR+status:merged)</a></li>
+ <li>
+ <a href="https://android-review.googlesource.com/#/c/394215/" class="external">https://android-review.googlesource.com/#/c/394215/</a></li>
+ </ul>
+</li>
+</ol>
+
+<h3 id="early-mounting-device-tree-vboot-2-0">Early mounting device tree, VBoot
+2.0</h3>
+<p>The configuration in device tree for VBoot 2.0 is the same as that in
+<a href="#early-mounting-device-tree-vboot-1-0">VBoot 1.0</a>, with the
+following exceptions:</p>
+<ul>
+<li>The <code>fsmgr_flag</code> is switched from <code>verify</code> to
+<code>avb</code>.</li>
+<li>All partitions with AVB metadata must be in the vbmeta entry in device tree,
+even when the partition isn't mounting early (e.g., <code>/boot</code>).</li>
+</ul>
+
+<h4><strong>Example:</strong> /system and /vendor on N5X</h4>
+<p>The following example shows device tree early mount for <code>system</code>
+and <code>vendor</code> partitions on Nexus 5X. Note that:</p>
+<ul>
+<li><code>/system</code> is mounted with AVB and <code>/vendor</code> is mounted
+without integrity verification.</li>
+<li>As the Nexus 5X has no <code>/vbmeta</code> partition, so the top-level
+vbmeta resides at the end of <code>/boot</code> partition (for details, refer to
+the
+<a href="https://android-review.googlesource.com/#/c/344907/" class="external">AOSP
+changelist</a>).
+
+<pre class="prettyprint">
+/ {
+ firmware {
+ android {
+ compatible = "android,firmware";
+ vbmeta {
+ compatible = "android,vbmeta";
+ parts = "boot,system,vendor";
+ };
+ fstab {
+ compatible = "android,fstab";
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait,avb";
+ };
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
+ fsmgr_flags = "wait";
+ };
+ };
+ };
+ };
+};
+</pre>
+</li>
+</ul>
+
+<h4><strong>Example:</strong> /vendor on Pixel</h4>
+<p>The following example shows mounting <code>/vendor</code> early on a Pixel.
+Note that:</p>
+
+<ul>
+<li>More partitions are specified in the vbmeta entry because those partitions
+are
+<a href="https://android.googlesource.com/platform/external/avb/#The-VBMeta-struct">protected
+by AVB.</a></li>
+<li>All AVB partitions must be included, even if only <code>/vendor</code> is
+early mounted.</li>
+<li>Remember to add <strong><code>slotselect</code></strong> for partitions
+subject to A/B.
+<pre class="prettyprint">
+/ {
+ vbmeta {
+ compatible = "android,vbmeta";
+ parts = "vbmeta,boot,system,vendor,dtbo";
+ };
+ firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,slotselect,avb";
+ };
+ };
+ };
+ };
+};
+</pre>
+</li>
+</ul>
+
+<h2 id="device-tree-overlay-support-bootloader">Device tree overlay support
+(Bootloader)</h2>
+<p>
+<a href="https://lkml.org/lkml/2012/11/5/615">Device Tree Overlay</a> (DTO) was
+designed to extend the existing
+<a href="https://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf" class="external">flattened
+device-tree (FDT)</a> implementation so that the initial device-tree data in
+kernel can be modified by userspace at runtime by loading additional overlay
+FDTs that amend the original data. Android does not require runtime updates of
+DT blobs from user space, but instead recommends that vendors add the device
+tree patching in the bootloader with the help of
+<code>libfdt</code>/<code>libufdt</code>.</p>
+
+<p>In Android 7.x and earlier, Android did not require device tree support and
+did not provide recommendations regarding how vendors pass DT blobs to the
+kernel or where they store them. Android O recommends such support to keep the
+board–specific and SoC-only parts of the kernel separate.</p>
+
+<h3 id="partitioning-requirements">Partitioning requirements</h3>
+<p>Most Android devices today append the DT blob to the kernel at build time,
+which the bootloader knows how to read from. As Android has no specific
+requirements for how to build/store DT blobs (which is considered as part of the
+SoC kernel), the DT blob can be appended to the kernel or stored in a separate
+partition. The only assumption is that the bootloader already knows how and
+where to load the DT blob from.</p>
+
+<p>Requirements for Device Tree Overlay support (if used):</p>
+<ul>
+<li>Device should have new device tree blob for overlay (DTBO) partion per
+kernel image for board–specific DT overlay (for details on the partition format,
+see <a href="/devices/architecture/dto/partitions.html">DTB/DTBO Partitions</a>.
+The assumption is that bootloader already knows where and how to load the
+SoC–specific DTB.</li>
+<li>Overlay DT partition should be
+<a href="https://source.android.com/devices/tech/ota/ab_updates.html">A/B-ed</a>
+for A/B devices. For these devices, the recovery kernel is the same as Android
+kernel, but the partition must be A/B-ed as it can be updated via OTA.</li>
+<li>Partition size is board–specific.
+ <ul>
+ <li>The DT overlay partition size depends on the device and the amount of
+ changes needed on top of the main SoC kernel DT blob.</li>
+ <li>The size of the DTBO partition is a function of number of changes needed to
+ make the SoC kernel. Choose a size with room to grow for future updates
+ (typically, 8MB partition size is more than enough).</li>
+ </ul>
+</li>
+</ul>
+
+<h3 id="bootloader-requirements">Bootloader requirements</h3>
+<p>Requirements for bootloader include the following:</p>
+<ul>
+<li>Bootloader should know how and where (considering the boot slot for A/B
+devices) to load the SoC–specific DT blob from in a vendor-specific way. This is
+typically extracted from the end of the kernel image as blobs are appended to
+the kernel.</li>
+<li>Bootloader should know how and where (considering the boot slot for A/B
+devices) to load the overlay DT blob from in a vendor-specific way.</li>
+<li>Bootloader must patch the main DT blob with the overlay before passing the
+combined device tree to the kernel.</li>
+</ul>
+
+<p>For more details about adding support for DTO in bootloader, see
+<a href="/devices/architecture/dto/index.html">Device Tree Overlays</a>.</p>
+
+<h2 id="core-kernel-requirements">Core kernel requirements</h2>
+<p>Android O mandates a minimum kernel version and kernel configuration and
+checks them both in VTS as well as during an OTA. Android device kernels must
+enable the kernel <code>.config</code> support along with the option to read the
+kernel configuration at runtime through <code>procfs</code>.</p>
+
+<h3 id="kernel-config-support">Kernel .config support</h3>
+<p>All device kernels must enable the entirety of
+<a href="https://android.googlesource.com/kernel/common/+/android-4.4/android/configs/android-base.cfg" class="external">android-base.cfg</a>,
+which must include the following kernel–config options (or their kernel–version
+equivalent):</p>
+
+<pre class="prettyprint">
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+</pre>
+
+<h3 id="kernel-version">Kernel version</h3>
+<p>Kernel version requirements:</p>
+<ul>
+<li>All SoCs productized in 2017 must launch with kernel 4.4 or newer.</li>
+<li>All other SoCs launching new Android devices running Android O must use
+kernel 3.18 or newer.</li>
+<li>Regardless of launch date, all SoCs with device launches on Android O remain
+subject to kernel changes required to enable Treble.</li>
+<li>Older Android devices released prior to Android O but that will be upgraded
+to Android O can continue to use their original base kernel version if
+desired.</li>
+</ul>
+
+<h3 id="device-tree-support">Device tree support</h3>
+<p>Device tree support in the kernel must be enabled and bootloaders must pass
+the hardware description in the form of device tree to the kernel (unless the
+platform supports ACPI). The device tree must also be available for Android to
+read and be able to pass vendor/odm specific parameters to Android.
+<code>CONFIG_OF</code> (along with all other device/subsystem specific
+<code>CONFIG_OF_*</code> kernel config options) are mandatory.</p>
+
+<p><code>CONFIG_PROC_DEVICETREE</code> is required on kernels prior to 3.15 so
+Android can access vendor/odm specific configuration very early during boot. On
+kernels 3.15 and later, the functionality of this option is merged into
+<code>CONFIG_OF</code>.</p>
+
+<pre class="prettyprint">
+CONFIG_OF=y
+CONFIG_PROC_DEVICETREE=y (kernels prior to 3.15)
+</pre>
+
+<p>For an example of using device tree to early mount
+<code>vendor</code>/<code>odm</code> partitions, refer to the
+<a href="https://android-review.googlesource.com/#/c/337310/" class="external">AOSP
+changelist</a>.</p>
+
+<h3 id="debugfs">DebugFS</h3>
+<p>The implementation of the vendor interface should not rely on
+<code>debugfs</code>. It may be enabled, but VTS testing may be done with
+<code>debugfs</code> unmounted.</p>
+
+<h2 id="beyond-android-o">Beyond Android O</h2>
+<p>Android O recommends any board–specific kernel functionality to be in the
+form of loadable kernel modules and device–tree overlays. The rest of the kernel
+is treated monolithically with respect to Android (whether or not is it is
+actually a monolithic kernel, or parts of it are compiled as kernel modules).
+</p>
+
+<p>This monolithic kernel is an SoC kernel that can boot on the SoC vendor's
+reference hardware but nothing beyond that. Today, SoC kernels are treated
+similar to the common kernel; they are also heavily replicated in board–specific
+repos. This distribution model causes them to be fixed differently for the same
+bug in each branch, delaying future updates to the kernel due to cherry–picking
+at different times or fixing the same bug differently. To counter this, the SoC
+kernels must be a separate deliverable, with everyone who uses the SoC
+contributing to the same SoC kernel.</p>
+
+<p>Figure 1 (below) illustrates a common example of how SoC kernels get
+fragmented over time, across Android releases, and across ODMs.</p>
+
+<img src="../images/treble_kernel_current.png">
+<figcaption><strong>Figure 1.</strong> Device kernel replication.</figcaption>
+
+<p>Figure 1 shows the following:</p>
+<ol>
+<li>It takes a significant amount of effort and time for everyone to cross-merge
+across board–specific branches/tags.</li>
+<li>While waiting for the cross-merge, Android device manufacturers patch their
+own kernel for bugs/security fixes.</li>
+<li>Divergence from the ancestor make future upgrades/merges really
+difficult.</li>
+</ol>
+<p>The proposed model for a common SoC kernel addresses problems created by
+upmerging changes (SoC-specific bug fixes, LTS upgrades, security fixes, etc.).
+Figure 2 (below) illustrates how the workflow will change in an ideal,
+unified–per–SoC–kernel scenario:</p>
+
+<img src="../images/treble_kernel_treble.png">
+<figcaption><strong>Figure 2.</strong> Android O and higher device
+kernels.</figcaption>
+
+<p>This is intended to solve the problem of fragmented kernel repos by
+recommending and working with device manufacturers to stay up to date with the
+common SoC kernel. Android O provides all possible options to ODMs to help them
+avoid maintaining their own SoC kernels and instead rely on the common SoC
+kernel for LTS upgrades/bug fixes/security patches/etc.</p>
+
+<p>As a start, we want to facilitate all ODMs/vendors using a single kernel
+source for an SoC. In the future, we want to move towards a single binary
+distribution of kernel per-SoC.</p>
+
+<h3 id="upstreaming">Upstreaming</h3>
+<p>To make updating to newer kernel versions much easier and almost automatic,
+and to provide a more secure and reliable platform for ODMs to build a product
+with, it is strongly recommended that SoC vendors work to upstream their kernel
+changes and get them accepted into the main kernel.org repository. While doing
+so requires additional, up front efforts in time and engineering resources, it
+is well documented to save both time and money in the long run. It has also been
+documented that merged code is of a much higher quality with fewer bugs and
+security issues (and usually smaller) than code that has not been reviewed by
+the community.</p>
+
+<p>If full support for the SoC is merged upstream, the community can make needed
+API changes as the internal kernel API evolves over time, automatically
+extending the longevity of the platform. The kernel can also be automatically
+tested for any regressions in development and stable releases by adding the
+hardware platform to one of the many community-managed kernel test platforms
+(such as
+<code><a href="https://kernelci.org" class="external">kernelci.org</a></code>).
+</p>
+
+<p>For help working with the Linux kernel community to upstream your code, refer
+to the following resources:</p>
+<ul>
+<li><code>Documentation/process</code>
+(<code>Documentation/development-process</code> in 4.9 and earlier)</li>
+<li><code>Documentation/CodingStyle</code></li>
+<li><code>Documentation/SubmittingPatches</code></li>
+</ul>
+
+<p>The community uses a minimal review process to accept stand-alone drivers and
+filesystems into the staging portion of the kernel, where the community works to
+improve code quality.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/kernel/releases.html b/en/devices/architecture/kernel/releases.html
new file mode 100644
index 00000000..612922d9
--- /dev/null
+++ b/en/devices/architecture/kernel/releases.html
@@ -0,0 +1,180 @@
+<html devsite>
+ <head>
+ <title>Stable Kernel Releases &amp; Updates</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>
+The Linux kernel stable release model started in 2005, when it was determined
+that the existing kernel development model (a new release every 2-3 months) was
+not meeting the needs of most users. Users wanted bugfixes made during those 2-3
+months, and Linux distributions found it difficult to keep kernels up to date
+without feedback from the kernel community. In general, attempts to keep
+individual kernels secure and with the latest bugfixes was a large and confusing
+effort by lots of different individuals.
+</p>
+<p>
+Stable kernel releases are based directly on Linus Torvalds' releases, and are
+released every week or so, depending on various external factors (time of year,
+available patches, maintainer workload, etc.). The numbering of the stable
+releases starts with the number of the kernel release, and an additional number
+is added to the end of it. For example, the 4.4 kernel is released by Linus, and
+then the stable kernel releases based on this kernel are numbered 4.4.1, 4.4.2,
+4.4.3, and so on. This sequence is usually shortened with the number 4.4.y when
+referring to a stable kernel release tree. Each stable kernel release tree is
+maintained by a single kernel developer, who is responsible for picking the
+needed patches for the release and managing the review/release process.
+</p>
+<p>
+Stable kernels are maintained for the length of the current development cycle.
+After Linus releases a new kernel, the previous stable kernel release tree is
+stopped and users must move to the newer released kernel.
+</p>
+
+<h2 id="long-term-stable-kernels">Long-term stable kernels</h2>
+<p>
+After a year of this new stable release process, it was determined that many
+different users of Linux wanted a kernel to be supported for longer than just a
+few months. In response, the Long Term Supported (LTS) kernel release was
+created, with the first LTS kernel (2.6.16) released in 2006. Since then, a new
+LTS kernel has been selected once a year and kernel community maintains that
+kernel for a minimum of 2 years.
+</p>
+<p>At the time of this writing, the LTS kernels are the 4.4.y and 4.9.y
+releases, and a new kernel is released weekly. Due to the needs of some users
+and distributions, a few additional older kernels are maintained by kernel
+developers at a slower release cycle. Information about all long-term stable
+kernels, who is in charge of them, and how long they will be maintained, can be
+found on the
+<a href="https://www.kernel.org/category/releases.html" class="external">kernel.org
+releases</a> page.</p>
+<p>
+LTS kernel releases average 6-8 patches accepted per day, while the normal
+stable kernel releases contain 10-15 patches per day. The number of patches
+fluctuates per release given the current time of the corresponding development
+kernel release, and other external variables. The older a LTS kernel is, the
+less patches are applicable to it as many recent bugfixes are not relevant to
+older kernels. However, the older a kernel is, the harder it is to backport the
+changes that are needed to be applied, due to the changes in the codebase. So
+while there might be a lower number of overall patches being applied, the effort
+involved in maintaining a LTS kernel is greater than maintaining the normal
+stable kernel.
+</p>
+
+<h2 id="stable-kernel-patch-rules">Stable kernel patch rules</h2>
+<p>The rules for what can be added to a stable kernel release have remained
+almost identical since its introduction and are summarized below:</p>
+<ul>
+<li>Must be obviously correct and tested.
+<li>Must not be bigger than 100 lines.
+<li>Must fix only one thing.
+<li>Must fix something that has been reported to be an issue.
+<li>Can be a new device id or quirk for hardware, but not add major new
+functionality.
+<li>Must already be merged into Linus Torvalds' tree.</li>
+</ul>
+<aside class="note"><strong>Note:</strong> For a full list of the rules for
+patches to be accepted into a stable kernel release, refer to the
+<code><a href="https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html" class="external">Documentation/process/stable_kernel_rules.rst</a></code>
+kernel file.</aside>
+
+<p>The last rule, "Must already be merged into Linus Torvalds' tree", prevents
+the kernel community from losing fixes. The community never wants a fix to go
+into a stable kernel release that is not already in Linus Torvalds' tree, so
+that anyone who upgrades should never see a regression. This prevents many
+problems that other projects who maintain a stable and development branch can
+have.</p>
+
+<h2 id="kernel-updates">Kernel updates</h2>
+<p>The Linux kernel community has promised its userbase that no upgrade will
+ever break anything that is currently working in a previous release. That
+promise still holds true today. Regressions do happen, but those are the highest
+priority bugs and are either quickly fixed, or the change that caused the
+regression is quickly reverted from the Linux kernel tree.</p>
+
+<p>This promise holds true for both the incremental stable kernel updates, as
+well as the larger major updates that happen every three months. However, the
+kernel community can only make this promise for the code that is merged into the
+Linux kernel tree. Any code that is merged into a device's kernel that is not in
+the <a href="https://www.kernel.org/">kernel.org</a> releases is unknown and
+interactions with it can never be planned for, or even considered.</p>
+
+<p>Devices based on Linux that have large patch sets can have major issues when
+updating to newer kernels, because of the large number of changes between each
+release (10-14 thousand changes per release). SoC patchsets are especially known
+to have issues with updating to newer kernels due to their large size and heavy
+modification of architecture specific, and sometimes core, kernel code. As a
+result, most SoC vendors are starting to standardize on using the LTS releases
+for their devices, enabling those devices to receive bug and security updates
+directly from the Linux kernel community.</p>
+
+<h2 id="security">Security</h2>
+<p>When doing kernel releases, the Linux kernel community almost never declares
+specific changes as <em>security fixes</em>. This is due to the basic problem of
+the difficulty in determining if a bugfix is a security fix or not at the time
+of creation. Also, many bugfixes are only determined to be security related
+after much time has passed, so the kernel community strongly recommends always
+taking all bugfixes that are released.</p>
+
+<aside class="note"><strong>Note:</strong> For details on Linus Torvalds'
+statement on security fixes, refer to the relevant
+<a href="http://marc.info/?t=121507404600023&r=4&w=2" class="external">email
+thread</a>.</aside>
+
+<p>
+When security problems are reported to the kernel community, they are fixed as
+soon as possible and pushed out publically to the development tree and the
+stable releases. As described above, the changes are almost never described as
+a "security fix", but rather look like any other bugfix for the kernel. This is
+done to allow affected parties the ability to update their systems before the
+reporter of the problem announces it.
+</p>
+
+<p>For details on reporting security bugs to the kernel community to get
+them resolved and fixed as soon as possible, refer to
+<a href="https://www.kernel.org/doc/html/latest/admin-guide/security-bugs.html" class="external">Security
+bugs</a> in <em>The Linux kernel user's and administrator's guide</em> at
+<a href="https://www.kernel.org">www.kernel.org</a>.</p>
+
+<p>
+Because security bugs are not announced to the public by the kernel team, CVE
+numbers for Linux kernel-related issues are usually released weeks, months, and
+sometimes years after the fix was merged into the stable and development
+branches.
+</p>
+<h3 id="keeping-a-secure-system">Keeping a secure system</h3>
+<p>When deploying a device that uses Linux, it is strongly recommended that all
+LTS kernel updates be taken by the manufacturer and pushed out to their users
+after proper testing shows the update works well. This has several advantages:
+</p>
+<ul>
+<li>Releases have been reviewed by the kernel developers as a whole, not in
+individual parts.</li>
+<li>It is hard, if not impossible, to determine which patches fix "security"
+issues and which do not. Almost every LTS release contains at least one known
+security fix, and many yet "unknown".</li>
+<li>If testing shows a problem, the kernel developer community will react
+quickly to resolve the issue.</li>
+<li>Attempts to filter out only the changes you run will result in a kernel
+tree that is impossible to merge correctly with future upstream releases.</li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/kernel/reqs-interfaces.html b/en/devices/architecture/kernel/reqs-interfaces.html
new file mode 100644
index 00000000..82349f7b
--- /dev/null
+++ b/en/devices/architecture/kernel/reqs-interfaces.html
@@ -0,0 +1,273 @@
+<html devsite>
+ <head>
+ <title>Interface Requirements</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>This page describes a subset of the Linux kernel interfaces on which Android
+relies to function properly. The presence and correctness of these interfaces is
+tested as part of the <a href="/devices/tech/vts/index.html">Vendor Test Suite
+(VTS)</a>. This subset will grow over time to contain a larger portion of
+Android kernel interfaces.</p>
+
+<h2 id="system-calls">System calls</h2>
+<p>System calls are expected to provide the same signatures and semantics as in
+the upstream Linux kernel.</p>
+
+<p>ARM64 system calls required by bionic per
+<code>bionic/libc/SYSCALLS.txt</code>:</p>
+
+<table>
+<tr>
+<td class="devsite-click-to-copy">accept4, acct, adjtimex, bind, brk, capget, capset, chdir, chroot, clock_adjtime, clock_getres, clock_gettime, clock_nanosleep, clock_settime, close, connect, delete_module, dup3, dup, epoll_create1, epoll_ctl, epoll_pwait, eventfd2, execve, exit, exit_group, faccessat, fadvise64, fallocate, fchdir, fchmodat, fchmod, fchownat, fchown, fcntl, fdatasync, fgetxattr, flistxattr, flock, fremovexattr, fsetxattr, fstat, newfstatat, fstatfs, fsync, ftruncate, getcpu, getcwd, getdents64, getegid, geteuid, getgid, getgroups, getitimer, getpeername, getpgid, getpid, getppid, getpriority, getresgid, getresuid, getrlimit, getrusage, getsid, getsockname, getsockopt, gettimeofday, getuid, getxattr, init_module, inotify_add_watch, inotify_init1, inotify_rm_watch, ioctl, kill, syslog, lgetxattr, linkat, listen, listxattr, llistxattr, lremovexattr, lseek, lsetxattr, madvise, mincore, mkdirat, mknodat, mlockall, mlock, mmap, mount, mprotect, mremap, msync, munlockall, munlock, munmap, nanosleep, openat, personality, pipe2, ppoll, prctl, pread64, preadv, prlimit64, process_vm_readv, process_vm_writev, pselect6, ptrace, pwrite64, pwritev, quotactl, readahead, readlinkat, read, readv, reboot, recvfrom, recvmmsg, recvmsg, removexattr, renameat, rt_sigaction, rt_sigpending, rt_sigprocmask, rt_sigqueueinfo, rt_sigsuspend, rt_sigtimedwait, sched_getaffinity, sched_getparam, sched_get_priority_max, sched_get_priority_min, sched_getscheduler, sched_rr_get_interval, sched_setaffinity, sched_setparam, sched_setscheduler, sched_yield, sendfile, sendmmsg, sendmsg, sendto, setdomainname, setfsgid, setfsuid, setgid, setgroups, sethostname, setitimer, setns, setpgid, setpriority, setregid, setresgid, setresuid, setreuid, setrlimit, setsid, setsockopt, set_tid_address, settimeofday, setuid, setxattr, shutdown, sigaltstack, signalfd4, socketpair, socket, splice, statfs, swapoff, swapon, symlinkat, sync_file_range, sync, sysinfo, tee, tgkill, timer_create, timer_delete, timerfd_create, timerfd_gettime, timerfd_settime, timer_getoverrun, timer_gettime, timer_settime, times, truncate, umask, umount2, uname, unlinkat, unshare, utimensat, vmsplice, wait4, waitid, write, writev</td>
+</tr></table>
+
+<p>ARM32 system calls required by bionic per
+<code>bionic/libc/SYSCALLS.txt</code>:</p>
+
+<table>
+<tr>
+<td class="devsite-click-to-copy">accept4, acct, adjtimex, arm_fadvise64_64, bind, brk, cacheflush, capget, capset, chdir, chroot, clock_adjtime, clock_getres, clock_gettime, clock_nanosleep, clock_settime, close, connect, delete_module, dup3, dup, epoll_create1, epoll_ctl, epoll_pwait, eventfd2, execve, exit, exit_group, faccessat, fallocate, fchdir, fchmodat, fchmod, fchownat, fchown32, fcntl64, fdatasync, fgetxattr, flistxattr, flock, fremovexattr, fsetxattr, fstat64, fstatat64, fstatfs64, fsync, ftruncate64, getcpu, getcwd, getdents64, getegid32, geteuid32, getgid32, getgroups32, getitimer, getpeername, getpgid, getpid, getppid, getpriority, getresgid32, getresuid32, ugetrlimit, getrusage, getsid, getsockname, getsockopt, gettimeofday, getuid32, getxattr, init_module, inotify_add_watch, inotify_init1, inotify_rm_watch, ioctl, kill, syslog, lgetxattr, linkat, listen, listxattr, llistxattr, _llseek, lremovexattr, lseek, lsetxattr, madvise, mincore, mkdirat, mknodat, mlockall, mlock, mmap2, mount, mprotect, mremap, msync, munlockall, munlock, munmap, nanosleep, openat, personality, pipe2, ppoll, prctl, pread64, preadv, prlimit64, process_vm_readv, process_vm_writev, pselect6, ptrace, pwrite64, pwritev, quotactl, readahead, readlinkat, read, readv, reboot, recvfrom, recvmmsg, recvmsg, removexattr, renameat, rt_sigaction, rt_sigpending, rt_sigprocmask, rt_sigqueueinfo, rt_sigsuspend, rt_sigtimedwait, sched_getaffinity, sched_getparam, sched_get_priority_max, sched_get_priority_min, sched_getscheduler, sched_rr_get_interval, sched_setaffinity, sched_setparam, sched_setscheduler, sched_yield, sendfile64, sendfile, sendmmsg, sendmsg, sendto, setdomainname, setfsgid, setfsuid, setgid32, setgroups32, sethostname, setitimer, setns, setpgid, setpriority, setregid32, setresgid32, setresuid32, setreuid32, setrlimit, setsid, setsockopt, set_tid_address, settimeofday, set_tls, setuid32, setxattr, shutdown, sigaction, sigaltstack, signalfd4, socketpair, socket, splice, statfs64, swapoff, swapon, symlinkat, sync_file_range2, sync, sysinfo, tee, tgkill, timer_create, timer_delete, timerfd_create, timerfd_gettime, timerfd_settime, timer_getoverrun, timer_gettime, timer_settime, times, truncate64, truncate, umask, umount2, uname, unlinkat, unshare, utimensat, vmsplice, wait4, waitid, write, writev</td>
+</tr></table>
+
+<p>The system calls listed below are made by bypassing bionic:</p>
+
+<table>
+ <tr>
+ <th style="width:20%">All Architectures</th>
+ <td>gettid, futex, clone, rt_sigreturn, rt_tgsigqueueinfo, restart_syscall,
+getrandom, perf_event_open, syncfs, tkill, seccomp</td>
+ </tr>
+ <tr>
+ <th>arm</th>
+ <td>vfork, sigreturn, pipe, access, stat64, lstat64, open, getdents, eventfd,
+epoll_wait, readlink, epoll_create, creat, unlink</td>
+ </tr>
+ <tr>
+ <th>arm64</th>
+ <td>pivot_root, ioprio_get, ioprio_set</td>
+ </tr>
+</table>
+
+<aside class="note"><strong>Note:</strong> x86 and x86_64 system calls will be
+added in a future release.</aside>
+
+<h3 id="prctl">prctl</h3>
+<p>In addition to the upstream <code>prctl</code> operations for supported
+kernel versions, Android relies on additional <code>prctl</code> operations, the
+implementation of which can be found in the android-common kernel.</p>
+
+<pre class="prettyprint">
+PR_SET_TIMERSLACK_PID
+PR_SET_VMA
+</pre>
+
+<h2 id="filesystems">Filesystems</h2>
+<p>The Linux kernel exports interfaces via several filesystems. Android expects
+these interfaces to communicate the same information, in the same format, and
+provide the same semantics as in the upstream Linux kernel. For interfaces that
+do not exist upstream, the appropriate behavior is dictated by the corresponding
+branch of the Android common kernel.</p>
+
+<h3 id="procfs">procfs</h3>
+<table>
+ <tr>
+ <th>Path</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>/proc/cmdline</code></td>
+ <td>Read-only file containing command line arguments passed to the kernel.
+ </td>
+ </tr>
+ <tr>
+ <td><code>/proc/config.gz</code></td>
+ <td>Read-only file containing kernel build configuration.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/cpuinfo</code></td>
+ <td>Read-only file containing architecture-specific CPU details.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/kmsg</code></td>
+ <td>Read-only file showing kernel messages in real time.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/meminfo</code></td>
+ <td>Read-only file showing memory subsystem details.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/modules</code></td>
+ <td>Read-only file containing information about loaded kernel modules.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/mounts</code></td>
+ <td>Symlink to <code>/proc/self/mounts</code>, which is a read-only file
+ listing information about the mounted filesystems.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/net/xt_qtaguid/ctrl</code></td>
+ <td>Read-write file providing information about tagged sockets.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/self/maps</code></td>
+ <td>Read-only file containing the currently mapped memory regions and
+ permissions.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/stat</code></td>
+ <td>Read-only file containing various kernel and system statistics.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/kernel/kptr_restrict</code></td>
+ <td>Read-write file that determines whether kernel pointers are printed in
+ <code>proc</code> files and other interfaces.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/kernel/randomize_va_space</code></td>
+ <td>Read-write file that determines the address layout randomization policy
+ for the system.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/vm/mmap_min_addr</code></td>
+ <td>Read-write file that determines the minimum address than can be
+ <code>mmap</code>'d.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/vm/mmap_rnd_bits</code></td>
+ <td>Read-write file that specifies the amount of randomness in
+ <code>mmap</code>'d addresses.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/vm/mmap_rnd_compat_bits</code></td>
+ <td>Read-write file that specifies the amount of randomness in
+ <code>mmap</code>'d addresses.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/sys/vm/overcommit_memory</code></td>
+ <td>Read-write file that determines the kernel virtual memory accounting
+ mode.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/uid_cputime/remove_uid_range</code></td>
+ <td>Write-only file that, when written, removes UIDs from being shown in
+ <code>/proc/uid_cputime/show_uid_stat</code>.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/uid_cputime/show_uid_stat</code></td>
+ <td>Read-only file containing the time a UID's processes spent in user and
+ kernel space.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/version</code></td>
+ <td>Read-only file containing a string describing the kernel version.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/vmallocinfo</code></td>
+ <td>Read-only file containing <code>vmalloc</code>'d ranges.</td>
+ </tr>
+ <tr>
+ <td><code>/proc/zoneinfo</code></td>
+ <td>Read-only file containing information about memory zones.</td>
+ </tr>
+</table>
+
+<h3 id="dev">dev</h3>
+
+<table>
+ <tr>
+ <th>Path</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>/dev/ashmem</code></td>
+ <td>Anonymous shared memory device file.</td>
+ </tr>
+ <tr>
+ <td><code>/dev/binder</code></td>
+ <td>Binder device file.</td>
+ </tr>
+ <tr>
+ <td><code>/dev/hwbinder</code></td>
+ <td>Hardware binder device file.</td>
+ </tr>
+ <tr>
+ <td><code>/dev/tun</code></td>
+ <td>Universal TUN/TAP device file.</td>
+ </tr>
+ <tr>
+ <td><code>/dev/xt_qtaguid</code></td>
+ <td>QTAGUID netfilter device file.</td>
+ </tr>
+</table>
+
+<h3 id="sysfs">sysfs</h3>
+<table>
+ <tr>
+ <th>Path</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>/sys/devices/system/cpu/online</code></td>
+ <td>Read-only file showing ranges of CPUs that are currently online.</td>
+ </tr>
+ <tr>
+ <td><code>/sys/kernel/wakeup_reasons/last_resume_reason</code></td>
+ <td>Read-only file showing a textual description of why the system exited the
+ last instance of suspend.</td>
+ </tr>
+ <tr>
+ <td><code>/sys/devices/system/cpu/kernel_max</code></td>
+ <td>Read-only file showing the maximum CPU index supported by the kernel.
+ </td>
+ </tr>
+</table>
+
+<h3 id="selinuxfs">selinuxfs</h3>
+<p>The framework mounts <code>selinuxfs</code> at <code>/sys/fs/selinux</code>.
+</p>
+
+<table>
+ <tr>
+ <th>Path</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>/sys/fs/selinux/checkreqprot</code></td>
+ <td>Read/write file containing a binary flag that determines how selinux
+ protections are checked on <code>mmap</code> and <code>mprotect</code> calls.
+ </td>
+ </tr>
+ <tr>
+ <td><code>/sys/fs/selinux/null</code></td>
+ <td>Read/write null device for use by selinux.</td>
+ </tr>
+ <tr>
+ <td><code>/sys/fs/selinux/policy</code></td>
+ <td>Read-only file containing the selinux policy in binary form.</td>
+ </tr>
+</table>
+
+<aside class="note"><strong>Note:</strong> For details on SELinux in Android
+8.0, see <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for
+Android 8.0</a>.</aside>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/kernel/squashfs.html b/en/devices/architecture/kernel/squashfs.html
new file mode 100644
index 00000000..93b97ad0
--- /dev/null
+++ b/en/devices/architecture/kernel/squashfs.html
@@ -0,0 +1,114 @@
+<html devsite>
+ <head>
+ <title>Optimizing SquashFS at the Kernel Level</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>
+ SquashFS is a compressed read-only filesystem for Linux. The file system is
+ read-only by design and thus suitable for use on the system partition. Many
+ Android devices may benefit from using this file system for their system
+ partition, for example, the following:
+ </p><ul>
+ <li>Devices with a low capacity storage such as Android Watch.
+ <li>Devices with a slow flash storage (compression reduces the number of block
+ I/Os).</li></ul>
+ <p>
+ Unfortunately the performance of SquashFS lags behind ext4.
+ </p>
+ <h2 id="optimizations">Optimizations</h2>
+ <p>
+ The following optimizations have been implemented to improve the performance of
+ SquashFS.
+ </p>
+ <h3 id="reduce-the-memory-usage-and-memcpy">Reduce the memory usage and
+ memcpy</h3>
+ <p>
+ When reading a block (default 128K), SquashFS tries to grab all the pages
+ covering this block.
+ </p>
+ <p>
+ If a single page is up-to-date or locked, it falls back to allocating a full
+ block, submitting a read request, and then copying its content to the pages.
+ </p>
+ <p>
+ This approach is very ineffective; after some time the page cache is likely to
+ contain pages that are up-to-date even if the adjacent pages are not.
+ </p>
+ <p>
+ The code is now able to handle blocks with holes (=missing pages). This
+ improves performance in the following ways:
+ </p><ul>
+ <li>Reduces the number of <code>memcpy</code> calls
+ <li>Decreases memory allocations</li></ul>
+ <h3 id="asynchronous-reads">Asynchronous reads</h3>
+ <p>
+ SquashFS still uses the deprecated <code>ll_rw_block()</code> function. There
+ are two problems with this approach:
+ </p><ul>
+ <li>As the name implies, the function waits for the reads to complete before
+ returning. This is redundant since <code>.readpage()</code> already waits on the
+ page's lock. Moreover, we need an asynchronous mechanism to efficiently
+ implement <code>.readpages()</code>.
+ <li>Merging the read requests entirely depends on the I/O scheduler.
+ <code>ll_rw_block()</code> simply creates one request per buffer. SquashFS has
+ more information than the I/O scheduler about what should be merged. Moreover,
+ merging the request means that we rely less on the I/O scheduler.</li></ul>
+ <p>
+ For these reasons, the <code>ll_rw_block()</code> function has been replaced
+ with <code>submit_bio()</code>.
+ </p>
+ <h3 id="readpages-prefetching">Readpages (prefetching)</h3>
+ <p>
+ SquashFS does not implement <code>.readpages()</code>, so the kernel repeatedly
+ calls <code>.readpage()</code>.
+ </p>
+ <p>
+ Now that our read requests are asynchronous, the kernel can truly prefetch pages
+ using its asynchronous read-ahead mechanism.
+ </p>
+ <h3 id="optimize-reading-uncompressed-blocks">Optimize reading uncompressed
+ blocks</h3>
+ <p>
+ Modern systems such as Android contain a lot of files that are already
+ compressed. As a consequence, the image contains a lot of blocks that can't be
+ compressed.
+ </p>
+ <p>
+ SquashFS handles compressed and uncompressed blocks using the same logic: when
+ asked to read a single page, it actually reads a full block (default 128k).
+ While this is necessary for compressed blocks, it is just a waste of resources
+ for uncompressed blocks.
+ </p>
+ <p>
+ Instead of reading a full block, SquashFS now just reads what is advised by the
+ readahead algorithm.
+ </p>
+ <p>
+ This greatly improves the performance of random reads.
+ </p>
+ <h2 id="code">Code</h2>
+ <p>
+ SquashFS code optimizations are available in AOSP:
+ </p><ul>
+ <li><a
+ href="https://android-review.googlesource.com/#/q/topic:squashfs">https://android-review.googlesource.com/#/q/topic:squashfs</a></li></ul>
+ </body>
+</html>
diff --git a/en/devices/architecture/treble.html b/en/devices/architecture/treble.html
index 343858df..ca3c4086 100644
--- a/en/devices/architecture/treble.html
+++ b/en/devices/architecture/treble.html
@@ -22,11 +22,13 @@
-->
-<p>The upcoming Android O release includes Project Treble, a major re-architect
+<p>The Android 8.0 release includes Project Treble, a major re-architect
of the Android OS framework designed to make it easier, faster, and less costly
-for manufacturers to update devices to a new version of Android.</p>
+for manufacturers to update devices to a new version of Android. Treble is for
+all new devices launching with Android 8.0 and beyond (the new architecture is
+already running on the Developer Preview for Pixel phones).</p>
-<h2 id=about-treble>Android updates</h2>
+<h2 id=about-treble>About Android updates</h2>
<p>Project Treble separates the vendor implementation (device-specific,
lower-level software written by silicon manufacturers) from the Android OS
framework via a new vendor interface.</p>
@@ -51,23 +53,40 @@ additional work required from the silicon manufacturers:</p>
environment</p>
<h2 id=testing-treble>Testing Treble</h2>
-<p>To ensure forward compatibility of the vendor implementation, the new vendor
-interface will be validated by the Vendor Test Suite (VTS), which is analogous
-to the <a href="/compatibility/cts/">Compatibility Test Suite (CTS)</a>. VTS is
-already launched and can be used to automate HAL and OS kernel testing even in
-pre-Treble environments; for details, see
-<a href="/devices/tech/test_infra/tradefed/fundamentals/vts">Systems Testing
-With VTS</a>.</p>
-
-<h2 id=launching-treble>Coming soon</h2>
-<p>Project Treble is coming to all new devices launching with Android O and
-beyond, and the new architecture is already running on the Developer Preview of
-O for Pixel phones. When Android O launches, we'll have full details here (on
-<a href="https://source.android.com/">source.android.com</a>). In the interim,
-you can find more details on Treble over at the
-<a href="https://android-developers.googleblog.com/2017/05/here-comes-treble-modular-base-for.html">Android
-Developers Blog</a>.</p>
-
+<p>To ensure forward compatibility of vendor implementations, the new vendor
+interface is validated by the <a href="/devices/tech/vts/index.html">Vendor Test
+Suite (VTS)</a>, which is analogous to the
+<a href="/compatibility/cts/">Compatibility Test Suite (CTS)</a>. You can use
+VTS to automate HAL and OS kernel testing in both pre-Treble and Treble
+environments.</p>
+
+<h2 id=treble-resources>Treble resources</h2>
+<p>For details on the new Treble architecture, see the following sections:</p>
+<ul>
+<li><a href="/devices/architecture/hal-types.html">HAL Types</a>. Describes
+binderized, passthrough, Same-Process (SP), and legacy HALs.</li>
+<li><a href="/devices/architecture/hidl/index.html">HIDL (General)</a>.
+Contains general information about the HAL interface definition language (HIDL,
+pronounced "hide-l"), which is an interface description language (IDL) to
+specify the interface between a HAL and its users.</li>
+<li><a href="/devices/architecture/hidl-cpp/index.html">HIDL (C++)</a>. Contains
+details for creating C++ implementations of HIDL interfaces.</li>
+<li><a href="/devices/architecture/hidl-java/index.html">HIDL (Java)</a>.
+Contains details about the Java frontend for HIDL interfaces.</li>
+<li><a href="/devices/architecture/configstore/index.html">ConfigStore HAL</a>.
+Describes the ConfigStore HAL, which provides a set of APIs for accessing
+read-only configuration items used to configure the Android framework.</li>
+<li><a href="/devices/architecture/dto/index.html">Device Tree Overlays</a>.
+Provides details on using device tree overlays (DTOs) in Android.</li>
+<li><a href="/devices/architecture/vndk/index.html">Vendor Native Development
+Kit (VNDK)</a>. Describes the VNDK, which is a set of libraries exclusively for
+vendors to implement their HALs.</li>
+<li><a href="/devices/architecture/vintf/index.html">Vendor Interface Object
+(VINTF)</a>. VINTF objects aggregate relevant information about a device and
+make that information available through a queryable API.</li>
+<li><a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
+8.0</a>. Details SELinux changes and customizations.</li>
+</ul>
</body>
</html>
diff --git a/en/devices/architecture/vintf/comp-matrices.html b/en/devices/architecture/vintf/comp-matrices.html
new file mode 100644
index 00000000..d3512e70
--- /dev/null
+++ b/en/devices/architecture/vintf/comp-matrices.html
@@ -0,0 +1,263 @@
+<html devsite>
+ <head>
+ <title>Compatibility Matrices</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>This section describes the framework and device compatibility matrices and
+the <a href="#compatiblity-matrix-schema">compatibility matrix schema</a>. For
+match rules, see <a href="/devices/architecture/vintf/match-rules.html">Matching
+Rules</a>.</p>
+
+<h2 id="framework-compatibility-matrix">Framework compatibility matrix</h2>
+<p>The framework compatibility matrix describes the requirements of the
+framework on the device it runs on. The matrix file is associated with the
+Android framework image (on <code>system.img</code>). It is expected the
+requirements of the framework's compatibility matrix will be satisfied by the
+device manifest (requirements enforced at launch and OTA time).</p>
+
+<p>Example framework compatibility matrix file:</p>
+
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;!-- Comments, Legal notices, etc. here -->
+&lt;compatibility-matrix version="1.0" type="framework">
+ &lt;hal>
+ &lt;name>android.hardware.camera&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;version>3.1-4&lt;/version>
+ &lt;interface>
+ &lt;name>ICameraProvider&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hardware.nfc&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>INfc&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal optional="true">
+ &lt;name>android.hardware.graphics.composer&lt;/name>
+ &lt;version>2.1&lt;/version>
+ &lt;/hal>
+ &lt;hal format="native">
+ &lt;name>GL&lt;/name>
+ &lt;version>1.1&lt;/version>
+ &lt;version>3.0&lt;/version>
+ &lt;/hal>
+ &lt;hal format="native">
+ &lt;name>EGL&lt;/name>
+ &lt;version>1.1&lt;/version>
+ &lt;/hal>
+ &lt;kernel version="3.18.51">
+ &lt;config>
+ &lt;key>CONFIG_A&lt;/key>
+ &lt;value type="string">&lt;/value>
+ &lt;/config>
+ &lt;config>
+ &lt;key>CONFIG_B&lt;/key>
+ &lt;value type="tristate">y&lt;/value>
+ &lt;/config>
+ &lt;/kernel>
+ &lt;kernel version="4.1.22">
+ &lt;config>
+ &lt;key>CONFIG_A&lt;/key>
+ &lt;value type="string">foo&lt;/value>
+ &lt;/config>
+ &lt;config>
+ &lt;key>CONFIG_B2&lt;/key>
+ &lt;value type="int">1024&lt;/value>
+ &lt;/config>
+ &lt;/kernel>
+ &lt;sepolicy>
+ &lt;kernel-sepolicy-version>30&lt;/kernel-sepolicy-version>
+ &lt;sepolicy-version>25.0&lt;/sepolicy-version>
+ &lt;sepolicy-version>26.0-3&lt;/sepolicy-version>
+ &lt;/sepolicy>
+ &lt;avb>
+ &lt;vbmeta-version>2.1&lt;/vbmeta-version>
+ &lt;/avb>
+ &lt;xmlfile format="dtd">
+ &lt;name>media_profile&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;path>/system/etc/media_profile_V1_0.dtd&lt;/path>
+ &lt;/xmlfile>
+&lt;/compatiblity-matrix>
+</pre>
+
+<h2 id="device-compatibility-matrix">Device compatibility matrix</h2>
+<p>The device compatibility matrix describes a set of requirements the device
+expects from the framework (requirements enforced at launch and OTA time).
+</p>
+<p>Example device compatibility matrix file:</p>
+
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;!-- Comments, Legal notices, etc. here -->
+&lt;compatibility-matrix version="1.0" type="device">
+ &lt;hal>
+ &lt;name>android.hidl.manager&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IServiceManager&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hidl.memory&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IMemory&lt;/name>
+ &lt;instance>ashmem&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hidl.allocator&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IAllocator&lt;/name>
+ &lt;instance>ashmem&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.framework.sensor&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>ISensorManager&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;xmlfile format="dtd" optional="false">
+ &lt;name>sample_xml&lt;/name>
+ &lt;version>1.0&lt;/version>
+ &lt;/xmlfile>
+&lt;/compatibility-matrix>
+</pre>
+
+<h2 id="compatiblity-matrix-schema">Compatiblity matrix schema</h2>
+<dl>
+<dt><code>?xml</code></dt>
+<dd>Optional. It only provides information to the XML parser.</dd>
+<dt><code>compatibility-matrix.version</code></dt>
+<dd>Required. Version of this compatiblity matrix. Describes the elements
+expected in the manifest. Unrelated to XML version.</dd>
+<dt><code>compatibility-matrix.type</code></dt>
+<dd>Required. Type of this compatibility matrix:
+ <ul>
+ <li><code>"device"</code>: Device compatibility matrix.</li>
+ <li><code>"framework"</code>: Framework compatibility matrix.</li>
+ </ul>
+</dd>
+<dt><code>compatibility-matrix.hal</code></dt>
+<dd>Optional and can repeat. Lists a single HAL (HIDL or native) that is
+required by owner of the compatibility matrix (framework or device) to be
+present. HAL entries are distinguished by a <code>&lt;name&gt;</code> element;
+there can be several HAL entries with the same name (implies "and" condition).
+</dd>
+<dt><code>compatibility-matrix.hal.format</code></dt>
+<dd>Optional. Value can be one of:
+ <ul>
+ <li><code>"hidl"</code>: HIDL HALs. This is the default.</li>
+ <li><code>"native"</code>: native HALs.</li>
+ </ul>
+</dd>
+<dt><code>compatibility-matrix.hal.optional</code></dt>
+<dd>Attribute is optional and defaults to false. States whether this HAL is
+optional to the owner of the compatibility matrix (framework or device). If a
+<code>&ltp;hal&gt;</code> entry is marked as optional, it means the owner can
+work with this HAL, if present, but does not require it to be present.</dd>
+<dt><code>compatibility-matrix.hal.name</code></dt>
+<dd>Required. Full package name of this HAL. Examples:
+ <ul>
+ <li><code>android.hardware.camera</code> (HIDL HAL)</li>
+ <li><code>GLES</code> (native HAL, requires name only)</li>
+ </ul>
+</dd>
+<dt><code>compatibility-matrix.hal.version</code></dt>
+<dd>Required, can repeat without duplicates. A list of version ranges (see
+<a href="/devices/architecture/vintf/match-rules.html#hals">HAL matches</a>)
+that defines what versions the owner of the compatibility matrix (framework or
+device) expects.</dd>
+<dt><code>compatibility-matrix.hal.interface</code></dt>
+<dd>Optional, can repeat. A list of required interfaces of this HAL.</dd>
+<dt><code>compatibility-matrix.hal.interface.name</code></dt>
+<dd>Required. Name of the interface.</dd>
+<dt><code>compatibility-matrix.hal.interface</code></dt>
+<dd>Optional, can repeat. A list of required instances of this interface.</dd>
+<dt><code>compatibility-matrix.kernel.version</code></dt>
+<dd>Required. Kernel version. Format is
+<code>{version}.{major-revision}.{minor-revision}</code>. Version and major
+revision must match exactly, minor-revision defines the minimum LTS version of
+the kernel the framework expects.</dd>
+<dt><code>compatibility-matrix.kernel.config</code></dt>
+<dd>Optional, can repeat. Lists <code>CONFIG</code> items that must be
+matched for this kernel version. Each <code>CONFIG</code> item is a key-value
+pair; config items are distinguished by key.</dd>
+<dt><code>compatibility-matrix.kernel.config.key</code></dt>
+<dd>Required. Key name of the <code>CONFIG</code> item. Starts with
+<code>CONFIG_</code>.</dd>
+<dt><code>compatibility-matrix.kernel.config.value</code></dt>
+<dd>Required. Value of the <code>CONFIG</code> item. Format depends on type:
+ <ul>
+ <li><code>string</code>. Quotes are omitted.</li>
+ <li><code>int</code>. Decimal and hexadecimal (must start with <code>0x</code>
+ or <code>0X)</code>values are accepted. Interpreted as an 64-bit integer;
+ overflows result in truncation. (Parser accepts values from -2<sup>64</sup> + 1
+ to 2<sup>64</sup> - 1, 65th bit is truncated; for details refer to the
+ <a href="http://man7.org/linux/man-pages/man3/strtoul.3.html" class="external">strtoull
+ man page</a>.)</li>
+ <li><code>range</code>. Format is <code>[int]-[int]</code>, e.g.
+ <code>10-20</code>. Hexadecimal values are accepted and must start with
+ <code>0x</code> or <code>0X</code>. Two boundaries must be an unsigned 64-bit
+ integer.</li>
+ <li><code>tristate</code>. Valid values are <code>y</code>, <code>m</code> and
+ <code>n</code>.</li>
+ </ul>
+</dd>
+<dt><code>compatibility-matrix.kernel.config.value.type</code></dt>
+<dd>Required. Type of the value of the <code>CONFIG</code> item, one of:
+ <ul>
+ <li><code>string</code></li>
+ <li><code>int</code></li>
+ <li><code>range</code></li>
+ <li><code>tristate</code></li>
+ </ul>
+</dd>
+<dt><code>compatibility-matrix.sepolicy</code></dt>
+<dd>Required. Contains all sepolicy-related entries. Used only by the
+framework compatibility matrix.</dd>
+<dt><code>compatibility-matrix.sepolicy.sepolicy-version</code></dt>
+<dd>Required, can repeat. Describes the requirement on sepolicy version.
+Corresponds to <code>manifest.sepolicy.version</code>. Each instance of an
+element defines a range of sepolicy versions.</dd>
+<dt><code>compatibility-matrix.sepolicy.kernel-sepolicy-version</code></dt>
+<dd>Required. Declares the <code>policydb</code> version the framework works
+with.</dd>
+<dt><code>compatibility-matrix.avb.vbmeta-version</code></dt>
+<dd>Optional; used only by the framework compatibility matrix. Declares the
+<a href="/devices/architecture/vintf/match-rules.html#avb-version">AVB
+version</a> used to sign <code>system.img</code>.</dd>
+</dl>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vintf/index.html b/en/devices/architecture/vintf/index.html
new file mode 100644
index 00000000..b0517a32
--- /dev/null
+++ b/en/devices/architecture/vintf/index.html
@@ -0,0 +1,113 @@
+<html devsite>
+ <head>
+ <title>Vendor Interface Object</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>This document describes the design of the <em>vendor interface object</em>
+(VINTF object), which aggregates relevant information about a device and makes
+that information available through a <em>queryable API</em>.</p>
+
+
+<h2 id=about-objects>VINTF object design</h2>
+<p>A VINTF object gathers some of the information it needs directly from the
+device. Other aspects, such as the manifests, are described statically in
+XML.</p>
+
+<img src="../images/treble_vintf_mm.png">
+<figcaption><strong>Figure 1.</strong> Manifests, compatibility matrices, and
+runtime-collectible information.</figcaption>
+
+<p>VINTF object design provides the following for device and framework
+components:</p>
+
+<table>
+<tr>
+<th style="width:50%">For the Device</th>
+<th>For the Framework</th>
+</tr>
+<tr>
+<td>
+<ul>
+<li>Defines a schema for the static component (the
+<a href="/devices/architecture/vintf/objects.html#device-manifest-file">device
+manifest file</a>).</li>
+<li>Adds build time support for defining the device manifest file for a given
+device.</li>
+<li>Defines the
+<a href="/devices/architecture/vintf/objects.html#queryable-api">queryable
+API</a> at runtime that retrieves the device manifest file (along with the other
+runtime-collectible information) and packages them into the query result.</li>
+</ul>
+</td>
+<td>
+<ul>
+<li>Defines a schema for the static component (the
+<a href="/devices/architecture/vintf/objects.html#framework-manifest-file">framework
+manifest file</a>).</li>
+<li>Defines the
+<a href="/devices/architecture/vintf/objects.html#queryable-api">queryable
+API</a> at runtime that retrieves the framework manifest file and packages it
+into the query result.</li>
+</ul>
+</td>
+</tr>
+</table>
+
+<p>The VINTF object must be reliable and provide the same complete information
+regardless of when the object is requested (see
+<a href="/devices/architecture/vintf/resources.html#caveats">Caveats</a>).</p>
+
+<h2 id=manifests-matrices>Manifests &amp; matrices</h2>
+<p>Android O requires an API at runtime to query what is on the device and send
+that information to the <a href="/devices/tech/ota/index.html">Over-the-Air
+(OTA)</a> update server and other interested parties (such as CTS
+<code>DeviceInfo</code>). Some information is retrieved at runtime and some of
+it is statically-defined.</p>
+
+<ul>
+<li>The <strong>device manifest</strong> describes the static component of what
+the device can provide to the the framework.</li>
+<li>The <strong>framework compatibility matrix</strong> describes what the
+Android framework expects from a given device. The matrix is a static entity
+whose composition is determined manually during development of the next release
+of the Android framework.</li>
+<li>The <strong>framework manifest</strong> describes high-level services the
+framework can provide to the device.</li>
+<li>The <strong>device compatibility matrix</strong> describes the services the
+vendor image requires of the framework. Its composition is determined manually
+during the development of the device.</li>
+</ul>
+
+<p>These two pairs of manifests and matrices must be reconciled at OTA time to
+ensure a device can get framework updates that are compatible with the device's
+capabilities. In general, a <em>manifest</em> describes what is provided and a
+<em>compatibility matrix</em> describes what is required.</p>
+
+<p><a href="/devices/architecture/vintf/objects.html">VINTF Object Data</a>
+defines the schema for the manifest,
+<a href="/devices/architecture/vintf/comp-matrices.html">Compatibility
+Matrices</a> defines the schema for the compatibility matrix, and
+<a href="/devices/architecture/vintf/match-rules.html">Matching Rules</a>
+defines the rules for a successful match between a compatibility matrix
+and a manifest.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vintf/match-rules.html b/en/devices/architecture/vintf/match-rules.html
new file mode 100644
index 00000000..61a5f1a7
--- /dev/null
+++ b/en/devices/architecture/vintf/match-rules.html
@@ -0,0 +1,366 @@
+<html devsite>
+ <head>
+ <title>Matching Rules</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>The two pairs of compatibility matrices and manifests are meant to be
+reconciled at <a href="/devices/tech/ota/index.html">OTA</a> time to verify the
+framework and vendor implementation can work with each other. This verification
+is successful upon a match between the framework compatibility matrix and the
+device manifest, as well as between the framework manifest and the device
+compatibility matrix. The following sections detail matching rules used by
+various components.</p>
+
+<h2 id="hals">HAL matches</h2>
+<p>The HAL-match rule identifies the versions of <code>hal</code> elements in a
+manifest file that are considered supported by the owner of the corresponding
+compatibility matrix.</p>
+<ul>
+<li>Multiple <code>version</code> elements are concatenated with
+<strong>OR</strong> (see camera example below).</li>
+<li>Multiple <code>&lt;hal&gt;</code> elements with the same name are
+concatenated with <strong>AND</strong>.</li>
+</ul>
+
+<h4><strong>Example</strong>: Successful HAL match for Camera module</h4>
+<p>For a HAL at version 2.5, the match rule is as follows:</p>
+
+<table>
+ <tr>
+ <th>Matrix</th>
+ <th>Matching Manifest</th>
+ </tr>
+ <tr>
+ <td><code>2.5</code></td>
+ <td>2.5-2.∞. Shorthand for 2.5-5.</td>
+ </tr>
+ <tr>
+ <td><code>2.5-7</code></td>
+ <td>2.5-2.∞. Indicates the following:
+ <br>
+ <ul>
+ <li>2.5 is the minimum required version, meaning a manifest providing HAL
+ 2.0-2.4 is not compatible.</li>
+ <li>2.7 is the maximum version that could be requested, meaning the owner of
+ the compatibility matrix (framework or device) will not request versions
+ beyond 2.7. The owner of the matching manifest can still serve version 2.10
+ (as an example) when 2.7 is requested. The compatibility-matrix owner knows
+ only that the requested service is compatible with API version 2.7.</li>
+ <li>-7 is informational only and does not affect the OTA update process.</li>
+ </ul>
+ Thus, a device with a HAL at version 2.10 in its manifest file remains
+ compatible with a framework that states <code>camera:</code>
+ <code>2.5-7</code> in its compatibility matrix.</td>
+ </tr>
+</table>
+
+<h4><strong>Example:</strong> Successful HAL match for DRM module</h4>
+<p>The framework compatibility matrix states the following version information
+for DRM HAL:</p>
+
+<pre class="prettyprint">&lt;hal>
+ &lt;name>android.hardware.drm
+ &lt;version>1.0&lt;/version>
+ &lt;version>3.1-2&lt;/version>
+ &lt;interface>
+ &lt;name>IDrmFactory&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;instance>specific&lt;/instance>
+ &lt;/interface>
+&lt;/hal>
+&lt;hal>
+ &lt;name>android.hardware.drm
+ &lt;version>2.0&lt;/version>
+ &lt;interface>
+ &lt;name>ICryptoFactory&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+&lt;/hal>
+</pre>
+
+<p>A vendor must implement ONE of the following HALs:</p>
+
+<pre>
+android.hardware.drm@1.x::IDrmFactory/default //where x >= 0
+android.hardware.drm@1.x::IDrmFactory/specific //where x >= 0
+</pre>
+
+OR
+
+<pre>
+android.hardware.drm@3.y::IDrmFactory/default //where y >= 1
+android.hardware.drm@3.y::IDrmFactory/specific //where y >= 1
+</pre>
+
+<p>... AND must also implement this HAL:</p>
+
+<pre>
+android.hardware.drm@2.z::ICryptoFactory/default //where z >= 0
+</pre>
+
+<h2 id="kernel">Kernel matches</h2>
+<p>The <code>&lt;kernel&gt;</code> section of the framework compatibility matrix
+describes the framework's requirements of the Linux kernel on the device. This
+information is meant to be matched at OTA time against the
+<a href="/devices/architecture/vintf/objects.html#runtime-collectible-information">information</a>
+about the kernel that gets reported by the device's VINTF object.</p>
+
+<p>A matrix can include multiple <code>&lt;kernel&gt;</code> sections, each with
+a different <code>version</code> attribute using the format:</p>
+
+<pre class="prettyprint">${ver}.${major_rev}.${kernel_minor_rev}</pre>
+
+<p>The OTA considers only the <code>&lt;kernel&gt;</code> section with the same
+<code>${ver}</code> and <code>${major_rev}</code> as the device kernel (i.e.,
+<code>version="${ver}.${major_rev}.${matrix_minor_rev}")</code>; other sections
+are ignored. In addition, the minor revision from the kernel must be a value
+from the compatibility matrix (<code>${kernel_minor_rev} >=
+${matrix_minor_rev}</code>;). If no <code>&lt;kernel&gt;</code> section meets
+these requirements, it is a non-match.</p>
+
+<p>If the <code>&lt;kernel&gt;</code> section does match, the process continues
+by attempting to match <code>config</code> elements against
+<code>/proc/config.gz</code>. For each config element in the compatibility
+matrix, it looks up <code>/proc/config.gz</code> to see if the config is
+present. When a config item is set to <code>n</code> in the compatibility
+matrix for the matching <code>&lt;kernel&gt;</code> section, it must be absent
+from <code>/proc/config.gz</code>. Finally, a config item not in the
+compatibility matrix may or may not be present in <code>/proc/config.gz</code>.
+</p>
+
+<p>Examples of matches:</p>
+<ul>
+<li><code>&lt;value type="string"&gt;bar&lt;/value&gt;</code> matches
+<code>"bar"</code>. Quotes are omitted in the compatibility matrix but present
+in <code>/proc/config.gz</code>.</li>
+<li><code>&lt;value type="int"&gt;4096&lt;/value&gt;</code> matches
+<code>4096</code> or <code>0x1000</code> or <code>0X1000</code>.</li>
+<li><code>&lt;value type="int"&gt;0x1000&lt;/value&gt;</code> matches
+<code>4096</code> or <code>0x1000</code> or <code>0X1000</code>.</li>
+<li><code>&lt;value type="int"&gt;0X1000&lt;/value&gt;</code> matches
+<code>4096</code> or <code>0x1000</code> or <code>0X1000</code>.</li>
+<li><code>&lt;value type="tristate"&gt;y&lt;/value&gt;</code> matches
+<code>y</code>.</li>
+<li><code>&lt;value type="tristate"&gt;m&lt;/value&gt;</code> matches
+<code>m</code>.</li>
+<li><code>&lt;value type="tristate"&gt;n&lt;/value&gt;</code> means the config
+item must NOT exist in <code>/proc/config.gz</code>.</li>
+<li><code>&lt;value type="range"&gt;1-0x3&lt;/value&gt;</code> matches
+<code>1</code>, <code>2</code>, or <code>3</code>, or hexadecimal equivalent.
+</li>
+</ul>
+
+<h4><strong>Example:</strong> Successful kernel match</h4>
+<p>A framework compatibility matrix has the following kernel information:</p>
+
+<pre class="prettyprint">
+&lt;kernel version=&quot;3.18.51&quot;&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_TRI&lt;/key&gt;
+ &lt;value type=&quot;tristate&quot;&gt;y&lt;/value&gt;
+ &lt;/config&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_NOEXIST&lt;/key&gt;
+ &lt;value type=&quot;tristate&quot;&gt;n&lt;/value&gt;
+ &lt;/config&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_DEC&lt;/key&gt;
+ &lt;value type=&quot;int&quot;&gt;4096&lt;/value&gt;
+ &lt;/config&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_HEX&lt;/key&gt;
+ &lt;value type=&quot;int&quot;&gt;0XDEAD&lt;/value&gt;
+ &lt;/config&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_STR&lt;/key&gt;
+ &lt;value type=&quot;string&quot;&gt;str&lt;/value&gt;
+ &lt;/config&gt;
+ &lt;config&gt;
+ &lt;key&gt;CONFIG_EMPTY&lt;/key&gt;
+ &lt;value type=&quot;string&quot;&gt;&lt;/value&gt;
+ &lt;/config&gt;
+&lt;/kernel&gt;
+</pre>
+
+<p>The kernel version is matched first. If a device in <code>uname()</code>
+reports:</p>
+<ul>
+<li>3.10.73 (no match to matrix unless there is a separate kernel section
+with <code>&lt;kernel version="3.10.x"&gt;</code> where <code>x <= 73</code>)
+</li>
+<li>3.18.50 (no match to matrix, smaller than <code>version</code>)</li>
+<li>3.18.51 (match to matrix)</li>
+<li>3.18.52 (match to matrix)</li>
+<li>4.1.22 (no match to matrix unless there is a separate kernel section
+with <code>&lt;kernel version="4.1.x"&gt;</code> where <code>x <= 22</code>)
+</li>
+</ul>
+
+<p>After the appropriate <code>&lt;kernel&gt;</code> section is selected, for
+each <code>&lt;config&gt;</code> item with value other than <code>n</code>, we
+expect the corresponding entry to be present in <code>/proc/config.gz</code>;
+for each <code>&lt;config&gt;</code> item with value <code>n</code>, we expect
+the corresponding entry to not be present in <code>/proc/config.gz</code>. We
+expect the content of <code>&lt;value&gt;</code> to exactly match the text after
+the equal sign (including quotes), up to the newline character or
+<code>#</code>, with leading and trailing whitespace truncated.</p>
+
+<p>The following kernel configuration is an example of a successful match:</p>
+
+<pre class="prettyprint">
+# comments don't matter
+CONFIG_TRI=y
+# CONFIG_NOEXIST should not exist
+CONFIG_DEC = 4096 # trailing comments and whitespaces are fine
+CONFIG_HEX=57005 # 0XDEAD == 57005
+CONFIG_STR="str"
+CONFIG_EMPTY="" # empty string must have quotes
+CONFIG_EXTRA="extra config items are fine too"
+</pre>
+
+<p>The following kernel configuration is an example of an unsuccessful match:</p>
+
+<pre class="prettyprint">
+CONFIG_TRI="y" # mismatch: quotes
+CONFIG_NOEXIST=y # mismatch: CONFIG_NOEXIST exists
+CONFIG_HEX=0x0 # mismatch; value doesn't match
+CONFIG_DEC="" # mismatch; type mismatch (expect int)
+CONFIG_EMPTY=1 # mismatch; expects ""
+# mismatch: CONFIG_STR is missing
+</pre>
+
+<h2 id="se-policy">SE policy matches</h2>
+<p>SE policy requires the following matches:</p>
+<ul>
+<li><code>&lt;sepolicy-version&gt;</code> defines a closed range of minor
+versions for every major version. The sepolicy version reported by the device
+must fall within one of these ranges to be compatible with the framework. Match
+rules are similar to HAL versions; it is a match if the sepolicy version is
+higher or equal to the minimum version for the range. The maximum version is
+purely informational.</li>
+<li><code>&lt;kernel-sepolicy-version&gt;</code> i.e. policydb version. Must
+exactly match the <code>security_policyvers()</code> reported by the device.
+</li>
+</ul>
+
+<h4><strong>Example:</strong> Successful SE policy match</h4>
+<p>The framework compatibility matrix states the following sepolicy information:
+</p>
+
+<pre class="prettyprint">
+ &lt;sepolicy>
+ &lt;kernel-sepolicy-version>30&lt;/kernel-sepolicy-version>
+ &lt;sepolicy-version>25.0&lt;/sepolicy-version>
+ &lt;sepolicy-version>26.0-3&lt;/sepolicy-version>
+ &lt;/sepolicy>
+</pre>
+
+<p>On the device:</p>
+<ul>
+<li>The value returned by <code>security_policyvers()</code> must exactly equal
+30. Otherwise it is not a match.</li>
+<li>SE Policy version must be one of 25.0-∞ or 26.0-∞. Otherwise it is not a
+match. (The "<code>-3</code>" after "<code>26.0</code>" is purely
+informational.)</li>
+</ul>
+
+<h2 id="avb-version">AVB version matches</h2>
+<p>The AVB version contains a MAJOR version and MINOR version, with the format
+as MAJOR.MINOR (e.g., 1.0, 2.1). For details, refer to
+<a href="https://android.googlesource.com/platform/external/avb/#Versioning-and-compatibility" class="external">Versioning
+and Compatibility</a>. AVB version has the following system properties:</p>
+<ul>
+<li><code>ro.boot.vbmeta.avb_version</code> is the <code>libavb</code> version
+in bootloader</li>
+<li><code>ro.boot.avb_version</code> is the <code>libavb</code> version in
+Android OS (<code>init/fs_mgr</code>)</li>
+</ul>
+
+<p>The system property appears only when the corresponding libavb has been used
+to verify AVB metadata (and returns OK). It is absent if a verification failure
+occurred (or no verification occurred at all).</p>
+
+<p>A compatibility match compares the following:</p>
+<ul>
+<li>sysprop <code>ro.boot.vbmeta.avb_version</code> with
+<code>avb.vbmeta-version</code> from framework compatibility matrix;
+ <ul>
+ <li><code>ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJOR</code></li>
+ <li><code>ro.boot.vbmeta.avb_version.MINOR >= avb.vbmeta-version.MINOR</code></li>
+ </ul>
+</li>
+<li>sysprop <code>ro.boot.avb_version</code> with
+<code>avb.vbmeta-version</code> from framework compatibility matrix.
+ <ul>
+ <li><code>ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR</code></li>
+ <li><code>ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR</code></li>
+ </ul>
+</li>
+</ul>
+
+<p>The bootloader or Android OS might contain two copies of <code>libavb</code>
+libraries, each with a different MAJOR version for upgrade devices and launch
+devices. In this case, the same <em>unsigned</em> system image can be shared but
+the final <em>signed</em> system images are different (with different
+<code>avb.vbmeta-version</code>):</p>
+
+<img src="../images/treble_vintf_avb_o_p.png">
+<figcaption><strong>Figure 1. </strong>AVB version matches (<code>/system</code>
+is P, all other partitions are O).</figcaption>
+<br>
+<br>
+<img src="../images/treble_vintf_avb_p.png">
+<figcaption><strong>Figure 2.</strong> AVB version matches (all partitions are
+P).</figcaption>
+
+<h4><strong>Example:</strong> Successful AVB version match</h4>
+<p>The framework compatibility matrix states the following AVB information:</p>
+
+<pre class="prettyprint">
+&lt;avb>
+ &lt;vbmeta-version>2.1&lt;/vbmeta-version>
+&lt;/avb>
+</pre>
+
+<p>On the device:</p>
+
+<pre class="prettyprint">
+ro.boot.avb_version == 1.0 &amp;&amp;
+ro.boot.vbmeta.avb_version == 2.1 <font style="font-family: Roboto, Arial, Helvetica, sans-serif; background-color: red; color: white">&nbsp;mismatch&nbsp;</font>
+</pre>
+
+<pre class="prettyprint">
+ro.boot.avb_version == 2.1 &amp;&amp;
+ro.boot.vbmeta.avb_version == 3.0 <font style="font-family: Roboto, Arial, Helvetica, sans-serif; background-color: red; color: white">&nbsp;mismatch&nbsp;</font>
+</pre>
+
+<pre class="prettyprint">
+ro.boot.avb_version == 2.1 &amp;&amp;
+ro.boot.vbmeta.avb_version == 2.3 <font style="font-family: Roboto, Arial, Helvetica, sans-serif; background-color: green; color: white">&nbsp;match&nbsp;</font>
+</pre>
+
+<pre class="prettyprint">
+ro.boot.avb_version == 2.3 &amp;&amp;
+ro.boot.vbmeta.avb_version == 2.1 <font style="font-family: Roboto, Arial, Helvetica, sans-serif; background-color: green; color: white">&nbsp;match&nbsp;</font>
+</pre>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vintf/objects.html b/en/devices/architecture/vintf/objects.html
new file mode 100644
index 00000000..87abeedf
--- /dev/null
+++ b/en/devices/architecture/vintf/objects.html
@@ -0,0 +1,262 @@
+<html devsite>
+ <head>
+ <title>VINTF Object Data</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>A VINTF object aggregates data from
+<a href="#device-manifest-file">device manifest</a> and
+<a href="#framework-manifest-file">framework manifest</a> files (XML) and from
+the device itself at <a href="#runtime-data">runtime</a>. Both manifests share a
+format, although not all elements apply to both (for details on the schema, see
+<a href="#manifest-file-schema">Manifest file schema</a>).</p>
+
+<h2 id="device-manifest-file">Device manifest file</h2>
+<p>The Device manifest file is provided by the device. It lives in the Android
+source tree at <code>device/${VENDOR}/${DEVICE}/manifest.xml</code> and on the
+device at
+<code><a href="https://android.googlesource.com/platform/system/libhidl/+/master/manifest.xml" class="external">/vendor/manifest.xml</a></code>.
+</p>
+
+<p>Example Device manifest:</p>
+
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;!-- Comments, Legal notices, etc. here -->
+&lt;manifest version="1.0" type="device">
+ &lt;hal>
+ &lt;name>android.hardware.camera&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>3.4&lt;/version>
+ &lt;interface>
+ &lt;name>ICameraProvider&lt;/name>
+ &lt;instance>legacy/0&lt;/instance>
+ &lt;instance>proprietary/0&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hardware.nfc&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>1.0&lt;/version>
+ &lt;version>2.0&lt;/version>
+ &lt;interface>
+ &lt;name>INfc&lt;/name>
+ &lt;instance>nfc_nci&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hardware.nfc&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>2.0&lt;/version>
+ &lt;interface>
+ &lt;name>INfc&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal format="native">
+ &lt;name>EGL&lt;/name>
+ &lt;version>1.1&lt;/version>
+ &lt;/hal>
+ &lt;hal format="native">
+ &lt;name>GLES&lt;/name>
+ &lt;version>1.1&lt;/version>
+ &lt;version>2.0&lt;/version>
+ &lt;version>3.0&lt;/version>
+ &lt;/hal>
+ &lt;sepolicy>
+ &lt;version>25.0&lt;/version>
+ &lt;/sepolicy>
+&lt;/manifest>
+</pre>
+
+<h2 id="framework-manifest-file">Framework manifest file</h2>
+<p>The Framework manifest file is provided by Google and is manually generated.
+It lives in the Android source tree at <code>system/libhidl/manifest.xml</code>
+and on the device under <code>/system/manifest.xml</code>.</p>
+
+<p>Example Framework manifest (provided by Google):</p>
+
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;!-- Comments, Legal notices, etc. here -->
+&lt;manifest version="1.0" type="framework">
+ &lt;hal>
+ &lt;name>android.hidl.allocator&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IAllocator&lt;/name>
+ &lt;instance>ashmem&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hidl.memory&lt;/name>
+ &lt;transport arch="32+64">passthrough&lt;/transport>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IMapper&lt;/name>
+ &lt;instance>ashmem&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.hidl.manager&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>IServiceManager&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+ &lt;hal>
+ &lt;name>android.framework.sensorservice&lt;/name>
+ &lt;transport>hwbinder&lt;/transport>
+ &lt;version>1.0&lt;/version>
+ &lt;interface>
+ &lt;name>ISensorManager&lt;/name>
+ &lt;instance>default&lt;/instance>
+ &lt;/interface>
+ &lt;/hal>
+&lt;/manifest>
+</pre>
+
+<h2 id="manifest-file-schema">Manifest file schema</h2>
+<dl>
+<dt><code>?xml</code></dt>
+<dd>Optional. Only provides information to the XML parser.</dd>
+<dt><code>manifest.version</code></dt>
+<dd>Required. Version of <strong>this</strong> manifest. Describes the elements
+expected in the manifest. Unrelated to XML version.</dd>
+<dt><code>manifest.type</code></dt>
+<dd>Required. Type of this manifest. It has value <code>device</code> for
+device manifest file and <code>framework</code> for framework manifest
+file.</dd>
+<dt><code>manifest.hal</code></dt>
+<dd>Optional, can repeat. A single HAL (HIDL or native, such as GL),
+depending on the <code>format</code> attribute.</dd>
+<dt><code>manifest.hal.format</code></dt>
+<dd>Optional. Value can be one of:
+ <ul>
+ <li><code>hidl</code>: HIDL HALs. This is the default.
+ <li><code>native</code>: native HALs.</li>
+ </ul>
+</dd>
+<dt><code>manifest.hal.name</code></dt>
+<dd>Required. Fully-qualified package name of HAL. Multiple HAL entries can use
+the same name. Examples:
+ <ul>
+ <li><code>android.hardware.camera</code> (HIDL HAL)</li>
+ <li><code>GLES</code> (native HAL, requires name only)</li>
+ </ul>
+ </dd>
+<dt><code>manifest.hal.transport</code></dt>
+<dd>Required when <code>manifest.hal.format == "hidl"</code>. Must NOT be
+present otherwise. States what transport will be used when an interface from
+this package is queried from service manager. Value can be one of:
+ <ul>
+ <li><code>hwbinder</code>: binderized mode</li>
+ <li><code>passthrough</code>: passthrough mode</li>
+ </ul>
+</dd>
+<dt><code>manifest.hal.transport.arch</code></dt>
+<dd>Required for <code>passthrough</code> and must not be present for
+<code>hwbinder</code>. Describes the bitness of the passthrough service being
+provided. Value can be one of:
+ <ul>
+ <li><code>32</code>: 32-bit mode</li>
+ <li><code>64</code>: 64-bit mode</li>
+ <li><code>32+64</code>: both</li>
+ </ul>
+</dd>
+<dt><code>manifest.hal.version</code></dt>
+<dd>Required, can repeat. A version for the <code>hal</code> tags in a
+manifest. Format is <code><var>MAJOR</var>.<var>MINOR</var></code>. For
+examples, refer to <code>hardware/interfaces</code>,
+<code>vendor/${VENDOR}/interfaces</code>,
+<code>framework/hardware/interfaces</code>, or<code>
+system/hardware/interfaces</code>.
+<br><br>
+HIDL and native HALs may use multiple version fields as long as they represent
+<strong>distinct major versions</strong>, with only one minor version per major
+version provided. For example, 3.1 and 3.2 cannot coexist, but 1.0 and 3.4 can.
+This applies for all <code>hal</code> elements with the same name.</dd>
+<dt><code>manifest.hal.interface</code></dt>
+<dd>Required, can repeat without duplicates. State an interface in the
+package that has an instance name. There can be multiple
+<code>&lt;interface&gt;</code> elements in a <code>&lt;hal&gt;</code>; names
+must be distinct.</dd>
+<dt><code>manifest.hal.interface.name</code></dt>
+<dd>Required. Name of the interface.</dd>
+<dt><code>manifest.hal.interface.instance</code></dt>
+<dd>Required, can repeat. Instance name of the interface. Can have multiple
+instances for an interface but no duplicated <code>&lt;instance&gt;</code>
+elements.</dd>
+<dt><code>manifest.sepolicy</code></dt>
+<dd>Required. Contains all sepolicy-related entries.</dd>
+<dt><code>manifest.sepolicy.version</code></dt>
+<dd>Required for device manifest. Declares sepolicy version. It has the
+format <var>SDK_INT</var>.<var>PLAT_INT</var>.</dd>
+</dl>
+
+<h2 id=runtime-data>Runtime data</h2>
+<p>Some information required for the device manifest can be collected only at
+runtime. Information is available via
+<code>::android::vintf::VintfObject::GetRuntimeInfo()</code> and includes the
+following:</p>
+
+<ul>
+<li>Kernel information, including:
+ <ul>
+ <li><code>/proc/config.gz</code>. Zipped full kernel configuration that needs
+ to be read at runtime and converted to a queryable object.</li>
+ <li><code>/proc/version</code>. Information available through
+ <code>uname()</code> system call.</li>
+ <li><code>/proc/cpuinfo</code>. Format may be different for 32-bit and 64-bit
+ machine.</li>
+ <li>policydb version
+ <ul>
+ <li><code>/sys/fs/selinux/policyvers</code> (assuming <code>selinuxfs</code>
+ is mounted at <code>/sys/fs/selinux</code>).</li>
+ <li><code>security_policyvers()</code> API from <code>libselinux</code> gives
+ you the same.</li>
+ </ul>
+ </li>
+ </ul>
+<li>static libavb version, including:
+ <ul>
+ <li>bootloader system property: <code>ro.boot.vbmeta.avb_version</code></li>
+ <li>init/fs_mgr system property: <code>ro.boot.avb_version</code></li>
+ </ul>
+</li>
+</ul>
+
+<h2 id="queryable-api">Queryable API</h2>
+<p>The VINTF object is a system API as the
+<code>hwservicemanager</code>, OTA update service, CTS <code>DeviceInfo</code>,
+and others need information from this API.</p>
+
+<ul>
+<li>C++ queryable API is in
+<a href="https://android.googlesource.com/platform/system/libvintf/+/master/include/vintf/VintfObject.h" class="external"><code>android::vintf::VintfObject</code></a></li>
+<li>Java queryable API is in
+<a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/VintfObject.java" class="external"><code>android.os.VintfObject</code></a>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vintf/resources.html b/en/devices/architecture/vintf/resources.html
new file mode 100644
index 00000000..65828508
--- /dev/null
+++ b/en/devices/architecture/vintf/resources.html
@@ -0,0 +1,184 @@
+<html devsite>
+ <head>
+ <title>Additional Resources</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>The following resources provide details on code locations, tools, testing,
+licensing, and caveats.</p>
+
+<h2 id=query-api-code>Queryable code location</h2>
+<p>The code for the queryable vendor interface object goes to
+<code><a href="https://android.googlesource.com/platform/system/libvintf/+/master#" class="external">system/libvintf</a></code>
+(see the
+<a href="/devices/architecture/vintf/objects.html#queryable-api">queryable
+API</a>).</p>
+
+<h2 id="related-tools">Tools</h2>
+<p>Handwriting manifest files and compatibility matrices can be tough. Use the
+following tools to generate a boilerplate manifest/compatibility matrix to start
+from.</p>
+
+<h3 id="lshal">LSHAL</h3>
+<p>LSHAL is a device-side tool that lists all registered HALs to
+<code>hwservicemanager</code> and all available passthrough implementations
+(e.g. <code>android.hardware.foo@1.0-impl.so</code>) on the device. It can also
+generate a <strong>device manifest</strong> file based on the list:</p>
+
+<pre class="devsite-terminal">
+adb shell su 0 /system/bin/lshal --init-vintf
+</pre>
+
+<p>Note the following:</p>
+<ol>
+<li>If a package is both registered to <code>hwservicemanager</code> and found
+as a passthrough HAL, <code>&lt;transport&gt;</code> is set to
+<code>hwbinder</code>.</li>
+<li>A dummy <code>&lt;sepolicy&gt;<version>0.0</version>&lt;/sepolicy&gt;</code>
+element exists at the end of the manifest. It is suggested that the element is
+deleted and injected via <code>assemble_vintf</code> as explained below.</li>
+<li>The generated HAL manifest file may be inaccurate. Human attention is
+required to fix inconsistencies between the device manifest and what
+<code>vendor.img</code> actually provides.</li>
+</ol>
+
+<h3 id="assemble_vintf">ASSEMBLE_VINTF</h3>
+<p><code>assemble_vintf</code> is a host-side tool that:</p>
+<ol>
+<li>Verifies a compatibility matrix or manifest file is valid.</li>
+<li>Injects variables to manifests/compatibility matrices available at build
+time and generates a new file that should be installed to the device.</li>
+<li>Checks compatibility between the generated file and its dual.</li>
+<li>If a manifest file is given, optionally generates a boilerplate
+compatibility matrix that is compatible with the manifest file.</li>
+</ol>
+
+<h4><strong>Example:</strong> Generate <strong>device compatibility
+matrix</strong> from a framework manifest file</h4>
+
+<pre class="devsite-terminal">
+assemble_vintf -m \
+ -i system/libhidl/manifest.xml \
+ -o device/manufacturer/device_name/compatibility_matrix.xml
+</pre>
+<p>Note the following:</p>
+<ul>
+<li>Even though <code>&lt;vndk&gt;</code> entries are in the output
+compatibility matrix, they should be deleted and injected at build time.</li>
+<li>All HALs are set to <code>optional="true"</code>.</li>
+</ul>
+
+<h4><strong>Example:</strong> Generate a skeleton framework compatibility
+matrix from a device manifest file</h4>
+
+<pre class="devsite-terminal">
+BOARD_SEPOLICY_VERS=10000.0 assemble_vintf -m \
+ -i device/foo/bar/manifest.xml
+ -o path/to/place/output/compatibility_matrix.xml
+</pre>
+<p>Note the following:</p>
+<ul>
+<li>Even though <code>&lt;sepolicy&gt;</code> and <code>&lt;avb&gt;</code> are
+in the output compatibility matrix, they should be deleted and injected at
+build time.</li>
+<li>All HALs are set to <code>optional="true"</code>.</li>
+</ul>
+
+<h4><strong>Example:</strong> Generate XML files from variables</h4>
+
+<p>At build time, if the following variables are
+defined in <code>device/manufacturer/device_name/BoardConfig.mk</code>:</p>
+
+<pre class="prettyprint">
+DEVICE_MANIFEST_FILE := \
+ device/manufacturer/device_name/manifest.xml
+DEVICE_MATRIX_FILE := \
+ device/manufacturer/device_name/compatibility_matrix.xml
+</pre>
+
+<p>Then the following commands (modified to omit implementation details) are
+executed to generate all XML files:</p>
+
+<pre class="prettyprint">
+# device manifest; only when DEVICE_MANIFEST_FILE is set
+BOARD_SEPOLICY_VERS=10000.0 assemble_vintf \
+ -i device/manufacturer/device_name/manifest.xml \
+ -o $(TARGET_OUT_VENDOR)/manifest.xml
+
+# device compatibility matrix; only when DEVICE_MATRIX_FILE is set
+assemble_vintf \
+ -i device/manufacturer/device_name/compatibility_matrix.xml \
+ -o $(TARGET_OUT_VENDOR)/compatibility_matrix.xml
+
+# framework manifest
+assemble_vintf
+ -i system/libhidl/manifest.xml \
+ -o $(TARGET_OUT)/manifest.xml \
+ -c $(TARGET_OUT_VENDOR)/compatibility_matrix.xml
+
+# framework compatibility matrix
+BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
+POLICYVERS=$(POLICYVERS) \
+BOARD_AVB_VBMETA_VERSION=$(BOARD_AVB_VBMETA_VERSION)
+assemble_vintf \
+ -i hardware/interfaces/compatibility_matrix.xml \
+ -o $(TARGET_OUT)/compatibility_matrix.xml \
+ -c $(TARGET_OUT_VENDOR)/manifest.xml \
+</pre>
+
+<p>For details, see:</p>
+
+<pre class="devsite-terminal">assemble_vintf --help</pre>
+
+<h2 id="testing">Testing</h2>
+<p>The <code>platform/system/libvintf</code> project uses
+<a href="https://github.com/google/googletest" class="external">GTest</a> for
+the serialization, deserialization, and compatibility checking.</p>
+
+<h2 id="licensing">Licensing</h2>
+<ul>
+<li><code>tinyxml2</code> (external/tinyxml2) for serializing/deserializing the
+object to/from XML. BSD-like license.</li>
+<li><code>libselinux</code> (external/selinux/libselinux) for getting policydb
+version. Public domain license.</li>
+<li><code>libz</code> (external/zlib) for decompressing
+<code>/proc/config.gz</code>. BSD-like license.</li>
+<li><code>libvintf</code> project uses Apache 2.0 license (with appropriate
+MODULE_LICENSE_APACHE2 and NOTICE files).</li>
+</ul>
+
+<h2 id="caveats">Caveats</h2>
+<p>It is also possible to determine the HALs at runtime by querying
+<code>hwservicemanager</code> (as <code>lshal</code> does). However:</p>
+<ul>
+<li><code>hwservicemanager</code> does not list passthrough services.</li>
+<li>If a service has just crashed and is restarting, it may be missing from the
+query result.</li>
+<li>It doesn't work for hot pluggable services.</li>
+<li><code>hwservicemanager</code> is not available in recovery mode (see
+below).</li>
+</ul>
+
+<p>In recovery mode, the API to retrieve the vendor interface object must still
+be available to allow the device to check the vendor interface against the
+compatibility matrix again.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/deftool.html b/en/devices/architecture/vndk/deftool.html
new file mode 100644
index 00000000..bfed22c4
--- /dev/null
+++ b/en/devices/architecture/vndk/deftool.html
@@ -0,0 +1,433 @@
+<html devsite>
+ <head>
+ <title>VNDK Definition Tool</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>
+The VNDK definition tool helps vendors migrate their source tree to an Android O
+environment. This tool scans binary files in the system and vendor images then
+resolves dependencies. Based on the module dependency graph, the tool can also
+detect violations to VNDK concepts and provide insight/suggestions for moving
+modules between partitions. If an AOSP system image is specified, the VNDK
+definition tool can compare your system image with the AOSP system image and
+determine the extended libraries.
+</p>
+<p>
+This section covers three frequently used commands for the VNDK definition tool:
+</p>
+<ul>
+<li><code>vndk</code>. Compute VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES, and
+EXTRA_VENDOR_LIBRARIES for build system workaround in Android O.</li>
+<li><code>check-dep</code>. Check the violating module dependencies from vendor
+modules to non-eligible framework shared libraries.</li>
+<li><code>deps</code>. Print the dependencies between the shared libraries and
+executables.</li>
+</ul>
+
+<p>For more details on advanced command usage, refer to
+<a href="https://android.googlesource.com/platform/development/+/master/vndk/tools/definition-tool/README.md" class="external">README.md</a>
+file in the VNDK Definition Tool repository.</p>
+
+<h2 id="vndk">vndk</h2>
+<p>The <code>vndk</code> subcommand loads the shared libraries and executables
+from the system partition and vendor partitions, then resolves module
+dependencies to determine the libraries that must be copied to
+<code>/system/lib[64]/vndk-sp</code> and <code>/vendor/lib[64]</code>. Options
+for the <code>vndk</code> subcommand include:</p>
+
+<table>
+ <tr>
+ <th>Option</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>--system</code>
+ </td>
+ <td>Point to a directory containing the files that will reside in the system
+partition.
+ </td>
+ </tr>
+ <tr>
+ <td><code>--vendor</code>
+ </td>
+ <td>Point to a directory containing the files that will reside in a vendor
+partition.
+ </td>
+ </tr>
+ <tr>
+ <td><code>--aosp-system</code>
+ </td>
+ <td>Point to a directory containing the files that will reside in the AOSP
+system image.
+ </td>
+ </tr>
+ <tr>
+ <td><code>--load-extra-deps</code>
+ </td>
+ <td>Point to a file that describes the implicit dependencies, such as
+<code>dlopen()</code>.
+ </td>
+ </tr>
+</table>
+
+<p>For example, to compute the VNDK library sets, run the following
+<code>vndk</code> subcommand:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">./vndk_definition_tool.py vndk \</code>
+ --system ${ANDROID_PRODUCT_OUT}/system \
+ --vendor ${ANDROID_PRODUCT_OUT}/vendor \
+ --aosp-system ${ANDROID_PRODUCT_OUT}/../generic_arm64_ab/system\
+ --load-extra-deps dlopen.dep
+</pre>
+
+<p>Specify extra dependencies with a simple file format. Each line represents a
+relationship, with the file before the colon depending on the file after the
+colon. For example:</p>
+
+<pre class="prettyprint">/system/lib/libart.so: /system/lib/libart-compiler.so</pre>
+
+<p>This line lets the VNDK definition tool know that <code>libart.so</code>
+depends on <code>libart-compiler.so</code>.
+</p>
+
+<h3 id="installation-destination">Installation destination</h3>
+<p>VNDK definition tool lists libraries and corresponding install directories
+for the following categories:</p>
+
+<table>
+ <tr>
+ <th>Category</th>
+ <th>Directory</th>
+ </tr>
+ <tr>
+ <td>vndk_sp
+ </td>
+ <td>Must install to <code>/system/lib[64]/vndk-sp</code>
+ </td>
+ </tr>
+ <tr>
+ <td>vndk_sp_ext
+ </td>
+ <td>Must install to <code>/vendor/lib[64]/vndk-sp</code>
+ </td>
+ </tr>
+ <tr>
+ <td>extra_vendor_libs
+ </td>
+ <td>Must install to <code>/vendor/lib[64]</code>
+ </td>
+ </tr>
+</table>
+
+<h3 id="build-system-templates">Build system templates</h3>
+<p>After gathering outputs from VNDK definition tool, a vendor can create an
+<code>Android.mk</code> and fill in <code>VNDK_SP_LIBRARIES</code>,
+<code>VNDK_SP_EXT_LIBRARIES</code> and <code>EXTRA_VENDOR_LIBRARIES</code> to
+automate the process to copy libraries to the designated installation
+destination.</p>
+
+<pre class="prettyprint">ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
+VNDK_SP_LIBRARIES := ##_VNDK_SP_##
+VNDK_SP_EXT_LIBRARIES := ##_VNDK_SP_EXT_##
+EXTRA_VENDOR_LIBRARIES := ##_EXTRA_VENDOR_LIBS_##
+
+#-------------------------------------------------------------------------------
+# VNDK Modules
+#-------------------------------------------------------------------------------
+LOCAL_PATH := $(call my-dir)
+
+define define-vndk-lib
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.$2
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
+LOCAL_STRIP_MODULE := false
+LOCAL_MULTILIB := first
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := $3
+LOCAL_VENDOR_MODULE := $4
+include $$(BUILD_PREBUILT)
+
+ifneq ($$(TARGET_2ND_ARCH),)
+ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.$2
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$($$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
+LOCAL_STRIP_MODULE := false
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := $3
+LOCAL_VENDOR_MODULE := $4
+include $$(BUILD_PREBUILT)
+endif # TARGET_TRANSLATE_2ND_ARCH is not true
+endif # TARGET_2ND_ARCH is not empty
+endef
+
+$(foreach lib,$(VNDK_SP_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-sp-gen,vndk-sp,)))
+$(foreach lib,$(VNDK_SP_EXT_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-sp-ext-gen,vndk-sp,true)))
+$(foreach lib,$(EXTRA_VENDOR_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-ext-gen,,true)))
+
+
+#-------------------------------------------------------------------------------
+# Phony Package
+#-------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(YOUR_DEVICE_NAME)-vndk
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := \
+ $(addsuffix .vndk-sp-gen,$(VNDK_SP_LIBRARIES)) \
+ $(addsuffix .vndk-sp-ext-gen,$(VNDK_SP_EXT_LIBRARIES)) \
+ $(addsuffix .vndk-ext-gen,$(EXTRA_VENDOR_LIBRARIES))
+include $(BUILD_PHONY_PACKAGE)
+
+endif # ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
+</pre>
+
+<h2 id="check-dep">check-dep</h2>
+<p>The <code>check-dep</code> subcommand scans vendor modules and checks their
+dependencies. If it detects violations, it prints the violating dependant
+library and symbol usages:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">./vndk_definition_tool.py check-dep \</code>
+ --system ${ANDROID_PRODUCT_OUT}/system \
+ --vendor ${ANDROID_PRODUCT_OUT}/vendor \
+ --tag-file eligible-list.csv \
+ --module-info ${ANDROID_PRODUCT_OUT}/module-info.json \
+ 1> check_dep.txt \
+ 2> check_dep_err.txt
+</pre>
+
+<p>For example, the following sample output shows a violating dependency from
+<code>libRS_internal.so</code> to <code>libmediandk.so</code>:</p>
+
+<pre class="prettyprint">
+/system/lib/libRS_internal.so
+ MODULE_PATH: frameworks/rs
+ /system/lib/libmediandk.so
+ AImageReader_acquireNextImage
+ AImageReader_delete
+ AImageReader_getWindow
+ AImageReader_new
+ AImageReader_setImageListener
+</pre>
+
+<p>Options for the <code>check-dep</code> subcommand include:</p>
+
+<table>
+ <tr>
+ <th style="width:25%">Option</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>--tag-file</code>
+ </td>
+ <td>Must refer to an eligible library tag file (described below), which is a
+Google-provided spreadsheet that described categories of framework shared
+libraries.
+ </td>
+ </tr>
+ <tr>
+ <td><code>--module-info</code>
+ </td>
+ <td>Points to the <code>module-info.json</code> generated by Android build
+system. It helps the VNDK definition tool associate binary modules with source
+code.
+ </td>
+ </tr>
+</table>
+
+<h3 id="eligible-library-tag-file">Eligible library tag file</h3>
+<p>Google provides an eligible VNDK spreadsheet (e.g.
+<code>eligible-list.csv</code>) that tags the framework shared libraries that
+can be used by vendor modules:</p>
+
+<table>
+ <tr>
+ <th style="width:25%">Tag</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>LL-NDK</td>
+ <td>Low-level NDK libraries that can be used by both framework and vendor
+modules.</td>
+ </tr>
+ <tr>
+ <td>LL-NDK-Indirect</td>
+ <td>Private dependencies of LL-NDK libraries. Vendor modules must not access
+these libraries directly.</td>
+ </tr>
+ <tr>
+ <td>SP-NDK</td>
+ <td>Same-process NDK libraries that can be used by both framework and vendor
+modules.</td>
+ </tr>
+ <tr>
+ <td>SP-NDK-Indirect</td>
+ <td>Private dependencies of SP-NDK libraries. Vendor modules must not access
+these libraries directly.</td>
+ </tr>
+ <tr>
+ <td>VNDK-SP</td>
+ <td>SP-HAL framework shared libraries dependencies.</td>
+ </tr>
+ <tr>
+ <td>VNDK-SP-Indirect</td>
+ <td>VNDK-SP dependencies that are not directly accessible to SP-HAL, but can
+be accessed by other vendor modules (except SP-HAL and SP-HAL-Dep)</td>
+ </tr>
+ <tr>
+ <td>VNDK-SP-Indirect-Private</td>
+ <td>VNDK-SP dependencies that are not directly accessible to all vendor
+modules.</td>
+ </tr>
+ <tr>
+ <td>VNDK</td>
+ <td>Framework shared libraries that are available to vendor modules (except
+SP-HAL and SP-HAL-Dep).</td>
+ </tr>
+ <tr>
+ <td>FWK-ONLY</td>
+ <td>Framework-only shared libraries that must not be accessed by vendor
+modules (neither directly nor indirectly).</td>
+ </tr>
+ <tr>
+ <td>FWK-ONLY-RS</td>
+ <td>Framework-only shared libraries that must not be accessed by vendor
+modules (except for RS usages).</td>
+ </tr>
+</table>
+
+<p>The following table describes tags used for vendor shared libraries:</p>
+
+<table>
+ <tr>
+ <th style="width:25%">Tag</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>SP-HAL</td>
+ <td>Same-process HAL implementation shared libraries.</td>
+ </tr>
+ <tr>
+ <td>SP-HAL-Dep</td>
+ <td>SP-HAL vendor shared libraries dependencies (a.k.a. SP-HAL dependencies
+excluding LL-NDK, SP-NDK, and VNDK-SP)</td>
+ </tr>
+ <tr>
+ <td>VND-ONLY</td>
+ <td>Framework-invisible shared libraries that must not be accessed by
+framework modules. The copied extended VNDK libraries will be tagged as VND-ONLY
+as well.</td>
+ </tr>
+</table>
+
+<p>Relationships between tags:</p>
+
+<img src="../images/treble_vndk_design.png">
+<figcaption><strong>Figure 1.</strong> Relationships between tags.</figcaption>
+
+<h2 id="deps">deps</h2>
+<p>To debug the library dependencies, the <code>deps</code> subcommand prints
+the module dependencies:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">./vndk_definition_tool.py deps \</code>
+ --system ${ANDROID_PRODUCT_OUT}/system \
+ --vendor ${ANDROID_PRODUCT_OUT}/vendor
+</pre>
+
+<p>The output consists of multiple lines. The line without a tab character
+starts a new section. The line with a tab character depends on the preceding
+section. For example:</p>
+
+<pre class="prettyprint">
+/system/lib/ld-android.so
+/system/lib/libc.so
+ /system/lib/libdl.so
+</pre>
+
+<p>This output shows that <code>ld-android.so</code> does not have a dependency
+and <code>libc.so</code> depends on <code>libdl.so</code>.</p>
+
+<p>When specifying the <code>--revert</code> option, <code>deps</code>
+subcommand prints the <strong>usages of libraries</strong> (reversed
+dependencies):</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">./vndk_definition_tool.py deps \</code>
+ --revert \
+ --system ${ANDROID_PRODUCT_OUT}/system \
+ --vendor ${ANDROID_PRODUCT_OUT}/vendor</pre>
+
+<p>For example:</p>
+
+<pre class="prettyprint">
+/system/lib/ld-android.so
+ /system/lib/libdl.so
+ </pre>
+
+<p>This output shows that <code>ld-android.so</code> is used by
+<code>libdl.so</code>, or in other words, <code>libdl.so</code> depends on
+<code>ld-android.so</code>. In addition, this output shows that
+<code>libdl.so</code> is the sole user of <code>ld-android.so</code>.</p>
+
+<p>When specifying the <code>--symbol</code> option, the <code>deps</code>
+subcommand prints the symbols being used:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">./vndk_definition_tool.py deps \</code>
+ --symbol \
+ --system ${ANDROID_PRODUCT_OUT}/system \
+ --vendor ${ANDROID_PRODUCT_OUT}/vendor
+ </pre>
+
+<p>For example:</p>
+
+<pre class="prettyprint">
+/system/lib/libc.so
+ /system/lib/libdl.so
+ android_get_application_target_sdk_version
+ dl_unwind_find_exidx
+ dlclose
+ dlerror
+ dlopen
+ dlsym
+</pre>
+
+<p>This output shows that <code>libc.so</code> depends on 6 functions exported
+from <code>libdl.so</code>. If both the <code>--symbol</code> option and
+<code>--revert</code> option are specified, the symbols used by the user
+will be printed.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/dir-rules-sepolicy.html b/en/devices/architecture/vndk/dir-rules-sepolicy.html
new file mode 100644
index 00000000..0cc2ceae
--- /dev/null
+++ b/en/devices/architecture/vndk/dir-rules-sepolicy.html
@@ -0,0 +1,189 @@
+<html devsite>
+ <head>
+ <title>Directories, Rules, and sepolicy</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>This page describes the directory layout for devices running Android O, VNDK
+rules, and associated sepolicy.</p>
+
+<h2 id="directory">Directory layout</h2>
+<p>The <em>Degenerated Directory Layout</em> consists of the following
+directories:</p>
+<ul>
+<li><code>/system/lib[64]</code> contains all framework shared libraries,
+including LL-NDK, SP-NDK, VNDK, and framework-only libraries (including
+LL-NDK-Indirect, SP-NDK-Indirect, and some libraries with the same names as the
+ones in VNDK-SP).</li>
+<li><code>/system/lib[64]/vndk-sp</code> contains VNDK-SP libraries for
+same-process HALs.</li>
+<li><code>/vendor/lib[64]</code> contains the extended VNDK libraries (either
+DXUA or DXUX VNDK libraries), same-process HAL implementations, and other vendor
+shared libraries.</li>
+<li><code>/vendor/lib[64]/vndk-sp</code> may contain extra libraries that are
+used by VNDK-SP libraries.</li>
+</ul>
+
+<p>Vendor modules load the VNDK libraries from <code>/system/lib[64]</code>.</p>
+
+<h2 id="rules">VNDK rules</h2>
+<p>This section provides a comprehensive list of VNDK rules:</p>
+
+<ul>
+<li>Framework processes must not load non-SP-HAL shared libraries from vendor
+partitions (not strictly enforced in Android O but will be in a future release).
+</li>
+<li>Vendor processes must not load non-LL-NDK, non-SP-NDK, non-VNDK-SP, and
+non-VNDK libraries from the system partition. (not strictly enforced in Android
+O but will be in a future release).</li>
+
+<p class="note"><strong>NOTE</strong>: To benefit from the framework-only OTA
+beyond Android O, this rule must not be violated in devices launched with
+Android O.</p>
+
+<li>Installed VNDK libraries must be a subset of Google-defined eligible VNDK
+libraries.</li>
+<li>The outer dependencies of SP-HAL and SP-HAL-Dep must be restricted to
+LL-NDK, SP-NDK, or Google-defined VNDK-SP libraries.
+ <ul>
+ <li>The dependencies of an SP-HAL shared library must be restricted to LL-NDK
+ libraries, SP-NDK libraries, SP-NDK libraries, Google-defined VNDK-SP
+ libraries, other SP-HAL libraries, and/or other vendor shared libraries that
+ can be labeled as SP-HAL-Dep libraries.</li>
+ <li>A vendor shared library can be labeled as a SP-HAL-Dep library only if it
+ is not an AOSP library and its dependencies are restricted to LL-NDK libraries,
+ SP-NDK libraries, Google-defined VNDK-SP libraries, SP-HAL libraries, and/or
+ other SP-HAL-Dep libraries.</li>
+ </ul>
+</li>
+<li>VNDK-SP must be self-contained. <code>libRS_internal.so</code> gets special
+treatment in Android O, but will be revisited in a future release.</li>
+<li>No framework-vendor communication through non-HIDL interfaces, including
+(but not limited to) binder, sockets, shared memories, files, etc.</li>
+<li>The size of the system partition must be large enough to contain two copies
+of all eligible VNDK libraries and a copy of ineligible framework shared
+libraries.</li>
+</ul>
+
+<h2 id="sepolicy">sepolicy</h2>
+<p>Framework processes described in this section correspond to
+<code>coredomain</code> in sepolicies while vendor processes correspond to
+<code>non-coredomain</code>. For example, <code>/dev/binder</code> can be
+accessed only in <code>coredomain</code> and <code>/dev/vndbinder</code> can be
+accessed only in non-<code>coredomain</code>.</p>
+
+<p>Similar policies restrict the access to the shared libraries on system and
+vendor partitions. The following table shows the rights to access shared
+libraries of different categories:</p>
+
+<table>
+ <tr>
+ <th style="width:35%">Category</th>
+ <th>Partition</th>
+ <th>Accessible from<br>coredomain</th>
+ <th>Accessible from<br>non-coredomain</th>
+ </tr>
+ <tr>
+ <td>LL-NDK</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>LL-NDK-Indirect</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>SP-NDK</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>SP-NDK-Indirect</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>VNDK-SP/VNDK-SP-Indirect/VNDK-SP-Indirect-Private</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>VNDK-SP-Ext/VNDK-SP-Indirect-Ext</td>
+ <td>Vendor</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>VNDK</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>VNDK-Ext</td>
+ <td>Vendor</td>
+ <td>N</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>FWK-ONLY</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>N</td>
+ </tr>
+ <tr>
+ <td>FWK-ONLY-RS</td>
+ <td>System</td>
+ <td>Y</td>
+ <td>N</td>
+ </tr>
+ <tr>
+ <td>SP-HAL</td>
+ <td>Vendor</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>SP-HAL-Dep</td>
+ <td>Vendor</td>
+ <td>Y</td>
+ <td>Y</td>
+ </tr>
+ <tr>
+ <td>VND-ONLY</td>
+ <td>Vendor</td>
+ <td>N</td>
+ <td>Y</td>
+ </tr>
+</table>
+
+<p>LL-NDK-Indirect, SP-NDK-Indirect, VNDK-SP-Indirect, and
+VNDK-SP-Indirect-Private must be accessible from both domains because
+non-<code>coredomain</code> will indirectly access them. Similarly, SP-HAL-Dep
+must be accessible from <code>coredomain</code> because SP-HAL relies on it.</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/extensions.html b/en/devices/architecture/vndk/extensions.html
new file mode 100644
index 00000000..2cc895c7
--- /dev/null
+++ b/en/devices/architecture/vndk/extensions.html
@@ -0,0 +1,150 @@
+<html devsite>
+ <head>
+ <title>VNDK Extensions</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 device manufacturers change the source code of AOSP libraries for
+various reasons. Some vendors reimplement functions in AOSP libraries to
+boost the performance while other vendors add new hooks, new APIs, or new
+functionalities to AOSP libraries. This section provides guidelines for
+extending AOSP libraries in a way that does not break CTS/VTS.</p>
+
+<h2 id="drop-in-replacement">Drop-in replacement</h2>
+<p>All modified shared libraries must be <strong>binary-compatible</strong>,
+<strong>drop-in replacements</strong> of their AOSP counterpart. All existing
+AOSP users must be able to use the modified shared library without
+recompilations. This requirement implies the following:</p>
+<ul>
+<li>AOSP functions must not be removed.</li>
+<li>Structures must not be altered if such structures are exposed to their
+users.</li>
+<li>Pre-condition of functions must not be strengthened.</li>
+<li>Functions must provide equivalent functionalities.</li>
+<li>Post-condition of functions must not be weakened.</li>
+</ul>
+
+<h2 id="extended-module-classifications">Extended module classifications</h2>
+<p>Classify modules by the functionalities they <strong>define</strong> and
+<strong>use</strong>.</p>
+<p class="note"><strong>Note</strong>: <em>Functionalities</em> is used here
+instead of API/ABI because it is possible to add functionality without changing
+any API/ABI.</p>
+
+<p>Depending on the functionalities defined in a module, modules can be
+classified into <strong>DA-Module</strong> and <strong>DX-Module</strong>:</p>
+<ul>
+<li><em>Defining-only-AOSP Modules (DA-Module)</em> do not define new
+functionalities which were not in the AOSP counterpart.
+ <ul>
+ <li><em>Example 1.</em> An intact unmodified AOSP library is a DA-Module.</li>
+ <li><em>Example 2.</em> If a vendor rewrites the functions in
+ <code>libcrypto.so</code> with SIMD instructions (without adding new
+ functions), then the modified <code>libcrypto.so</code> will be a DA-Module.
+ </li>
+ </ul>
+</li>
+<li><em>Defining-Extension Modules (DX-Module)</em> either define new
+functionalities or do not have an AOSP counterpart.
+ <ul>
+ <li><em>Example 1.</em> If a vendor adds a helper function to
+ <code>libjpeg.so</code> to access some internal data, then the modified
+ <code>libjpeg.so</code> will be a DX-Lib and the newly added function will be
+ the extended portion of the library.</li>
+ <li><em>Example 2.</em> If a vendor defines a non-AOSP library named
+ <code>libfoo.so</code>, then <code>libfoo.so</code> will be a DX-Lib.</li>
+ </ul>
+</li>
+</ul>
+
+<p>Depending on the functionalities used by a module, modules can be classified
+into <strong>UA-Module</strong> and <strong>UX-Module</strong>.</p>
+<ul>
+<li><em>Using-only-AOSP Modules (UA-Module)</em> only use AOSP functionalities
+in their implementations. They do not rely on any non-AOSP extensions.
+ <ul>
+ <li><em>Example 1.</em> An intact unmodified AOSP library is an UA-Module.</li>
+ <li><em>Example 2.</em> If a modified shared library <code>libjpeg.so</code>
+ only relies on other AOSP APIs, then it will be an UA-Module.</li>
+ </ul>
+</li>
+<li><em>Using-Extension Modules (UX-Module)</em> rely on some non-AOSP
+functionalities in their implementations.
+ <ul>
+ <li><em>Example 1.</em> If a modified <code>libjpeg.so</code> relies on another
+ non-AOSP library named <code>libjpeg_turbo2.so</code>, then the modified
+ <code>libjpeg.so</code> will be an UX-Module.</li>
+ <li><em>Example 2.</em> If a vendor adds a new function to their modified
+ <code>libexif.so</code> and their modified <code>libjpeg.so</code> uses the
+ newly added function from <code>libexif.so</code>, then their modified
+ <code>libjpeg.so</code> will be an UX-Module.</li>
+ </ul>
+</li>
+</ul>
+
+<p>Definitions and usages are independent from each other:</p>
+<table>
+ <tr>
+ <td rowspan="2" colspan="2" class="columns"></td>
+ <th colspan="2">Used Functionalities</th>
+ </tr>
+ <tr>
+ <td>Only AOSP (UA)</td>
+ <td>Extended (UX)</td>
+ </tr>
+ <tr>
+ <th rowspan="2">Defined Functionalities</th>
+ <td>Only AOSP (DA)</td>
+ <td>DAUA</td>
+ <td>DAUX</td>
+ </tr>
+ <tr>
+ <td>Extended (DX)</td>
+ <td>DXUA</td>
+ <td>DXUX</td>
+ </tr>
+</table>
+
+<h2 id="vndk-extension-mechanism">VNDK extension mechanism</h2>
+<p>
+Vendor modules that rely on extended functionalities won't work because the AOSP
+library with the same name does not have the extended functionality. If vendor
+modules directly or indirectly depend on extended functionalities, vendors
+should copy DAUX, DXUA, and DXUX shared libraries to the vendor partition
+(vendor processes always look for shared libraries in the vendor partition
+first). However, LL-NDK and SP-NDK libraries must not be copied, so vendor
+modules must not rely on the extended functionalities defined by the modified
+LL-NDK and SP-NDK libraries.
+</p>
+<p>
+DAUA shared libraries can remain on the system partition if the corresponding
+AOSP library can provide the same functionality and vendor modules continue to
+work when the system partition is overwritten by an AOSP system image.
+</p>
+<p>
+Drop-in replacement is important because the unmodified VNDK libraries in the
+AOSP system image will link with the modified shared libraries on name
+collision. If the AOSP libraries are modified in an API/ABI incompatible manner,
+the AOSP libraries in the AOSP system image might fail to link or result in
+undefined behaviors.
+</p>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/index.html b/en/devices/architecture/vndk/index.html
new file mode 100644
index 00000000..a0d4af59
--- /dev/null
+++ b/en/devices/architecture/vndk/index.html
@@ -0,0 +1,267 @@
+<html devsite>
+ <head>
+ <title>Vendor Native Development Kit (VNDK)</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>The Vendor Native Development Kit (VNDK) is a set of libraries
+exclusively for vendors to implement their HALs. The VNDK ships in
+<code>system.img</code> and is dynamically linked to vendor code at runtime.</p>
+
+<h2 id=why-vndk>Why VNDK?</h2>
+<p>Android O enables framework-only updates in which the system partition can be
+upgraded to the latest version while vendor partitions are left unchanged. This
+implies that binaries built at different times must be able to work with each
+other; VNDK covers API/ABI changes across Android releases.</p>
+
+<p>Framework-only updates include the following challenges:</p>
+
+<ul>
+<li><strong>Dependency between framework modules and vendor modules</strong>.
+Before Android O, modules from both sides could link with modules from the other
+side. However, dependencies from vendor modules imposed undesired restrictions
+to framework modules development.</li>
+<li><strong>Extensions to AOSP libraries</strong>. Android O requires all
+Android devices to pass CTS when the system partition is replaced with a
+standard AOSP system image. However, as vendors extend AOSP libraries to boost
+performance or to add extra functionalities for their HIDL implementations,
+flashing the system partition with a standard AOSP system image might break a
+vendor's HIDL implementation. (For guidelines on preventing such breakages, see
+<a href="/devices/architecture/vndk/extensions.html">VNDK extensions</a>.)</li>
+</ul>
+
+<p>To address these challenges, Android O introduces several techniques such as
+VNDK (described in this section),
+<a href="/devices/architecture/hidl/index.html">HIDL</a>, hwbinder,
+<a href="/devices/architecture/dto/index.html">device tree overlay</a>, and
+sepolicy overlay.</p>
+
+<h2 id=resources>VNDK resources</h2>
+<p>This section includes the following VNDK resources:</p>
+<ul>
+<li><em><a href="#vndk-concepts">VNDK concepts</a></em> (below) describes
+framework shared libraries, same-process HALs (SP-HALs), and VNDK terminology.
+</li>
+<li><em><a href="/devices/architecture/vndk/extensions.html">VNDK
+extensions</a></em> classifies vendor-specific changes into categories. For
+example, libraries with extended functionalities on which vendor modules rely
+must be copied into the vendor partition, but ABI-incompatible changes are
+prohibited.</li>
+<li>The <em><a href="/devices/architecture/vndk/deftool.html">VNDK Definition
+Tool</a></em> helps migrate your source tree to Android O.</li>
+<li>The <em><a href="/devices/architecture/vndk/linker-namespace.html">Linker
+Namespace</a></em> provides fine-grained control over shared library linkages.
+</li>
+<li><em><a href="/devices/architecture/vndk/dir-rules-sepolicy.html">Directories,
+Rules, and sepolicy</a></em> defines the directory structure for devices running
+Android O, VNDK rules, and associated sepolicy.</li>
+<li>The <em><a href="../images/vndk_design_android_o.pdf">VNDK Design in Android
+O</a></em> presentation illustrates fundamental VDNK concepts used in Android
+O.</li>
+</ul>
+
+<h2 id="concepts">VNDK concepts</h2>
+<p>In an ideal Android O world, framework processes do not load vendor shared
+libraries, all vendor processes load only vendor shared libraries (and a portion
+of framework shared libraries), and communications between framework processes
+and vendor processes are governed by HIDL and hardware binder.</p>
+
+<p>Such a world includes the possibility that stable, public APIs from
+framework shared libraries might not be sufficient for vendor module developers
+(although APIs can change between Android releases), requiring that some portion
+of framework shared libraries be accessible to vendor processes. In addition, as
+performance requirements can lead to compromises, some response-time-critical
+HALs must be treated differently.</p>
+
+<p>The following sections detail how VNDK handles framework shared libraries for
+vendors and Same-Process HALs (SP-HALs).</p>
+
+<h3 id="framework-shared-libraries">Framework shared libraries for vendor</h3>
+<p>This section describes the criteria for classifying shared libraries that are
+accessible to vendor processes. There are two approaches to support vendor
+modules across multiple Android releases:</p>
+
+<ol>
+<li><strong>Stabilize the ABIs/APIs of the framework shared libraries</strong>.
+New framework modules and old vendor modules can use the same shared library to
+reduce memory footprint and storage size. A unique shared library also avoids
+several double-loading issues. However, the development cost to maintain stable
+ABIs/APIs is high and it is unrealistic to stabilize all ABIs/APIs exported by
+every framework shared library.</li>
+<li><strong>Copy old framework shared libraries</strong>. Comes with the strong
+restriction against side channels, defined as all mechanisms to communicate
+among framework modules and vendor modules, including (but not limited to)
+binder, socket, pipe, shared memory, shared file, and system properties. There
+must be no communication unless the communication protocol is frozen and stable
+(e.g. HIDL through hwbinder). Double-loading shared libraries might cause
+problems as well; for example, if an object created by the new library is passed
+into the functions from the old library, an error may occur as these libraries
+may interpret the object differently.</li>
+</ol>
+
+<p>Different approaches are used depending on the characteristics of the shared
+libraries. As a result, framework shared libraries are classified into three
+sub-categories:</p>
+
+<ul>
+<li><em>LL-NDK</em> and <em>SP-NDK</em> are <em>Framework Shared Libraries</em>
+that are known to be stable. Their developers are committed to maintain their
+API/ABI stabilities.
+ <ul>
+ <li>LL-NDK includes the following libraries: <code>libandroid_net.so</code>,
+ <code>libc.so</code>, <code>libstdc++.so</code>, <code>libdl.so</code>,
+ <code>liblog.so</code>, <code>libm.so</code>, <code>libz.so</code>, and
+ <code>libvndksupport.so</code>.</li>
+ <li>SP-NDK includes the following libraries: <code>libEGL.so</code>,
+ <code>libGLESv1_CM.so</code>, <code>libGLESv2.so</code>,
+ <code>libGLESv3.so</code>, <code>libvulkan.so</code>,
+ <code>libnativewindow.so</code>, and <code>libsync.so</code>.</li>
+ </ul>
+</li>
+<li><em>Eligible VNDK Libraries (VNDK)</em> are <em>Framework Shared
+Libraries</em> that are safe to be copied twice. <em>Framework Modules</em> and
+<em>Vendor Modules</em> can link with their own copies. A framework shared
+library can become an eligible VNDK library only if it satisfies the following
+criteria:
+ <ul>
+ <li>It does not send/receive IPCs to/from the framework.</li>
+ <li>It is not related to ART virtual machine.</li>
+ <li>It does not read/write files/partitions with unstable file formats.</li>
+ <li>It does not have special software license which requires legal reviews.</li>
+ <li>Its code owner does not have objections to vendor usages.</li>
+ </ul>
+</li>
+<li><em>Framework-Only Libraries (FWK-ONLY)</em> are <em>Framework Shared
+Libraries</em> that do not belong to the categories mentioned above. These
+libraries:
+ <ul>
+ <li>Are considered framework internal implementation details.</li>
+ <li>Must not be accessed by vendor modules.</li>
+ <li>Have unstable ABIs/APIs and no API/ABI compatibility guarantees.</li>
+ <li>Are not copied.</li>
+ </ul>
+</li>
+</ul>
+
+<h3 id="sp-hal">Same-Process HAL (SP-HAL)</h3>
+<p>
+<em>Same-Process HAL</em> (<em>SP-HAL</em>) is a set of predetermined HALs
+implemented as <em>Vendor Shared Libraries</em> and loaded into <em>Framework
+Processes</em>. SP-HALs are isolated by a linker namespace (controls the
+libraries and symbols that are visible to the shared libraries). SP-HALs must
+depend only on <em>LL-NDK</em>, <em>SP-NDK</em>, and <em>VNDK-SP</em>.</p>
+
+<p>VNDK-SP is a predefined subset of eligible VNDK libraries. VNDK-SP libraries
+are carefully reviewed to ensure double-loading VNDK-SP libraries into framework
+processes does not cause problems. Both SP-HALs and VNDK-SPs are defined by
+Google.</p>
+
+<p>The following libraries are approved SP-HALs:</p>
+
+<ul>
+<li><code>libGLESv2_${driver}.so</code></li>
+<li><code>libGLESv1_CM_${driver}.so</code></li>
+<li><code>libEGL_${driver}.so</code></li>
+<li><code>vulkan.${driver}.so</code></li>
+<li><code>android.hardware.renderscript@1.0-impl.so</code></li>
+<li><code>android.hardware.graphics.mapper@2.0-impl.so</code></li>
+</ul>
+
+<p>The following libraries are VNDK-SP libraries that are accessible by SP-HALs:
+</p>
+
+<ul>
+<li><code>android.hardware.graphics.allocator@2.0.so</code></li>
+<li><code>android.hardware.graphics.common@1.0.so</code></li>
+<li><code>android.hardware.graphics.mapper@2.0.so</code></li>
+<li><code>android.hardware.renderscript@1.0.so</code> (Renderscript)</li>
+<li><code>libRS_internal.so</code> (Renderscript)</li>
+<li><code>libbase.so</code></li>
+<li><code>libc++.so</code></li>
+<li><code>libcutils.so</code></li>
+<li><code>libhardware.so</code></li>
+<li><code>libhidlbase.so</code></li>
+<li><code>libhidltransport.so</code></li>
+<li><code>libhwbinder.so</code></li>
+<li><code>libutils.so</code></li>
+</ul>
+
+<p>
+The following <em>VNDK-SP dependencies (VNDK-SP-Indirect)</em> are invisible to
+<em>SP-HALs</em>:
+</p><ul>
+<li><code>libRSCpuRef.so</code> (Renderscript)</li>
+<li><code>libRSDriver.so</code> (Renderscript)</li>
+<li><code>libbacktrace.so</code></li>
+<li><code>libblas.so</code> (Renderscript)</li>
+<li><code>libbcinfo.so</code> (Renderscript)</li>
+<li><code>liblzma.so</code></li>
+<li><code>libunwind.so</code></li>
+</ul>
+
+<p>The following <em>private VNDK-SP dependency (VNDK-SP-Indirect-Private)</em>
+is invisible to all vendor modules:</p>
+
+<ul>
+<li><code>libcompiler_rt.so</code> (Renderscript)</li>
+</ul>
+
+<p>The following are <em>framework-only libraries with RS exceptions
+(FWK-ONLY-RS)</em>:</p>
+<ul>
+<li><code>libft2.so</code> (Renderscript)</li>
+<li><code>libmediandk.so</code> (Renderscript)</li>
+</ul>
+
+
+<h2 id="vndk-terminology">VNDK terminology</h2>
+<ul>
+<li><em>Modules</em> refer to either <em>Shared Libraries</em> or
+<em>Executables</em>.</li>
+<li><em>Processes</em> are operating system tasks spawned from
+<em>Executables</em>.</li>
+<li><em>Framework</em>-qualified terms refer to the concepts related to the
+<strong>system</strong> partition.</li>
+<li><em>Vendor</em>-qualified terms refer to the concepts related to
+<strong>vendor</strong> partitions.</li>
+</ul>
+
+<p>For example:</p>
+<ul>
+<li><em>Framework Executables</em> refer to executables in
+<code>/system/bin</code> or <code>/system/xbin</code>.</li>
+<li><em>Framework Shared Libraries</em> refer to shared libraries under
+<code>/system/lib[64]</code>.</li>
+<li><em>Framework Modules</em> refer to both <em>Framework Shared Libraries</em>
+and <em>Framework Executables</em>.</li>
+<li><em>Framework Processes</em> are processes spawned from <em>Framework
+Executables</em> (e.g. <code>/system/bin/app_process</code>).</li>
+<li><em>Vendor Executables</em> refer to executables in <code>/vendor/bin</code>
+<li><em>Vendor Shared Libraries</em> refer to shared libraries under
+<code>/vendor/lib[64]</code>.</li>
+<li><em>Vendor Modules</em> refer to both <em>Vendor Executables</em> and
+<em>Vendor Shared Libraries</em>.</li>
+<li><em>Vendor Processes</em> are processes spawned from <em>Vendor
+Executables</em> (e.g.</li>
+<code>/vendor/bin/android.hardware.camera.provider@2.4-service</code>).</li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/linker-namespace.html b/en/devices/architecture/vndk/linker-namespace.html
new file mode 100644
index 00000000..d0ef3421
--- /dev/null
+++ b/en/devices/architecture/vndk/linker-namespace.html
@@ -0,0 +1,154 @@
+<html devsite>
+ <head>
+ <title>Linker Namespace</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>Linker namespace is a mechanism to control the shared library search path and
+the permission to open the libraries in a directory.</p>
+
+<h2 id="framework-processes">Framework processes</h2>
+<h3 id="default-namespace">Default namespace</h3>
+<p>Search paths and permitted paths:</p>
+<ol>
+<li><code>/system/lib[64]</code></li>
+<li><code>/vendor/lib[64]</code> # Deprecated in Android O (for legacy modules
+only)</li>
+</ol>
+
+<h3 id="sp-hal-namespace">SP-HAL namespace</h3>
+<p>Search paths and permitted paths:</p>
+<ol>
+<li><code>/vendor/lib[64]/egl</code></li>
+<li><code>/vendor/lib[64]/hw</code></li>
+<li><code>/vendor/lib[64]</code></li>
+</ol>
+
+<p>Shared libraries imported from other namespaces:</p>
+<ul>
+<li>Exported by <strong>default</strong> namespace:
+ <ul>
+ <li>LL-NDK: <code>libc.so</code>, <code>libm.so</code>, <code>libdl.so</code>,
+ <code>libstdc++.so</code>, <code>liblog.so, libz.so</code></li>
+ <li>SP-NDK: <code>libEGL.so</code>, <code>libGLESv1_CM.so</code>,
+ <code>libGLESv2.so</code>, <code>libnativewindow.so</code>,
+ <code>libsync.so</code>, <code>libvndksupport.so</code></li>
+ </ul>
+</li>
+<li>Exported by <strong>vndk</strong> namespace:
+<code>android.hardware.renderscript@1.0.so</code>,
+<code>android.hardware.graphics.allocator@2.0.so</code>,
+<code>android.hardware.graphics.mapper@2.0.so</code>,
+<code>android.hardware.graphics.common@1.0.so</code>,
+<code>libhwbinder.so</code>, <code>libbase.so</code>, <code>libcutils.so</code>,
+<code>libhardware.so</code>, <code>libhidlbase.so</code>,
+<code>libhidltransport.so</code>, <code>libutils.so</code>,
+<code>libc++.so</code>
+</li>
+<li>Exported by <strong>rs</strong> namespace: <code>libRS_internal.so</code>
+</li>
+</ul>
+
+<h3 id="vndk-vndk-sp-namespace">VNDK (VNDK-SP) namespace</h3>
+<p>Search paths:</p>
+<ol>
+<li><code>/vendor/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]/vndk-sp</code></li>
+<li><code>/vendor/lib[64]</code></li>
+</ol>
+
+<p>Permitted paths:</p>
+<ul>
+<li><code>/vendor/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]/vndk-sp</code></li>
+<li><code>/vendor/lib[64]</code></li>
+<li><code>/vendor/lib[64]/hw</code></li>
+<li><code>/vendor/lib[64]/egl</code></li>
+</ul>
+
+<p>Shared libraries imported from other namespaces:</p>
+<ul>
+<li>Exported by <strong>default</strong> namespace:
+ <ul>
+ <li>LL-NDK: <code>libc.so</code>, <code>libm.so</code>, <code>libdl.so</code>,
+ <code>libstdc++.so</code>, <code>liblog.so</code>,<code> libz.so</code>
+ <li>SP-NDK: <code>libEGL.so</code>, <code>libnativewindow.so</code>,
+ <code>libsync.so</code>, <code>libvndksupport.so</code>
+ </li>
+ </ul>
+</li>
+</ul>
+
+<h3 id="rs-namespace">RS namespace</h3>
+<p>This special namespace allows <code>libRS_internal.so</code> to use
+<code>libmediandk.so</code>, which is not accessible from either SP-HAL
+namespace or VNDK-SP namespace (this is a relaxation in Android O).</p>
+
+<p>Search paths:</p>
+<ol>
+<li><code>/vendor/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]/vndk-sp</code></li>
+<li><code>/vendor/lib[64]</code></li>
+</ol>
+
+<p>Permitted paths:</p>
+<ul>
+<li><code>/vendor/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]/vndk-sp</code></li>
+<li><code>/vendor/lib[64]</code></li>
+<li><code>/data</code> # Shared libraries JIT-compiled by RS CPU reference
+implementation</li>
+</ul>
+
+<p>Shared libraries imported from other namespaces:</p>
+<ul>
+<li>Exported by <strong>default</strong> namespace
+ <ul>
+ <li>LL-NDK: <code>libc.so</code>, <code>libm.so</code>, <code>libdl.so</code>,
+ <code>libstdc++.so</code>, <code>liblog.so</code></li>
+ <li>SP-NDK: <code>libEGL.so</code>, <code>libGLESv1_CM.so</code>,
+ <code>libGLESv2.so</code>, <code>libnativewindow.so</code>,
+ <code>libsync.so</code>, <code>libvndksupport.so</code></li>
+ <li>Other Lib: <code>libmediandk.so</code>, <code>libui.so</code></li>
+ </ul>
+</li>
+<li>Exported by <strong>vndk</strong> namespace:
+<code>android.hardware.renderscript@1.0.so</code>,
+<code>android.hardware.graphics.allocator@2.0.so</code>,
+<code>android.hardware.graphics.mapper@2.0.so</code>,
+<code>android.hardware.graphics.common@1.0.so</code>,
+<code>libhwbinder.so</code>, <code>libbase.so</code>, <code>libcutils.so</code>,
+<code>libhardware.so</code>, <code>libhidlbase.so</code>,
+<code>libhidltransport.so</code>, <code>libutils.so</code>,
+<code>libc++.so</code></li>
+</ul>
+
+<h2 id="vendor-processes">Vendor processes</h2>
+<h3 id="default-linker-namespace">Default linker namespace</h3>
+<p>Search paths and permitted paths:</p>
+<ol>
+<li><code>/vendor/lib[64]</code></li>
+<li><code>/vendor/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]/vndk-sp</code></li>
+<li><code>/system/lib[64]</code> # For degenerated VNDK libraries</li>
+</ol>
+
+ </body>
+</html>
diff --git a/en/devices/architecture/vndk/renderscript.html b/en/devices/architecture/vndk/renderscript.html
new file mode 100644
index 00000000..82f3db16
--- /dev/null
+++ b/en/devices/architecture/vndk/renderscript.html
@@ -0,0 +1,449 @@
+<html devsite>
+ <head>
+ <title>Renderscript</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><em>RenderScript</em> is a framework for running computationally intensive
+tasks at high performance on Android. It is designed for use with data-parallel
+computation, although serial workloads can benefit as well. The RenderScript
+runtime parallelizes work across processors available on a device, such as
+multi-core CPUs and GPUs, enabling developers to focus on expressing algorithms
+rather than scheduling work. RenderScript is especially useful for applications
+performing image processing, computational photography, or computer vision.</p>
+
+<p>Android O devices use the following RenderScript framework and vendor HALs:
+</p>
+<img src="../images/treble_rs_linking.png">
+<figcaption><strong>Figure 1.</strong> Vendor code linking to internal libs.
+</figcaption>
+
+<p>Differences from RenderScript in Android 7.x and earlier include:</p>
+<ul>
+<li>Two instances of RenderScript internal libs in a process. One set is for CPU
+fallback path and is from directly at <code>/system/lib</code>; the other set is
+for GPU path and is from <code>/system/lib/vndk-sp</code>.</li>
+<li>RS internal libs in <code>/system/lib</code> are built as part of the
+platform and are updated as <code>system.img</code> is upgraded. However, libs
+in <code>/system/lib/vndk-sp</code> are built for the vendor and are not updated
+when <code>system.img</code> is upgraded (while they can be updated for a
+security fix, their ABI remains the same).</li>
+<li>Vendor code (RS HAL, RS driver, and the bcc plugin) are linked against the
+RenderScript internal libs located at <code>/system/lib/vndk-sp</code>. They
+cannot link against libs in <code>/system/lib</code> because libs in that
+directory are built for the platform and thus may not be compatible with the
+vendor code (i.e., symbols may be removed). Doing so would make a framework-only
+OTA impossible.</li>
+</ul>
+
+<p>For more details, see
+<a href="https://developer.android.com/guide/topics/renderscript/compute.html" class="external">Renderscript</a>
+on developer.android.com.</p>
+
+<h2 id="design">Design</h2>
+<p>The following sections detail RenderScript design in Android O.</p>
+
+<h3 id="renderscript-libs-available-to-vendors">RenderScript libs available to
+vendors</h3>
+<p>This section lists the RenderScript libs (known as Vendor NDK for
+Same-Process HALs or VNDK-SP) that are available to vendor code and which can be
+linked against. It also details additional libraries that are unrelated to
+RenderScript but which are also provided to vendor code.</p>
+
+<p>While the following list of libraries might differ between Android release,
+it is immutable for a specific Android release; for an up-to-date list of
+available libraries, refer to <code>/system/etc/ld.config.txt</code>.</p>
+
+<aside class="note"><strong>Note:</strong> Libraries not listed below cannot be
+used by any vendor code; i.e. <code>libLLVM.so</code> cannot be used by the
+vendor's bcc plugin as the lib is not in the list.</aside>
+
+<table>
+<tr>
+<th style="width:50%">RenderScript Libs</th>
+<th>Non-RenderScript Libs</th>
+</tr>
+<tr>
+<td><ul>
+<li><code>android.hardware.graphics.renderscript@1.0.so</code></li>
+<li><code>libRS_internal.so</code></li>
+<li><code>libRSCpuRef.so</code></li>
+<li><code>libblas.so</code></li>
+<li><code>libbcinfo.so</code></li>
+<li><code>libcompiler_rt.so</code></li>
+<li><code>libRSDriver.so</code></li>
+</ul></td>
+<td><ul>
+<li><code>libc.so</code></li>
+<li><code>libm.so</code></li>
+<li><code>libdl.so</code></li>
+<li><code>libstdc++.so</code></li>
+<li><code>liblog.so</code></li>
+<li><code>libnativewindow.so</code></li>
+<li><code>libsync.so</code></li>
+<li><code>libvndksupport.so</code></li>
+<li><code>libbase.so</code></li>
+<li><code>libc++.so</code></li>
+<li><code>libcutils.so</code></li>
+<li><code>libutils.so</code></li>
+<li><code>libhardware.so</code></li>
+<li><code>libhidlbase.so</code></li>
+<li><code>libhidltransport.so</code></li>
+<li><code>libhwbinder.so</code></li>
+<li><code>liblzma.so</code></li>
+<li><code>libz.so</code></li>
+<li><code>libEGL.so</code></li>
+<li><code>libGLESv1_CM.so</code></li>
+<li><code>libGLESv2.so</code></li>
+</ul></td>
+ </tr>
+</table>
+
+<h3 id="linker-namespace-configuration">Linker namespace configuration</h3>
+<p>The linking restriction that prevents libs not in VNDK-SP from being used by
+vendor code is enforced at runtime using the linker namespace. (For details,
+refer to the
+<a href="/devices/architecture/images/vndk_design_android_o.pdf">VNDK Design in
+Android O</a> presentation.)</p>
+
+<p>On a device running Android O, all Same-Process HALs (SP-HALs) <em>except
+RenderScript</em> are loaded inside the linker namespace <code>sphal</code>.
+RenderScript is loaded into the RenderScript-specific namespace <code>rs</code>,
+a location that enables a slightly looser enforcement for RenderScript libs.
+Because the RS implementation needs to load the compiled bitcode,
+<code>/data/*/*.so</code> is added to the path of the <code>rs</code> namespace
+(other SP-HALs are not allowed to load libs from the data partition).</p>
+
+<p>In addition, the <code>rs</code> namespace allows more libs than provided for
+by other namespaces. <code>libmediandk.so</code> and <code>libft2.so</code> are
+exposed to the <code>rs</code> namespace because <code>libRS_internal.so</code>
+has an internal dependency to these libraries.</p>
+
+<img src="../images/treble_rs_namespace.png">
+<figcaption><strong>Figure 2.</strong> Namespace configuration for linker.
+</figcaption>
+
+<h3 id="loading-drivers">Loading drivers</h3>
+
+<h4>CPU fallback path</h4>
+<p>Depending on the existence of the <code>RS_CONTEXT_LOW_LATENCY</code> bit
+when creating an RS context, either the CPU or GPU path is selected. When the
+CPU path is selected, <code>libRS_internal.so</code> (the main implementation of
+the RS framework) is directly <code>dlopen</code>ed from the default linker
+namespace where the platform version of RS libs are provided.</p>
+
+<p>The RS HAL implementation from the vendor is not used at all when the CPU
+fallback path is taken, and an <code>RsContext</code> object is created with
+null <code>mVendorDriverName</code>. <code>libRSDriver.so</code> is (by default)
+<code>dlopen</code>ed and the driver lib is loaded from the <code>default</code>
+namespace because the caller (<code>libRS_internal.so</code>) is also loaded in
+the <code>default</code> namespace.</p>
+
+<img src="../images/treble_rs_cpu_fallback.png">
+<figcaption><strong>Figure 4.</strong> CPU fallback path.</figcaption>
+
+<h4 id="gpu-path">GPU path</h4>
+<p>For the GPU path, the <code>libRS_internal.so</code> is loaded differently.
+First, <code>libRS.so</code> uses
+<code>android.hardware.renderscript@1.0.so</code> (and its underlying
+<code>libhidltransport.so</code>) to load
+<code>android.hardware.renderscript@1.0-impl.so</code> (a vendor implementation
+of RS HAL) into a different linker namespace called <code>sphal</code>. The RS
+HAL then <code>dlopen</code>s <code>libRS_internal.so</code> in a another linker
+namespace called <code>rs</code>.</p>
+
+<p>Vendors can provide their own RS driver by setting the build-time flag
+<code>OVERRIDE_RS_DRIVER</code>, which is embedded into the RS HAL
+implementation
+(<code>hardware/interfaces/renderscript/1.0/default/Context.cpp</code>). This
+driver name is then <code>dlopen</code>ed for the RS context for the GPU path.
+</p>
+
+<p>The creation of the <code>RsContext</code> object is delegated to the RS HAL
+implementation. The HAL calls back to the RS framework using
+<code>rsContextCreateVendor()</code> function with the name of the driver to use
+as an argument. The RS framework then loads the specified driver when the
+<code>RsContext</code> is initialized. In this case, the driver library is
+loaded into the <code>rs</code> namespace because the <code>RsContext</code>
+object is created inside the <code>rs</code> namespace and
+<code>/vendor/lib</code> is in the search path of the namespace.</p>
+
+<img src="../images/treble_rs_gpu_fallback.png">
+<figcaption><strong>Figure 5.</strong> GPU fallback path.</figcaption>
+
+<p>When transitioning from the <code>default</code> namespace to the
+<code>sphal</code> namespace, <code>libhidltransport.so</code> uses the
+<code>android_load_sphal_library()</code> function to explicitly order the
+dynamic linker to load the <code>-impl.so</code> library from the
+<code>sphal</code> namespace.</p>
+
+<p>When transitioning from the <code>sphal</code> namespace to the <code>rs</code>
+namespace, loading is done indirectly by the following line in
+<code>/system/etc/ld.config.txt</code>:</p>
+
+<pre class="prettyprint">
+namespace.sphal.link.rs.shared_libs = libRS_internal.so
+</pre>
+
+<p>This line specifies the dynamic linker should load
+<code>libRS_internal.so</code> from the <code>rs</code> namespace when the lib
+can't be found/loaded from the <code>sphal</code> namespace (which is always the
+case because <code>sphal</code> namespace does not search
+<code>/system/lib/vndk-sp</code> where <code>libRS_internal.so</code> resides).
+With this configuration, a simple <code>dlopen()</code> call to
+<code>libRS_internal.so</code> is enough to make the namespace transition.</p>
+
+<h3 id="loading-bcc-plugin">Loading bcc plugin</h3>
+<p><code>bcc plugin</code> is a vendor-provided library loaded into the
+<code>bcc</code> compiler. Because <code>bcc</code> is a system process in the
+<code>/system/bin</code> directory, the <code>bcc plugin</code> library can be
+considered an SP-HAL (i.e., a vendor HAL that can be directly loaded into the
+system process without being binderized). As an SP-HAL, the
+<code>bcc-plugin</code> library:</p>
+<ul>
+<li>Cannot link against framework-only libraries such as
+<code>libLLVM.so</code>.</li>
+<li>Can link against only the VNDK-SP libraries available to the
+vendor.</li>
+</ul>
+
+<p>This restriction is enforced by loading the bcc plugin into the
+<code>sphal</code> namespace using the <code>android_sphal_load_library()</code>
+function. In previous versions of Android, the plugin name was specified using
+the <code>-load</code> option and the lib was loaded using the simple
+<code>dlopen()</code> by <code>libLLVM.so</code>. In Android O, this is
+specified in <code>-plugin</code> option and the lib is directly loaded by the
+<code>bcc</code> itself. This option enables a non-Android-specific path to
+the open source LLVM project.</p>
+
+<img src="../images/treble_rs_bcc_plugin_old.png">
+<figcaption><strong>Figure 6.</strong> Loading bcc plugin, Android 7.x and
+earlier.</figcaption>
+<br>
+<br>
+<img src="../images/treble_rs_bcc_plugin_new.png">
+<figcaption><strong>Figure 7. </strong>Loading bcc plugin, Android O.
+</figcaption>
+
+<h3 id="search-paths-for-ld-mc">Search paths for ld.mc</h3>
+<p>When executing <code>ld.mc</code>, some RS runtime libs are given as inputs
+to the linker. The RS bitcode from the app is linked against the runtime libs
+and when the converted bitcode is loaded into an app process, the runtime libs
+are again dynamically linked from the converted bitcode.</p>
+
+<p>Runtime libs include:</p>
+<ul>
+<li><code>libcompiler_rt.so</code></li>
+<li><code>libm.so</code></li>
+<li><code>libc.so</code></li>
+<li>RS driver (either <code>libRSDriver.so</code> or
+<code>OVERRIDE_RS_DRIVER</code>)</li>
+</ul>
+
+<p>When loading the compiled bitcode into the app process, we must provide the
+exact same library that was used by <code>ld.mc</code>. Otherwise, the compiled
+bitcode may not find a symbol which was available when it was linked.</p>
+
+<p>To do so, RS framework uses different search paths for the runtime libs when
+executing <code>ld.mc</code>, depending on whether the RS framework itself is
+loaded from <code>/system/lib</code> or from <code>/system/lib/vndk-sp</code>.
+This can be determined by reading the address of an arbitrary symbol of a RS
+framework lib and using <code>dladdr()</code> to get the file path mapped to the
+address.</p>
+
+<h3 id="selinux-policy">SELinux policy</h3>
+<p>As a result of the SELinux policy changes in Android O, you must follow
+specific rules (enforced through <code>neverallows</code>) when labelling
+additional files in <code>vendor</code> partition:</p>
+<ul>
+<li><code>vendor_file</code> must be the default label in for all files in
+<code>vendor</code> partition. The platform policy requires this to access
+passthrough HAL implementations.</li>
+<li>All new <code>exec_types</code> added in <code>vendor</code> partition
+through vendor SEPolicy must have <code>vendor_file_type</code> attribute. This
+is enforced through <code>neverallows</code>.</li>
+<li>To avoid conflicts with future platform/framework updates, avoid labelling
+files other than <code>exec_types</code> in <code>vendor</code> partition.
+<li>All library dependencies for AOSP-identified same process HALs must be
+labelled as <code>same_process_hal_file</code>.</li>
+</ul>
+
+<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>
+
+<h3 id="abi-compatibility-for-bitcode">ABI compatibility for bitcode</h3>
+<p>If no new APIs are added, which means no HAL version bump, the RS frameworks
+will keep using the existing GPU (HAL 1.0) driver.</p>
+
+<p>For minor HAL changes (HAL 1.1) not affecting bitcode, the frameworks should
+fallback to CPU for these newly added APIs and keep using GPU (HAL 1.0) driver
+elsewhere.</p>
+
+<p>For major HAL changes (HAL 2.0) affecting bitcode compilation/linking, RS
+frameworks should choose not to load vendor-provided GPU drivers and instead use
+the CPU or Vulkan path for acceleration.</p>
+
+<p>Consuming RenderScript bitcode occurs in three stages:</p>
+
+<table>
+<tr>
+<th>Stage</th>
+<th>Details</th>
+</tr>
+<tr>
+<td><em>Compile</em></td>
+<td><ul>
+<li>The input bitcode (.bc) for <code>bcc</code> must be in
+<code>LLVM 3.2</code> bitcode format and <code>bcc</code> must be backward
+compatible with existing (legacy) apps.</li>
+<li>However, the meta-data in .bc could change (there could new runtime
+functions, e.g, Allocation setters &mp; getters, math functions, etc.). Part
+of the runtime functions lives in <code>libclcore.bc</code>, part of them
+lives in LibRSDriver or vendor equivalent.</li>
+<li>New runtime functions or breaking meta-data changes require incrementing
+the bitcode API level. Because vendor drivers won't be able to consume it, the
+HAL version must also be incremented.</li>
+<li>Vendors may have their own compilers, but the conclusions/requirements for
+<code>bcc</code> also apply to those compilers.</li>
+</ul></td>
+</tr>
+<tr>
+<td><em>Link</em></td>
+<td><ul>
+<li>The compiled .o will be linked with vendor driver, e.g,
+<code>libRSDriver_foo.so</code>, and <code>libcompiler_rt.so</code>. The CPU
+path will link with <code>libRSDriver.so</code>.</li>
+<li>If the .o requires a new runtime API from <code>libRSDriver_foo</code>, the
+vendor driver has to be updated to support it.</li>
+<li>Certain vendors may have their own linkers, but the argument for
+<code>ld.mc</code> also apply to them.</li>
+</ul></td>
+</tr>
+<tr>
+<td><em>Load</em></td>
+<td><ul>
+<li><code>libRSCpuRef</code> loads the the shared object. If there are changes
+to this interface, a HAL version bump is needed.</li>
+<li>Vendors would either rely on <code>libRSCpuRef</code> to load the shared
+object, or implement their own.</li>
+</ul></td>
+</tr>
+</table>
+
+<p>In addition to the HAL, runtime APIs and the exported symbols are also
+interfaces. Neither interface has changed since Android 7.0 (API 24) and there
+are no immediate plans to change it in Android O and beyond. However, if the
+interface does change, the HAL version will also increment.</p>
+
+<h2 id="vendor-implementations">Vendor implementations</h2>
+<p>Android O requires some GPU driver changes for the GPU driver to work
+correctly.</p>
+
+<h3 id="driver-modules">Driver modules</h3>
+<ul>
+<li>Driver modules must not depend on any system libraries that are not in
+<a href="#renderscript-libs-available-to-vendors">the list</a>.</li>
+<li>Driver must provide its own
+<code>android.hardware.renderscript@1.0-impl_{NAME}</code>, or declare the
+default implementation <code>android.hardware.renderscript@1.0-impl</code> as
+its dependency.</li>
+<li>CPU implementation <code>libRSDriver.so</code> is a good example of how to
+remove non-VNDK-SP dependencies.</li>
+</ul>
+
+<h3 id="bitcode-compiler">Bitcode compiler</h3>
+<p>You can compile RenderScript bitcode for the vendor driver in two ways:</p>
+<ol>
+<li>Invoke vendor-specific RenderScript compiler in <code>/vendor/bin/</code>
+(preferred method of GPU compilation). Similar to other driver modules, the
+vendor compiler binary cannot depend on any system library that is not in the
+list of <a href="#renderscript-libs-available-to-vendors">RenderScript libs
+available to vendors</a>.</li>
+<li>Invoke system bcc: <code>/system/bin/bcc</code> with a vendor-provided bcc
+plugin. The <code>bcc plugin</code> cannot depend on any system library that is
+not in the list of
+<a href="#renderscript-libs-available-to-vendors">RenderScript libs available to
+vendors</a>.</li>
+</ol>
+
+<p>If the vendor <code>bcc plugin</code> needs to interfere with the CPU
+compilation and its dependency on <code>libLLVM.so</code> cannot be easily
+removed, the vendor should copy <code>bcc</code> (and all the non-LL-NDK
+dependencies, including <code>libLLVM.so</code>, <code>libbcc.so</code>) into
+<code>/vendor</code> partition.</p>
+
+<p>In addition, vendors need to make the following changes:</p>
+<img src="../images/treble_rs_vendor_driver.png">
+<figcaption><strong>Figure 8.</strong> Changes to vendor driver.</figcaption>
+<ol>
+<li>Copy <code>libclcore.bc</code> to <code>/vendor</code> partition. This
+ensures <code>libclcore.bc</code>, <code>libLLVM.so</code>, and
+<code>libbcc.so</code> are in sync.</li>
+<li>Change the path to the <code>bcc</code> executable by setting
+<code>RsdCpuScriptImpl::BCC_EXE_PATH</code> from the RS HAL implementation.</li>
+</ol>
+
+<aside class="note"><strong>Note:</strong> Restrictions for
+<code>/vendor/bin/*</code> processes are not fully implemented in Android O.
+While not recommended, it is theoretically possible to just copy
+<code>bcc</code> to <code>/vendor/bin/ </code>without copying its dependencies.
+</aside>
+
+<h3 id="selinux-policy">SELinux policy</h3>
+<p>SELinux policy affects both the driver and the compiler executables. All
+driver modules must be labeled <code>same_process_hal_file</code> in the
+device's <code>file_contexts</code>. For example:</p>
+
+<pre class="prettyprint">
+/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
+</pre>
+
+<p>The compiler executable must be able to be invoked by an app process, as does
+the vendor copy of bcc (<code>/vendor/bin/bcc</code>). For example:</p>
+
+<pre class="prettyprint">
+device/vendor_foo/device_bar/sepolicy/file.te:
+type renderscript_exec, exec_type, file_type;
+
+device/vendor_foo/device_bar/sepolicy/app.te:
+allow appdomain renderscript_exec:file { read open getattr execute execute_no_trans };
+
+device/vendor_foo/device_bar/sepolicy/file_contexts:
+/vendor/bin/bcc u:object_r:renderscript_exec:s0
+</pre>
+
+<h3 id="legacy-devices">Legacy devices</h3>
+<p>Legacy devices are those that satisfy the following conditions:</p>
+<ol>
+<li><em>PRODUCT_SHIPPING_API_LEVEL</em> is lower than 26.</li>
+<li><em>PRODUCT_FULL_TREBLE_OVERRIDE</em> is not defined.</li>
+</ol>
+
+<p>For legacy devices, the restrictions detailed throughout this document are
+not enforced when upgrading to Android O, meaning the drivers can continue to
+link to libraries in <code>/system/lib[64]</code>. However, because of the
+architecture change related with <code>OVERRIDE_RS_DRIVER</code>,
+<code>android.hardware.renderscript@1.0-impl</code> must be installed to
+<code>/vendor</code> partition; failing to do so forces RenderScript runtime
+fallback to CPU path.</p>
+
+ </body>
+</html>
diff --git a/en/devices/audio/usb.html b/en/devices/audio/usb.html
index d1dfcd3e..893ec9f1 100644
--- a/en/devices/audio/usb.html
+++ b/en/devices/audio/usb.html
@@ -634,5 +634,9 @@ So the USB audio HAL and tinyalsa do not need to concern
themselves with this part of USB protocol.
</p>
+<h2 id="testing-usb-audio">Testing USB audio</h2>
+<p>For information on CTS testing for USB audio, see <a
+href="/compatibility/cts/usb-audio">USB Audio CTS Verifier Tests</a>.</p>
+
</body>
</html>
diff --git a/en/devices/automotive/camera-hal.html b/en/devices/automotive/camera-hal.html
new file mode 100644
index 00000000..91e2ca28
--- /dev/null
+++ b/en/devices/automotive/camera-hal.html
@@ -0,0 +1,625 @@
+<html devsite>
+ <head>
+ <title>Vehicle Camera 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 8.0 includes an automotive HIDL Hardware Abstraction Layer (HAL) that
+provides for imagery capture and display very early in the Android boot process
+and continues functioning for the life of the system. The HAL includes the
+exterior view system (EVS) stack and is typically used to support rear-view
+camera and surround view displays in vehicles with Android-based In-Vehicle
+Infotainment (IVI) systems. EVS also enables advanced features to be implemented
+in user applications.</p>
+
+<p>Android 8.0 also includes an EVS-specific capture and display driver
+interface (in <code>/hardware/interfaces/automotive/evs/1.0</code>). While it is
+possible to build a rear view camera application on top of existing Android
+camera and display services, such an application would likely run too late in
+the Android boot process. Using a dedicated HAL enables a streamlined interface
+and makes it clear what an OEM needs to implement to support the EVS stack.</p>
+
+<h2 id="system-components">System components</h2>
+<p>EVS includes the following system components:</p>
+
+<img src="/devices/automotive/images/vhal_evs_components.png" alt="EVS System
+components diagram.">
+<figcaption><strong>Figure 1.</strong> EVS System components
+overview.</figcaption>
+
+<h3 id="evs-application">EVS application</h3>
+<p>A sample C++ EVS application
+(<code>/packages/services/Car/evs/sample_app</code>) serves as a reference
+implementation. This application is responsible for requesting video frames from
+the EVS Manager and sending finished frames for display back to the EVS Manager.
+It expects to be started by init as soon as EVS and Car Service are available,
+targeted within two (2) seconds of power on. OEMs can modify or replace the EVS
+application as desired.</p>
+
+<h3 id="evs-manager">EVS Manager</h3>
+
+<p>The EVS Manager (<code>/packages/services/Car/evs/service</code>) provides
+the building blocks needed by an EVS application to implement anything from a
+simple rear view camera display to a 6DOF multi-camera rendering. Its interface
+is presented through HIDL and is built to accept multiple concurrent clients.
+Other applications and services (specifically the Car Service) can query the EVS
+Manager state to find out when the EVS system is active.</p>
+
+<h3 id="evs-hidl-interface">EVS HIDL interface</h3>
+
+<p>The EVS system, both the camera and the display elements, is defined in the
+<code>android.hardware.automotive.evs</code> package. A sample implementation
+that exercises the interface (generates synthetic test images and validates the
+images make the round trip) is provided in
+<code>/hardware/interfaces/automotive/evs/1.0/default</code>.</p>
+
+<p>The OEM is responsible for implementing the API expressed by the .hal files
+in <code>/hardware/interfaces/automotive/evs</code>. Such implementations are
+responsible for configuring and gathering data from physical cameras and
+delivering it via shared memory buffers recognizable by Gralloc. The display
+side of the implementation is responsible for providing a shared memory buffer
+that can be filled by the application (usually via EGL rendering) and presenting
+the finished frames in preference to anything else that might want to appear on
+the physical display. Vendor implementations of the EVS interface may be stored
+under <code>/vendor/… /device/…</code> or <code>hardware/…</code> (e.g.,
+<code>/hardware/[vendor]/[platform]/evs</code>).</p>
+
+<h3 id="kernel-drivers">Kernel drivers</h3>
+
+<p>A device that supports the EVS stack requires kernel drivers. Instead of
+creating new drivers, OEMs have the option to support EVS-required features via
+existing camera and/or display hardware drivers. Reusing drivers could be
+advantageous, especially for display drivers where image presentation may
+require coordination with other active threads. Android 8.0 includes a v4l2-based
+sample driver (in <code>packages/services/Car/evs/sampleDriver</code>) that
+depends on the kernel for v4l2 support and on SurfaceFlinger for presenting the
+output image.</p>
+
+<aside class="note"><strong>Note:</strong> The dependency on SurfaceFlinger is
+not appropriate for an actual vendor implementation as EVS must be able to run
+within seconds of power on, long before SurfaceFlinger itself has booted.
+However, the sample driver implementation is moderately hardware independent and
+allows for EVS application development and testing in parallel with EVS driver
+development.</aside>
+
+<h2 id="evs-hardware-interface-description">EVS hardware interface
+description</h2>
+
+<p>The section describes the HAL. Vendors are expected to provide
+implementations of this API adapted for their hardware.</p>
+
+<h3 id="ievsenumerator">IEvsEnumerator</h3>
+
+<p>This object is responsible for enumerating the available EVS hardware in the
+system (one or more cameras and the single display device).</p>
+
+<pre class="prettyprint">
+getCameraList() generates (vec&lt;CameraDesc&gt; cameras);
+</pre>
+
+<p>Returns a vector containing descriptions for all cameras in the system. It is
+assumed the set of cameras is fixed and knowable at boot time. For details on
+camera descriptions, see <code><a href="#cameradesc">CameraDesc</a></code>.</p>
+
+<pre class="prettyprint">
+openCamera(string camera_id) generates (IEvsCamera camera);
+</pre>
+
+<p>Obtains an interface object used to interact with a specific camera
+identified by the unique <em>camera_id</em> string. Returns a NULL on failure.
+Attempts to reopen a camera that is already open cannot fail. To avoid race
+conditions associated with application startup and shutdown, reopening a camera
+should shut down the previous instance so the new request can be fulfilled. A
+camera instance that has been preempted in this way must be put in an inactive
+state, awaiting final destruction and responding to any request to affect the
+camera state with a return code of <code>OWNERSHIP_LOST</code>.</p>
+
+<pre class="prettyprint">
+closeCamera(IEvsCamera camera);
+</pre>
+
+<p>Releases the IEvsCamera interface (and is the opposite of the
+<code>openCamera()</code> call). If streaming is not already stopped, this call
+automatically stops streaming.</p>
+
+<pre class="prettyprint">
+openDisplay() generates (IEvsDisplay display);
+</pre>
+
+<p>Obtains an interface object used to exclusively interact with the system's
+EVS display. Only one client may hold a functional instance of IEvsDisplay at
+time. Similar to the aggressive open behavior described in
+<code>openCamera</code>, a new IEvsDisplay object may be created at any time and
+will disable any previous instances. Invalidated instances continue to exist and
+respond to function calls from their owners, but must perform no mutating
+operations when dead. Eventually, the client application is expected to notice
+the <code>OWNERSHIP_LOST</code> error return codes and close and release the
+dead interface.</p>
+
+<pre class="prettyprint">
+closeDisplay(IEvsDisplay display);
+</pre>
+
+<p>Releases the IEvsDisplay interface (and is the opposite of the
+<code>openDisplay()</code> call). Outstanding buffers received via
+<code>getTargetBuffer()</code> calls must be returned to the display before
+closing the display.</p>
+
+<pre class="prettyprint">
+getDisplayState() generates (DisplayState state);
+</pre>
+
+<p>Gets the current display state. The HAL implementation should report the
+actual current state, which might differ from the most recently requested state.
+The logic responsible for changing display states should exist above the device
+layer, making it undesirable for the HAL implementation to spontaneously change
+display states. If the display is not currently held by any client (by a call to
+openDisplay), then this function returns <code>NOT_OPEN</code>. Otherwise, it
+reports the current state of the EVS Display (see
+<a href="#ievsdisplay">IEvsDisplay API</a>).</p>
+
+<a name="cameradesc"></a>
+<pre class="prettyprint">
+struct CameraDesc {
+ string camera_id;
+ int32 vendor_flags; // Opaque value
+}
+</pre>
+
+<ul>
+<li><code>camera_id</code>. A string that uniquely identifies a given camera.
+Can be the kernel device name of the device or a name for the device, such as
+<em>rearview</em>. The value for this string is chosen by the HAL implementation
+and used opaquely by the stack above.</li>
+<li><code>vendor_flags</code>. A method for passing specialized camera
+information opaquely from the driver to a custom EVS application. It is passed
+uninterpreted from the driver up to the EVS application, which is free to ignore
+it.</li>
+</ul>
+
+<h3 id="ievscamera">IEvsCamera</h3>
+
+<p>This object represents a single camera and is the primary interface for
+capturing images.</p>
+
+<pre class="prettyprint">
+getId() generates (hidl_string cameraId);
+</pre>
+
+<p>Returns the string id of this camera. This must be the same value as reported
+in the <code>camera_id</code> field of the <code>CameraDesc</code> structure by
+<code>EvsEnumerator::getCameraList()</code>.</p>
+
+<pre class="prettyprint">
+setMaxFramesInFlight(int32 bufferCount) generates (EvsResult result);
+</pre>
+
+<p>Specifies the depth of the buffer chain the camera is asked to support. Up to
+this many frames may be held concurrently by the client of IEvsCamera. If this
+many frames have been delivered to the receiver without being returned by
+<code>doneWithFrame</code>, the stream skips frames until a buffer is returned
+for reuse. It is legal for this call to come at any time, even while streams are
+already running, in which case buffers should be added or removed from the chain
+as appropriate. If no call is made to this entry point, the IEvsCamera supports
+at least one frame by default; with more acceptable.</p>
+
+<p>If the requested bufferCount cannot be accommodated, the function returns
+<code>BUFFER_NOT_AVAILABLE</code> or other relevant error code. In this case,
+the system continues to operate with the previously-set value.</p>
+
+<pre class="prettyprint">
+startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
+</pre>
+
+<p>Requests delivery of EVS camera frames from this camera. The IEvsCameraStream
+begins receiving periodic calls with new image frames until
+<code>stopVideoStream()</code> is called. Frames must begin being delivered
+within 500ms of the <code>startVideoStream</code> call and after starting, must
+generated at a minimum of 10 FPS. The time required to start the video stream
+effectively counts against any rear view camera startup time requirement. If the
+stream is not started, an error code must be returned; otherwise OK is returned.
+</p>
+
+<pre class="prettyprint">
+doneWithFrame(BufferDesc buffer) generates (EvsResult result);
+</pre>
+
+<p>Returns a frame that was delivered by to the IEvsCameraStream. When done
+consuming a frame delivered to the IEvsCameraStream interface, the frame must be
+returned to the IEvsCamera for reuse. A small, finite number of buffers are
+available (possibly as small as one), and if the supply is exhausted, no further
+frames are delivered until a buffer is returned, potentially resulting in
+skipped frames (a buffer with a null handle denotes the end of a stream and does
+not need to be returned through this function). Returns OK on success, or
+appropriate error code potentially including <code>INVALID_ARG</code> or
+<code>BUFFER_NOT_AVAILABLE</code>.</p>
+
+<pre class="prettyprint">
+stopVideoStream();
+</pre>
+
+<p>Stops the delivery of EVS camera frames. Because delivery is asynchronous,
+frames may continue to arrive for some time after this call returns. Each frame
+must be returned until the closure of the stream is signaled to the
+IEvsCameraStream. It is legal to call <code>stopVideoStream</code> on a stream
+that has already been stopped or never started, in which cases it is ignored.
+</p>
+
+<pre class="prettyprint">
+getExtendedInfo(int32 opaqueIdentifier) generates (int32 value);
+</pre>
+
+<p>Requests driver-specific information from the HAL implementation. Values
+allowed for <code>opaqueIdentifier</code> are driver-specific, but no value
+passed may crash the driver. The driver should return 0 for any unrecognized
+<code>opaqueIdentifier</code>.</p>
+
+<pre class="prettyprint">
+setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
+</pre>
+
+<p>Sends a driver-specific value to the HAL implementation. This extension is
+provided only to facilitate vehicle-specific extensions and no HAL
+implementation should require this call to function in a default state. If the
+driver recognizes and accepts the values, OK should be returned; otherwise
+<code>INVALID_ARG</code> or other representative error code should be returned.
+</p>
+
+<pre class="prettyprint">
+struct BufferDesc {
+ uint32 width; // Units of pixels
+ uint32 height; // Units of pixels
+ uint32 stride; // Units of pixels
+ uint32 pixelSize; // Size of single pixel in bytes
+ uint32 format; // May contain values from android_pixel_format_t
+ uint32 usage; // May contain values from Gralloc.h
+ uint32 bufferId; // Opaque value
+ handle memHandle; // gralloc memory buffer handle
+}
+</pre>
+
+<p>Describes an image passed through the API. The HAL drive is responsible for
+filling out this structure to describe the image buffer and the HAL client
+should treat this structure as read-only. The fields contain enough information
+to allow the client to reconstruct an <code>ANativeWindowBuffer</code> object,
+as may be required to use the image with EGL via the
+<code>eglCreateImageKHR()</code> extension.</p>
+
+<ul>
+<li><code>width</code>. The width in pixels of the presented image.</li>
+<li><code>height</code>. The height in pixels of the presented image.</li>
+<li><code>stride</code>. Number of pixels each row actually occupies in memory,
+accounting for any padding for alignment of rows. Expressed in pixels to match
+the convention adopted by gralloc for its buffer descriptions.</li>
+<li><code>pixelSize</code>. Number of bytes occupied by each individual pixel,
+enabling computation of the size in bytes necessary to step between rows in the
+image (<code>stride</code> in bytes = <code>stride</code> in pixels *
+<code>pixelSize</code>).</li>
+<li><code>format</code>. The pixel format used by the image. The format provided
+must be compatible with the platform's OpenGL implementation. To pass
+compatibility testing, <code>HAL_PIXEL_FORMAT_YCRCB_420_SP</code> should be
+preferred for camera usage and and <code>RGBA</code> should be preferred for
+display.</li>
+<li><code>usage</code>. Usage flags set by the HAL implementation. HAL clients
+are expected to pass these unmodified (for details, refer to
+<code>Gralloc.h</code> related flags).</li>
+<li><code>bufferId</code>. A unique value specified by the HAL implementation to
+allow a buffer to be recognized after a round trip through the HAL APIs. The
+value stored in this field may be arbitrarily chosen by the HAL implementation.
+<li><code>memHandle</code>. The handle for the underlying memory buffer that
+contains the image data. The HAL implementation might choose to store a Gralloc
+buffer handle here.</li>
+</ul>
+
+<h3 id="ievscamerastream">IEvsCameraStream</h3>
+
+<p>The client implements this interface to receive asynchronous video frame
+deliveries.</p>
+
+<pre class="prettyprint">
+deliverFrame(BufferDesc buffer);
+</pre>
+
+<p>Receives calls from the HAL each time a video frame is ready for inspection.
+Buffer handles received by this method must be returned via calls to
+<code>IEvsCamera::doneWithFrame()</code>. When the video stream is stopped via a
+call to <code>IEvsCamera::stopVideoStream()</code>, this callback might continue
+as the pipeline drains. Each frame must still be returned; when the last frame
+in the stream has been delivered, a NULL bufferHandle will be delivered,
+signifying the end of the stream and no further frame deliveries occur. The NULL
+bufferHandle itself does not need to be sent back via
+<code>doneWithFrame()</code>, but all other handles must be returned</p>
+
+<p>While proprietary buffer formats are technically possible, compatibility
+testing requires the buffer be in one of four supported formats: NV21 (YCrCb
+4:2:0 Semi-Planar), YV12 (YCrCb 4:2:0 Planar), YUYV (YCrCb 4:2:2 Interleaved),
+RGBA (32 bit R:G:B:x). The selected format must be a valid GL texture source on
+the platform's GLES implementation.</p>
+
+<p>The application should <strong>not</strong> rely on any correspondence
+between the <code>bufferId</code> field and the <code>memHandle</code> in the
+<code>BufferDesc</code> structure. The <code>bufferId</code> values are
+essentially private to the HAL driver implementation, and it may use (and reuse)
+them as it sees fit.</p>
+
+<h3 id="ievsdisplay">IEvsDisplay</h3>
+
+<p>This object represents the Evs display, controls the state of the display,
+and handles the actual presentation of images.</p>
+
+<pre class="prettyprint">
+getDisplayInfo() generates (DisplayDesc info);
+</pre>
+
+<p>Returns basic information about the EVS display provided by the system (see
+<a href="#displaydesc">DisplayDesc</a>).</p>
+
+<pre class="prettyprint">
+setDisplayState(DisplayState state) generates (EvsResult result);
+</pre>
+
+<p>Sets the display state. Clients may set the display state to express the
+desired state, and the HAL implementation must gracefully accept a request for
+any state while in any other state, although the response may be to ignore the
+request.</p>
+
+<p>Upon initialization, the display is defined to start in the
+<code>NOT_VISIBLE</code> state, after which the client is expected to request
+the <code>VISIBLE_ON_NEXT_FRAME</code> state and begin providing video. When the
+display is no longer required, the client is expected to request the
+<code>NOT_VISIBLE</code> state after passing the last video frame.</p>
+
+<p>It is valid for any state to be requested at any time. If the display is
+already visible, it should remain visible if set to
+<code>VISIBLE_ON_NEXT_FRAME</code>. Always returns OK unless the requested state
+is an unrecognized enum value, in which case <code>INVALID_ARG</code> is
+returned.</p>
+
+<pre class="prettyprint">
+getDisplayState() generates (DisplayState state);
+</pre>
+
+<p>Gets the display state. The HAL implementation should report the actual
+current state, which might differ from the most recently requested state. The
+logic responsible for changing display states should exist above the device
+layer, making it undesirable for the HAL implementation to spontaneously change
+display states.</p>
+
+<pre class="prettyprint">
+getTargetBuffer() generates (handle bufferHandle);
+</pre>
+
+<p>Returns a handle to a frame buffer associated with the display. This buffer
+may be locked and written to by software and/or GL. This buffer must be returned
+via a call to <code>returnTargetBufferForDisplay()</code> even if the display is
+no longer visible.</p>
+
+<p>While proprietary buffer formats are technically possible, compatibility testing
+requires the buffer be in one of four supported formats: NV21 (YCrCb 4:2:0
+Semi-Planar), YV12 (YCrCb 4:2:0 Planar), YUYV (YCrCb 4:2:2 Interleaved), RGBA
+(32 bit R:G:B:x). The selected format must be a valid GL render target on the
+platform's GLES implementation.</p>
+
+<p>On error, a buffer with a null handle is returned, but such a buffer does not
+need to be passed back to <code>returnTargetBufferForDisplay</code>.</p>
+
+<pre class="prettyprint">
+returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);
+</pre>
+
+<p>Tells the display the buffer is ready for display. Only buffers retrieved
+through a call to <code>getTargetBuffer()</code> are valid for use with this
+call, and the contents of the <code>BufferDesc</code> may not be modified by the
+client application. After this call, the buffer is no longer valid for use by
+the client. Returns OK on success, or appropriate error code potentially
+including <code>INVALID_ARG</code> or <code>BUFFER_NOT_AVAILABLE</code>.</p>
+
+<a name="displaydesc"></a>
+<pre class="prettyprint">
+struct DisplayDesc {
+ string display_id;
+ int32 vendor_flags; // Opaque value
+}
+</pre>
+
+<p>Describes the basic properties of an EVS display and required by an EVS
+implementation. The HAL is responsible for filling out this structure to
+describe the EVS display. Can be a physical display or a virtual display that is
+overlaid or mixed with another presentation device.</p>
+
+<ul>
+<li><code>display_id</code>. A string that uniquely identifies the display.
+This could be the kernel device name of the device, or a name for the device,
+such as "rearview". The value for this string is chosen by the HAL
+implementation and used opaquely by the stack above.</li>
+<li><code>vendor_flags</code>. A method for passing specialized camera
+information opaquely from the driver to a custom EVS Application. It is passed
+uninterpreted from the driver up to the EVS Application, which is free to ignore
+it.</li>
+</ul>
+
+<pre class="prettyprint">
+enum DisplayState : uint32 {
+ NOT_OPEN, // Display has not been “opened” yet
+ NOT_VISIBLE, // Display is inhibited
+ VISIBLE_ON_NEXT_FRAME, // Will become visible with next frame
+ VISIBLE, // Display is currently active
+ DEAD, // Display is not available. Interface should be closed
+}
+</pre>
+
+<p>Describes the state of the EVS display, which can be <em>disabled</em> (not
+visible to the driver) or <em>enabled</em> (showing an image to the driver).
+Includes a transient state where the display is not visible yet but is prepared
+to become visible with the delivery of the next frame of imagery via the
+<code>returnTargetBufferForDisplay()</code> call.</p>
+
+<h2 id="evs-manager">EVS Manager</h2>
+<p>The EVS Manager provides the public interface to the EVS system for
+collecting and presenting external camera views. Where hardware drivers allow
+only one active interface per resource (camera or display), the EVS Manager
+facilitates shared access to the cameras. A single primary EVS application is
+the first client of the EVS Manager, and is the only client permitted to write
+display data (additional clients can be granted read-only access to camera
+images).</p>
+
+<p>The EVS Manager implements the same API as the underlying HAL drivers and
+provides expanded service by supporting multiple concurrent clients (more than
+one client can open a camera through the EVS Manager and receive a video
+stream).</p>
+
+<figure id="evs-manager">
+<img src="/devices/automotive/images/vhal_evs_manager.png" alt="EVS Manager and
+EVS Hardware API diagram.">
+<figcaption><strong>Figure 2.</strong> EVS Manager mirrors underlying EVS
+Hardware API</figcaption>
+</figure>
+
+<p>Applications see no differences when operating through the EVS Hardware HAL
+implementation or the EVS Manager API except that the EVS Manager API allows
+concurrent camera stream access. The EVS Manager is, itself, the one allowed
+client of the EVS Hardware HAL layer, and acts as a proxy for the EVS Hardware
+HAL.</p>
+
+<p>The following sections describe only those calls that have a different
+(extended) behavior in the EVS Manager implementation; remaining calls are
+identical to EVS HAL descriptions.</p>
+
+<h3 id="ievsenumerator">IEvsEnumerator</h3>
+
+<pre class="prettyprint">
+openCamera(string camera_id) generates (IEvsCamera camera);
+</pre>
+
+<p>Obtains an interface object used to interact with a specific camera
+identified by the unique <em>camera_id</em> string. Returns a NULL on failure.
+At the EVS Manager layer, as long as sufficient system resources are available,
+a camera that is already open may be opened again by another process, allowing
+teeing of the video stream to multiple consumer applications. The
+<code>camera_id</code> strings at the EVS Manager layer are the same as those
+reported to the EVS Hardware layer.</p>
+
+<h3 id="ievscamera">IEvsCamera</h3>
+
+<p>The EVS Manager provided IEvsCamera implementation is internally virtualized
+so operations on a camera by one client do not affect other clients, which
+retain independent access to their cameras.</p>
+
+<pre class="prettyprint">
+startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
+</pre>
+
+<p>Starts video streams. Clients may independently start and stop video streams
+on the same underlying camera. The underlying camera starts when the first
+client starts.</p>
+
+<pre class="prettyprint">
+doneWithFrame(uint32 frameId, handle bufferHandle) generates (EvsResult result);
+</pre>
+
+<p>Returns a frame. Each client must return their frames when they are done, but
+are permitted to hold onto their frames for as long as they desire. When the
+frame count held by a client reaches its configured limit, it will not receive
+any more frames until it returns one. This frame skipping does not affect other
+clients, which continue to receive all frames as expected.</p>
+
+<pre class="prettyprint">
+stopVideoStream();
+</pre>
+
+<p>Stops a video stream. Each client can stop its video stream any time without
+affecting other clients. The underlying camera stream at the hardware layer is
+stopped when the last client of a given camera stops its stream.</p>
+
+<pre class="prettyprint">
+setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
+</pre>
+
+<p>Sends a driver-specific value, potentially enabling one client to affect
+another client. Because the EVS Manager cannot understand the implications of
+vendor-defined control words, they are not virtualized and any side effects
+apply to all clients of a given camera. For example, if a vendor used this call
+to change frame rates, all clients of the affected hardware layer camera would
+receive frames at the new rate.</p>
+
+<h3 id="ievsdisplay">IEvsDisplay</h3>
+
+<p>Only one owner of the display is allowed, even at the EVS Manager level. The
+Manager adds no functionality and simply passess the IEvsDisplay interface
+directly through to the underlying HAL implementation.</p>
+
+<h2 id="evs-application">EVS application</h2>
+
+<p>Android 8.0 includes a native C++ reference implementation of an EVS
+application that communicates with the EVS Manager and the Vehicle HAL to
+provide basic rear view camera functions. The application is expected to start
+very early in the system boot process, with suitable video shown depending on
+the available cameras and the state of the car (gear and turn signal state).
+OEMs can modify or replace the EVS application with their own vehicle-specific
+logic and presentation.</p>
+
+<img src="/devices/automotive/images/vhal_evs_get_camera.png">
+<figcaption><strong>Figure 3.</strong> EVS application sample logic, get camera
+list.</figcaption>
+<br>
+<br>
+<img src="/devices/automotive/images/vhal_evs_receive_frame.png">
+<figcaption><strong>Figure 4.</strong> EVS application sample logic, receive
+frame callback.</figcaption>
+
+<p>Because image data is presented to the application in a standard graphics
+buffer, the application is responsible for moving the image from the source
+buffer into the output buffer. While this introduces the cost of a data copy,
+it also offers the opportunity for the application to render the image into the
+display buffer in any fashion it desires.</p>
+
+<p>For example, the application may choose to move the pixel data itself,
+potentially with an inline scale or rotation operation. The application could
+also choose to use the source image as an OpenGL texture and render a complex
+scene to the output buffer, including virtual elements such as icons,
+guidelines, and animations. A more sophisticated application may also select
+multiple concurrent input cameras and merge them into the single output frame
+(such as for use in a top-down, virtual view of vehicle surroundings).</p>
+
+<h2 id="beyond-android-o">Beyond Android 8.0</h2>
+
+<p>Android 8.0 provides support for basic rearview camera applications, but
+Google recognizes several use cases that may become the basis for future
+extensions to the EVS stack.</p>
+
+<aside class="note"><strong>Note:</strong> Google reserves the right to change
+release features at any time.</aside>
+
+<ul>
+<li><strong>Surround view</strong>. To address use cases where vehicles have
+multiple cameras around the car body, Google is considering enhancing the EVS
+application to warp video from multiple concurrent cameras into a 3D
+presentation suitable for tight quarter maneuvering (such as parking in a narrow
+space).</li>
+<li><strong>User input</strong>. In Android 8.0, it is the responsibility of the
+application to acquire and parse input events from the kernel device. Reading
+user input early in the boot cycle can be accomplished by interacting with the
+dev/event# kernel devices, and reading events from these streams does not
+interfere with Android InputFlinger's ability to monitor these same input
+streams. To address use cases for input events, Google is considering a simple
+EVS interface that supports single-touch events.</li>
+</ul>
+
+</body>
+</html>
diff --git a/en/devices/automotive/images/vhal_evs_components.png b/en/devices/automotive/images/vhal_evs_components.png
new file mode 100644
index 00000000..7b413f1d
--- /dev/null
+++ b/en/devices/automotive/images/vhal_evs_components.png
Binary files differ
diff --git a/en/devices/automotive/images/vhal_evs_get_camera.png b/en/devices/automotive/images/vhal_evs_get_camera.png
new file mode 100644
index 00000000..6b186a76
--- /dev/null
+++ b/en/devices/automotive/images/vhal_evs_get_camera.png
Binary files differ
diff --git a/en/devices/automotive/images/vhal_evs_manager.png b/en/devices/automotive/images/vhal_evs_manager.png
new file mode 100644
index 00000000..04622ade
--- /dev/null
+++ b/en/devices/automotive/images/vhal_evs_manager.png
Binary files differ
diff --git a/en/devices/automotive/images/vhal_evs_receive_frame.png b/en/devices/automotive/images/vhal_evs_receive_frame.png
new file mode 100644
index 00000000..3b2fcac9
--- /dev/null
+++ b/en/devices/automotive/images/vhal_evs_receive_frame.png
Binary files differ
diff --git a/en/devices/automotive/index.html b/en/devices/automotive/index.html
index 83a7a6ef..c6b6896f 100644
--- a/en/devices/automotive/index.html
+++ b/en/devices/automotive/index.html
@@ -56,8 +56,8 @@ network service:</p>
automotive architecture</p>
<ul>
-<li><strong>Car API</strong>. Contains the APIs such as CarHvacManager,
-CarSensorManager, and CarCameraManager. For details on supported APIs,
+<li><strong>Car API</strong>. Contains the APIs such as CarHvacManager
+and CarSensorManager. For details on supported APIs,
refer to <code>/platform/packages/services/Car/car-lib</code>.</li>
<li><strong>CarService</strong>. Located at
<code>/platform/packages/services/Car/</code>.</li>
diff --git a/en/devices/automotive/ivi_connectivity.html b/en/devices/automotive/ivi_connectivity.html
new file mode 100644
index 00000000..66fce686
--- /dev/null
+++ b/en/devices/automotive/ivi_connectivity.html
@@ -0,0 +1,270 @@
+<html devsite>
+ <head>
+ <title>IVI Connectivity</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 8.0 creates a more seamless Bluetooth user experience
+ when connecting devices to the in-vehicle infotainment system (IVI).
+ The IVI listens for events, such as unlocking a car door
+ or starting the engine, and automatically scans for in-range
+ Bluetooth devices. It will also simultaneously connect to separate
+ devices so users can make hands-free calls on any device.
+ </p>
+
+ <h2 id="bluetooth-connection-management">Bluetooth connection management</h2>
+
+ <p>
+ In Android 7.x and earlier, the IVI Bluetooth stack
+ scans for devices only when the Bluetooth adapter is powered on. Users have to
+ connect manually if their device comes into range while the IVI Bluetooth is on.
+ Android 8.0 reduces the need for users to manually connect their devices through
+ the IVI settings app.
+ </p>
+
+ <p>
+ While the Bluetooth adapter is on and not connected to a device, customizable
+ trigger events (such as unlocking the door or starting the engine) cause the
+ IVI Bluetooth to scan for in-range devices to pair with on available profiles.
+ The IVI Bluetooth then uses a priority list to determine which device to
+ connect with.
+ </p>
+
+ <p>
+ In addition to the trigger events, you can specify the device priority for each
+ profile. In the default implementation, the IVI Bluetooth prioritizes the most
+ recently connected device. There is a separate priority list for each Bluetooth
+ service, so each service profile can be connected to a different device. Each
+ Bluetooth service profile also has a different connection limit.
+ </p>
+
+ <table>
+ <tr>
+ <th>Service</th>
+ <th>Profile</th>
+ <th>Connection limit</th>
+ </tr>
+ <tr>
+ <td rowspan="2">Phone</td>
+ <td>HFP</td>
+ <td>2</td>
+ </tr>
+ <tr>
+ <td>PBAP</td>
+ <td>2</td>
+ </tr>
+ <tr>
+ <td>Message</td>
+ <td>MAP</td>
+ <td>1</td>
+ </tr>
+ <tr>
+ <td>Audio</td>
+ <td>A2DP</td>
+ <td>1</td>
+ </tr>
+ </table>
+
+ <h3 id="implement-connection-management">Implement connection management</h3>
+
+ <p>
+ To support auto-connect in Android 8.0, the Bluetooth connection management logic
+ moved from the Bluetooth Service to a policy in Car Service. Within a policy,
+ you can customize when the Bluetooth auto-connect should scan for new devices,
+ and which devices it should attempt to connect to first.
+ </p>
+
+ <p>
+ The default connection policy can be found in <code><a
+ href="https://android.googlesource.com/platform/packages/services/Car/+/oreo-r6-release/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java">
+ service/src/com/android/car/BluetoothDeviceConnectionPolicy.java</a></code>.
+ To use a custom phone policy, disable the default phone policy in <code><a href="https://android.googlesource.com/platform/packages/apps/Bluetooth/+/master/res/values/config.xml">
+ res/values/config.xml</a></code> by setting <code>enable_phone_policy</code>
+ to <code>false</code>.
+ </p>
+
+ <p>
+ To create a trigger event, register a listener to the respective Car Service.
+ Example of a new sensor event:
+ </p>
+
+<pre class="prettyprint">
+ /**
+ * Handles events coming in from the {&#64;link CarSensorService}
+ * Upon receiving the event that is of interest, initiate a connection attempt by
+ * calling the policy {&#64;link BluetoothDeviceConnectionPolicy}
+ */
+ private class CarSensorEventListener extends ICarSensorEventListener.Stub {
+ &#64;Override
+ public void onSensorChanged(List&lt;CarSensorEvent&gt; events) throws RemoteException {
+ if (events != null & !events.isEmpty()) {
+ CarSensorEvent event = events.get(0);
+ if (event.sensorType == CarSensorManager.SOME_NEW_SENSOR_EVENT) {
+ initiateConnection();
+ }
+ ...
+ }
+</pre>
+
+ <p>
+ To configure the device priority for each profile, modify the following methods
+ in <code><a
+ href="https://android.googlesource.com/platform/packages/services/Car/+/oreo-r6-release/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java">
+ BluetoothDeviceConnectionPolicy</a></code>:
+ </p>
+
+ <ul>
+ <li><code>updateDeviceConnectionStatus()</code></li>
+ <li><code>findDeviceToConnect()</code></li>
+ </ul>
+
+ <h3 id="verify-connection-management">Verify connection management</h3>
+
+ <p>
+ Verify the behavior of the Bluetooth connection management by toggling Bluetooth
+ on your Android Automotive IVI and see that it automatically connects to the
+ appropriate devices.
+ </p>
+
+ <p>
+ You can use the following <code>adb</code> commands to test your IVI with
+ simulated vehicle events:
+ </p>
+
+ <ul>
+ <li>For <code>CarCabinManager.ID_DOOR_LOCK</code>:
+ <pre class="devsite-terminal devsite-click-to-copy">adb shell dumpsys activity service com.android.car inject-event zoned-boolean 0x16200b02 1 false</pre>
+ </li>
+ <li>For <code>CarSensorManager.SENSOR_TYPE_IGNITION_STATE</code>:
+ <pre class="devsite-terminal devsite-click-to-copy">adb shell dumpsys activity service com.android.car inject-event global-integer 0x11400409 5</pre>
+ </li>
+ </ul>
+
+ <h2 id="bluetooth-multi-device-connectivity">Bluetooth multi-device connectivity</h2>
+
+ <p>
+ In Android 8.0, the IVI can support multiple devices connected simultaneously
+ over Bluetooth. Multi-device Bluetooth phone services let users connect
+ separate devices, such as a personal phone and a work phone, and make
+ hands-free calls from either device. This feature increases driving safety by
+ reducing distraction and improves in-call experiences by taking advantage
+ of automotive audio systems.
+ </p>
+
+ <h3 id="multi-device-connectivity">Multi-device connectivity</h3>
+
+ <p>
+ When a trigger event happens, the <a
+ href="https://android.googlesource.com/platform/packages/services/Car/+/oreo-r6-release/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java">
+ Bluetooth Connection Management Policy</a> determines which devices to connect
+ to on each Bluetooth profile. The policy then sends a connect intent to the
+ profile client service. In turn, the profile client service creates a client
+ state machine instance to manage the connection with each device.
+ </p>
+
+ <h4 id="hands-free-profile">Hands-Free Profile</h4>
+
+ <p>
+ The Bluetooth Hands-Free Profile (HFP) in Android 8.0 lets two devices connect
+ concurrently, and either device can make or receive phone calls. To do this,
+ each connection registers a separate phone account with the Telecom Manager,
+ which advertises the phone accounts to the IVI apps.
+ </p>
+
+ <p>
+ When a user makes or receives a phone call from a device, the corresponding
+ phone account creates an <code>HfpClientConnection</code> object. The Dialer app
+ interacts with the <code>HfpClientConnection</code> object to manage call
+ features, such as accepting a call or hanging up. However, the Dialer app does
+ not indicate which device an incoming call is coming from. To make an outgoing
+ call, the app uses the last connected device. Manufacturers can change this
+ behavior by customizing the Dialer app.
+ </p>
+
+ <h4 id="phone-book-access-profile">Phone Book Access Profile</h4>
+
+ <p>
+ The Bluetooth Phone Book Access Profile (PBAP) downloads contacts
+ from all connected devices. PBAP maintains an aggregated, searchable list of
+ contacts that is updated by PBAP client state machines. Because each device
+ interacts with a separate PBAP client state machine, contacts are associated
+ with the proper device when making a call. When a PBAP client disconnects, the
+ internal database removes all contacts associated with that phone.
+ </p>
+
+ <h3 id="implement-multi-device-hfp">Implement multi-device HFP</h3>
+
+ <p>
+ Using the default Android Bluetooth stack, an IVI automatically has the ability
+ to connect to multiple devices on HFP. The <code>MAX_STATE_MACHINES_POSSIBLE</code>
+ in the <code><a href="https://android.googlesource.com/platform/packages/apps/Bluetooth/+/master/src/com/android/bluetooth/hfpclient/HeadsetClientService.java">
+ HeadsetClientService</a></code> defines the maximum number of simultaneous
+ HFP connections.
+ </p>
+
+ <aside class="note"><strong>Note:</strong> HFP Synchronous Connection
+ Oriented (SCO) connections and phone call
+ audio routing need to be done manually with <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master/binder/android/bluetooth/IBluetoothHeadsetClient.aidl">
+ connectAudio</a></code> in the application Binder.
+ </aside>
+
+ <p>
+ When implementing multi-device HFP, you should customize your Dialer app UI to
+ let users select which device account to use when making a call. The app then
+ calls <code>telecomManager.placeCall</code> with the correct account.
+ </p>
+
+ <h3 id="verify-multi-device-hfp">Verify multi-device HFP</h3>
+
+ <p>
+ To check that multi-device connectivity works properly over Bluetooth:
+ </p>
+
+ <ol>
+ <li>Using Bluetooth, connect a device to the IVI and stream audio from the
+ device.</li>
+ <li>Connect two phones to the IVI over Bluetooth.</li>
+ <li>Pick one phone. Place an outgoing call directly from the phone,
+ and place an outgoing call using the IVI.
+ <ol>
+ <li>Both times, verify the streamed audio pauses and the phone audio
+ plays over the IVI connected speakers.</li>
+ </ol>
+ </li>
+ <li>Using the same phone, receive an incoming call directly on the phone, and
+ receive an incoming call using the IVI.
+ <ol>
+ <li>Both times, verify the stream audio pauses and the
+ phone audio plays over the IVI connected speakers.</li>
+ </ol>
+ </li>
+ <li>Repeat steps 3 and 4 with the other connected phone.</li>
+ </ol>
+
+ <aside class="note"><strong>Note</strong>: The Bluetooth PBAP profile,
+ like the MAP profile, is unidirectional. To connect a device on these profiles,
+ the connection needs to be instantiated from the IVI and not the source device.
+ </aside>
+
+ </body>
+
+</html>
diff --git a/en/devices/bluetooth.html b/en/devices/bluetooth.html
deleted file mode 100644
index ed967e95..00000000
--- a/en/devices/bluetooth.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<html devsite>
- <head>
- <title>Bluetooth</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.
- -->
-
-
-
-<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_bluetooth.png" alt="Android Bluetooth HAL icon"/>
-
-<p>Android provides a default Bluetooth stack that is divided into two layers: The Bluetooth Embedded System (BTE),
-which implements the core Bluetooth functionality, and the Bluetooth Application Layer (BTA), which
-communicates with Android framework applications.</p>
-
-<p>To fully leverage the <a href="http://developer.android.com/about/versions/android-5.0.html#BluetoothBroadcasting">Bluetooth Low Energy APIs</a>
-added in Android 5.0, you should implement the <a href="Android-6.0-Bluetooth-HCI-Reqs.pdf">Android 6.0 Bluetooth HCI Requirements</a>.
-That document initially was provided as the <a href="Android-5.0-Bluetooth-HCI-Reqs.pdf">Android 5.0 Bluetooth HCI Requirements</a>.</p>
-
-<h2 id="architecture">Architecture</h2>
-<p>A Bluetooth system service communicates with the Bluetooth stack through JNI and with applications through Binder IPC. The system service provides developers with access to various Bluetooth profiles. The following diagram shows the general structure of the Bluetooth stack:
-</p>
-
-<img src="images/ape_fwk_bluetooth.png" alt="Android Bluetooth architecture" id="figure1" />
-<p class="img-caption">
- <strong>Figure 1.</strong> Bluetooth architecture
-</p>
-
-<dl>
- <dt>Application framework</dt>
- <dd>At the application framework level is application code, which utilizes the <a
- href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a>
- APIs to interact with the Bluetooth hardware. Internally, this code calls the Bluetooth process through
- the Binder IPC mechanism.</dd>
-
- <dt>Bluetooth system service</dt>
- <dd>The Bluetooth system service, located in <code>packages/apps/Bluetooth</code>, is packaged as an Android
- app and implements the Bluetooth service and profiles at the Android framework layer. This app
- calls into the HAL layer via JNI.</dd>
-
- <dt>JNI</dt>
- <dd>The JNI code associated with <a
- href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> is located in
- <code>packages/apps/Bluetooth/jni</code>. The JNI code calls into the HAL layer and receives
- callbacks from the HAL when certain Bluetooth operations occur, such as when devices are
- discovered.</dd>
-
- <dt>HAL</dt>
- <dd>The hardware abstraction layer defines the standard interface that the <a
- href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> APIs
- and Bluetooth process call into and that you must implement to have your Bluetooth hardware
- function correctly. The header file for the Bluetooth HAL
- is <code>hardware/libhardware/include/hardware/bluetooth.h</code>. Additionally, please review all of the
- <code>hardware/libhardware/include/hardware/bt_*.h</code> files.
- </dd>
-
- <dt>Bluetooth stack</dt>
- <dd>The default Bluetooth stack is provided for you and is located in
- <code>system/bt</code>. The stack implements the generic Bluetooth HAL and
- customizes it with extensions and configuration changes.
- </dd>
-
- <dt>Vendor extensions</dt>
- <dd>To add custom extensions and an HCI layer for tracing, you can create a libbt-vendor module
- and specify these components.
- </dd>
-
- </dl>
-
-<h2 id="implementing">Implementing the HAL</h2>
-<p>The Bluetooth HAL is located in <code>/hardware/libhardware/include/hardware/bluetooth.h</code>.
-Thus, the <code>bluetooth.h</code> file contains the basic interface for the Bluetooth stack, and you must implement its functions.</p>
-
-<p>Profile-specific files are located in the same directory. For details, see the <a
-href="/reference/hal/dir_6b11132f1a015b03f2670f21bef1d871.html">HAL File Reference</a>.</p>
-
-<p>The following is a <strong>partial</strong> list of the profile-related
-files. For the <strong>complete set</strong>, see the <code>/hardware/libhardware/include/hardware/</code> directory:</p>
-
-<ul>
- <li><code>bt_av.h</code>: Includes the interface definition for the A2DP profile.</li>
- <li><code>bt_gatt.h</code>, <code>bt_gatt_client.h</code>, and <code>bt_gatt_server.h</code>: These include the interface definition for the GATT profile.</li>
- <li><code>bt_hf.h</code>: Includes the interface definition for the HFP profile.</li>
- <li><code>bt_hh.h</code>: Includes the interface definition for the HID host profile.</li>
- <li><code>bt_hl.h</code>: Includes the interface definition for the HDP profile.</li>
- <li><code>bt_mce.h</code>: Includes the interface definition for the MAP profile.</li>
- <li><code>bt_pan.h</code>: Includes the interface definition for the PAN profile.</li>
- <li><code>bt_rc.h</code>: Includes the interface definition for the AVRCP profile.</li>
- <li><code>bt_sock.h</code>: Includes the interface definition for RFCOMM sockets.</li>
-</ul>
-
-<p>Keep in mind that your Bluetooth implementation is not constrained to the features
- and profiles exposed in the HAL. You can find the default implementation located
- in the Bluetooth stack in the <code>system/bt</code> directory,
- which implements the default HAL and also extra features and customizations.</p>
-
-
-<h2 id="customizing">Customizing the Native Bluetooth Stack</h2>
-<p>If you are using the default Bluetooth stack, but want to make a few customizations, you can
- do the following:</p>
-<ul>
- <li>Custom Bluetooth profiles - If you want to add Bluetooth profiles that do not have
- HAL interfaces provided by Android, you must supply an SDK add-on download to make the profile available to app developers, make the APIs available in the Bluetooth system process app (<code>packages/apps/Bluetooth</code>), and add them to the default stack (<code>system/bt</code>).</li>
- <li>Custom vendor extensions and configuration changes - You can add things such as extra AT commands or device-specific configuration changes
- by creating a <code>libbt-vendor</code> module. See the <code>/hardware/broadcom/libbt</code> directory
- for an example.</li>
- <li>Host Controller Interface (HCI) - You can provide your own HCI by creating a <code>libbt-hci</code> module, which
- is mainly used for debug tracing. See the <code>external/bluetooth/hci</code> directory for an example.</li>
-</ul>
-
- </body>
-</html>
diff --git a/en/devices/bluetooth/hci_requirements.html b/en/devices/bluetooth/hci_requirements.html
new file mode 100644
index 00000000..d77825d1
--- /dev/null
+++ b/en/devices/bluetooth/hci_requirements.html
@@ -0,0 +1,2311 @@
+<html devsite> <head> <title>HCI Requirements</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>The Host Controller Interface (HCI) is used for interacting with a
+ Bluetooth controller.</p>
+
+ <p>This document provides a list of Bluetooth (BT) and Bluetooth Low
+ Energy (BLE) requirements. The aim is for Host BT stack vendors and BT
+ controller vendors to conform to these platform requirements in order to
+ use the feature set described below</p>
+
+ <p>The Bluetooth Core 4.1 Specification, referred to in this document as
+ the "BT 4.1 core specification," is available on the <a
+ href="https://www.bluetooth.org/en-us/specification/adopted-specifications">Bluetooth
+ SIG website</a> along with other adopted documents.</p>
+ <h2
+ id="general-design-overview">General design overview</h2>
+ <h3
+ id="chip-capabilities-and-configuration">Chip capabilities and
+ configuration</h3>
+ <p>Android, as an open platform, has a matrix of software
+ releases, OEMs, vendors, and platform and chip capabilities.</p>
+
+ <p>To manage the varying landscape and to manage migrations, a design
+ philosophy of allowing BT controllers to expose their capabilities
+ (beyond the standard BT 4.1 core specification) is described in this
+ document. The host BT stack can then use these capabilities to
+ determine which features to enable.</p>
+
+ <h3 id="supporting-open-standards">Supporting open standards</h3>
+ <p> One goal of Android is to support open standards after
+ ratification in a Bluetooth specification. If a feature described
+ below becomes available in standard HCI methods in a future Bluetooth
+ specification, we will lean towards making that approach the default.</p>
+ <h2 id="vendor-specific-capabilities">Vendor-specific capabilities</h2>
+ <p>Vendor-specific command:
+ <code>LE_Get_Vendor_Capabilities_Command</code></p>
+
+ <p>OCF (OpCode Command Field): 0x153</p>
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td></td>
+ <td>NA</td>
+ <td>Empty command parameter list</td>
+ </tr>
+ </table>
+ <p> A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th> <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>max_advt_instances</code></td>
+ <td>1 octet</td>
+ <td>Number of advertisement instances supported</td>
+ </tr>
+ <tr>
+ <td><code>offloaded_resolution_of_private-address</code></td>
+ <td>1 octet</td>
+ <td>BT chip capability of RPA; if supported by a chip,
+ it needs enablement by the host.<br/>
+ 0 = Not capable<br/>
+ 1 = Capable</td>
+ </tr>
+ <tr>
+ <td><code>total_scan_results_storage</code></td>
+ <td>2 octets</td>
+ <td>Storage for scan results in bytes</td>
+ </tr>
+ <tr>
+ <td><code>max_irk_list_sz</code></td>
+ <td>1 octet</td>
+ <td>Number of IRK entries supported in the firmware</td>
+ </tr>
+ <tr>
+ <td><code>filtering_support</code></td>
+ <td>1 octet</td>
+ <td>Support for filtering in the controller.<br/>
+ 0 = Not supported<br/>
+ 1 = Supported</td>
+ </tr>
+ <tr>
+ <td><code>max_filter</code></td>
+ <td>1 octet</td>
+ <td>Number of filters supported</td>
+ </tr>
+ <tr>
+ <td><code>activity_energy_info_support</code></td>
+ <td>1 octet</td>
+ <td>Supports reporting of activity and energy information.<br/>
+ 0 = Not capable<br/>
+ 1 = Capable</td>
+ </tr>
+ <tr>
+ <td><code>version_supported</code></td>
+ <td>2 octets<br/>
+ [0x00, 0x60]</td>
+ <td>Specifies the version of the Google feature spec supported.<br/>
+ byte[0] = major number<br/>
+ byte[1] = minor number</td>
+ </tr>
+ <tr>
+ <td><code>total_num_of_advt_tracked</code></td>
+ <td>2 octets</td>
+ <td>Total number of advertisers tracked for
+ <code>OnLost</code>/<code>OnFound</code> purposes</td>
+ </tr>
+ <tr>
+ <td><code>extended_scan_support</code></td>
+ <td>1 octet</td>
+ <td>Supports extended scan window and interval</td>
+ </tr>
+ <tr>
+ <td><code>debug_logging_supported</code></td>
+ <td>1 octet</td>
+ <td>Supports logging of binary debug information from controller</td>
+ </tr>
+ <tr>
+ <td><code>LE_address_generation_offloading_support</code></td>
+ <td>1 octet</td>
+ <td>0 = Not supported<br/>
+ 1 = supported</td>
+ </tr>
+ </table>
+
+ <p>The <code>max_advt_instances parameter</code> represents the total
+ advertisement instances in the controller. The range of
+ <code>advt_instance</code> IDs will be 0 to
+ <code>max_advt_instances-1</code>.</p>
+
+ <p>An advertisement instance with an ID equal to 0 will map to an
+ existing (default/standard) HCI instance. When operating on a
+ default/standard HCI interface, the standard HCI command set should be
+ used.</p>
+
+ <h2 id="multi-advertiser-support">Multi-advertiser support</h2>
+ <p>The objectives of multi-advertiser support are the following:</p>
+
+ <ul>
+ <li>Ability to support multiple advertisements
+ (<code>max_advt_instances</code>)</li> <li>Different transmit powers
+ to allow for a varying range</li> <li>Different advertising
+ content</li>
+ <li>An individualized response for each advertiser</li>
+ <li>Privacy (non-trackable) for each advertiser</li>
+ <li>Connectable</li>
+ </ul>
+
+ <p>To keep this specification close to existing standards, the
+ following vendor-specific commands are provided. They are derived from
+ the Bluetooth Core 4.1 Specification.</p>
+
+ <h3 id="le_multi_advt_command">LE_Multi_Advt_Command</h3>
+ <p>OCF: 0x154</p>
+
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x01 - <code>Set_Advt_Param_Multi_Sub_Cmd</code><br/>
+ 0x02 - <code>Set_Advt_Data_Multi_Sub_Cmd</code><br/>
+ 0x03 - <code>Set_Scan_Resp_Data_Multi_Sub_Cmd</code><br/>
+ 0x04 - <code>Set_Random_Addr_Multi_Sub_Cmd</code><br/>
+ 0x05 - <code>Set_Advt_Enable_Multi_Sub_Cmd</code></td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x01 - <code>Set_Advt_Param_Multi_Command</code><br/>
+ 0x02 - <code>Set_Advt_Data_Multi_Command</code><br/>
+ 0x03 - <code>Set_Scan_Resp_Data_Multi_Command</code><br/>
+ 0x04 - <code>Set_Random_Addr_Multi_Command</code><br/>
+ 0x05 - <code>Set_Advt_Enable_Multi_Command</code></td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_multi_advt_command-set_advt_param_multi_sub_cmd">LE_Multi_Advt_Command:
+ Set_Advt_Param_Multi_Sub_Cmd</h4>
+ <p>Base reference (referred to below as "spec"):
+ The BT 4.1 core specification, page 964 (LE Set Advertising
+ Parameter Command)</p>
+
+ <p>Sub OCF: 0x01</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Advertising_Interval_Min</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Interval_Max</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Type</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Own_Address_Type</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Own_Address</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Direct_Address_Type</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Direct_Address</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Channel_Map</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Adverstising_Filter_Policy</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Instance</code></td>
+ <td>1 octet</td>
+ <td>Specifies the applicability of the above parameters to an
+ instance</td>
+ </tr>
+ <tr>
+ <td><code>Tx_power</code></td>
+ <td>1 octet</td>
+ <td>Transmit_Power<br/>
+ Unit - in dBm (signed integer)<br/>
+ Range (-70 to +20)</td>
+ </tr>
+ </table>
+
+ <p>The <code>Own_Address</code> parameter could be a
+ host-configured address at the time of setting up this
+ multi-advertisement instance. This provides the ability to have a
+ resolvable private address at the time of the transmit of the first
+ beacon. Advertisement on an instance will continue irrespective of
+ the connection. The host BT stack could issue a command to start
+ advertisement on an instance, post connection.</p>
+
+ <p> A Command Complete event will be generated for this command as
+ specified in the Bluetooth Core 4.1 Specification, per the above
+ command. The controller will respond with a non-success (invalid
+ parameter) code if the advertising instance or <code>Tx_Power</code>
+ parameters are invalid.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x01 [<code>Set_Advt_Param_Multi_Sub_Cmd]</code></td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_multi_advt_command-set_advt_data_multi_sub_cmd">LE_Multi_Advt_Command:
+ Set_Advt_Data_Multi_Sub_Cmd</h4>
+
+ <p>Base reference: The BT 4.1 core specification, page 969 (LE Set
+ Advertising Data Command)</p>
+
+ <p>Sub OCF: 0x02</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Advertising_Data_Length</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Data</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Instance</code></td>
+ <td>1 octet</td>
+ <td>Specifies the applicability of the above parameters to an
+ instance</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command as
+ specified in the Bluetooth Core 4.1 Specification, per the above
+ command. The controller will respond with a non-success code if the
+ advertising instance or <code>Tx_Power</code> parameters are
+ invalid. </p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x02 [<code>Set_Advt_Data_Multi_Sub_Cmd]</code></td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_multi_advt_command-set_scan_resp_data_multi_sub_cmd">LE_Multi_Advt_Command:
+ Set_Scan_Resp_Data_Multi_Sub_Cmd</h4>
+ <p>Base reference: The BT 4.1 core specification, page 970
+ (LE Set Scan Response Data Command)</p>
+
+ <p>Sub OCF: 0x03</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Scan_Response_Data_Length</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Scan_Response_Data</code></td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Instance</code></td>
+ <td>1 octet</td>
+ <td>Specifies the applicability of the above
+ parameters to an instance</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command as
+ specified in the Bluetooth Core 4.1 Specification, per the above
+ command. The controller will respond with a non-success code
+ (invalid parameter) if the advertising instance or
+ <code>Tx_Power</code> parameters are invalid.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x03 [<code>Set_Scan_Resp_Data_Multi_Sub_Cmd]</code></td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_multi_advt_command-set_random_addr_multi_sub_cmd">LE_Multi_Advt_Command:
+ Set_Random_Addr_Multi_Sub_Cmd</h4>
+ <p>Base reference: The BT 4.1 core specification, page 963 (LE Set
+ Random Address Command)</p>
+
+ <p>Sub OCF: 0x04</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td>Random Address</td>
+ <td>Per spec</td>
+ <td>Per spec</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Instance</code></td>
+ <td>1 octet</td>
+ <td>Specifies the applicability of the above parameters to an
+ instance</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x04 [<code>Set_Random_Addr_Multi_Sub_Cmd]</code></td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_multi_advt_command-set_advt_enable_multi_sub_cmd">LE_Multi_Advt_Command:
+ Set_Advt_Enable_Multi_Sub_Cmd</h4>
+ <p>Base reference: The BT 4.1 core specification, page 971 (LE Set
+ Advertise Enable Command in that core specification)</p>
+
+ <p>OCF: 0x05</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Advertising_Enable</code></td>
+ <td>1 octet</td>
+ <td>A value of 1 means enable. Any other value means disable.</td>
+ </tr>
+ <tr>
+ <td><code>Advertising_Instance</code></td>
+ <td>1 octet</td>
+ <td>Specifies the applicability of the above
+ parameters to an instance. Instance 0 means a standard HCI
+ instance.</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Multi_advt_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x05 [<code>Set_Advt_Enable_Multi_Sub_Cmd]</code></td>
+ </tr>
+ </table>
+
+ <h2 id="offloaded-resolution-of-private-address">Offloaded resolution of
+ private address</h2>
+ <p> This feature allows the resolution of a private address in the
+ controller firmware or hardware, which provides the following benefits:
+ </p>
+
+ <ul>
+ <li>Latency involved with the host in resolving a private
+ address</li>
+ <li>Saving power by refraining from waking up the host</li>
+ </ul>
+
+ <h3 id="le_set_rpa_timeout">LE_Set_RPA_Timeout</h3>
+ <p>OCF: 0x15C</p>
+
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>LE_local_IRK</code></td>
+ <td>16 octet</td>
+ <td>The local device IRK used to generate the random resolvable
+ address(es).</td>
+ </tr>
+ <tr>
+ <td><code>tRPA_min</code></td>
+ <td>2 octets</td>
+ <td>The minimum RPA generation timeout in seconds.
+ The controller must generate new resolvable addresses
+ for any advertising/scanning/connection events on or after this
+ timeout.<br/>
+ Valid range: 300-1800</td>
+ </tr>
+ <tr>
+ <td><code>tRPA_max</code></td>
+ <td>2 octets</td>
+ <td>The maximum RPA generation timeout in seconds.
+ The controller must generate new resolvable addresses for
+ any advertising/scanning/connection
+ events on or before this timeout.<br/>
+ Valid range: <code>tRPA_min</code>-1800</td>
+ </tr>
+ </table>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>The status of the command.<br/>
+ <br/>
+ Suggested HCI status values:<br/>
+ 0x00 Success<br/>
+ 0x01 Unknown command (if not supported)<br/>
+ 0x12 Invalid command parameters (if any
+ parameters are outside the given range)</td>
+ </tr>
+ </table>
+
+ <h3 id="le_rpa_offload_command">LE_RPA_offload_Command</h3>
+ <p>OCF: 0x155</p>
+
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>RPA_offload_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x1 - Enable customer specific feature<br/>
+ 0x2 - Add IRK to the list<br/>
+ 0x3 - Remove IRK from the list<br/>
+ 0x4 - Clear IRK list<br/>
+ 0x5 - Read IRK list entry</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_RPA_offload_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x1 - Enable customer specific feature<br/>
+ 0x2 - Add IRK to the list<br/>
+ 0x3 - Remove IRK from the list<br/>
+ 0x4 - Clear IRK list<br/>
+ 0x5 - Read IRK list entry</td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_rpa_offload-enable_cust_specific_sub_command">LE_RPA_offload:
+ Enable_cust_specific_sub_Command</h4>
+ <p>Sub OCF: 0x01</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>enable_customer_specific_feature_set</code></td>
+ <td>1 octet</td>
+ <td>0x01 - Enable offloaded RPA feature<br/>
+ 0x00 - Disable offloaded RPA feature</td>
+ </tr>
+ </table>
+
+ <p>RPA offload is required to be enabled by the host, based on the
+ chip capability. Refer to the
+ <code>LE_Get_Vendor_Capabilities_Command.</code> Each chip can have
+ a varying <code>max_irk_list_sz </code>in the firmware. </p>
+
+ <p>A Command Complete event will be generated for this command.
+ </p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_cust_specific_feature_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x01 [Enable customer-specific feature]</td>
+ </tr>
+ </table>
+
+ <h4 id="le_rpa_offload-add_irk_to_list_sub_command">LE_RPA_offload:
+ Add_IRK_to_list_sub_Command</h4>
+ <p>Sub OCF: 0x02</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>LE_IRK</code></td>
+ <td>16 octets</td>
+ <td>LE IRK (1st byte LSB)</td>
+ </tr>
+ <tr>
+ <td><code>Address_Type</code></td>
+ <td>1 octet</td>
+ <td>0: Public address<br/>
+ 1: Random address</td>
+ </tr>
+ <tr>
+ <td><code>LE_Device_Address</code></td>
+ <td>6 octets</td>
+ <td>Public or random address associated to the IRK (1st byte
+ LSB)</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_cust_specific_feature_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x02 [Add IRK to the list]</td>
+ </tr>
+ <tr>
+ <td><code>LE_IrkList_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Available IRL list entries after current operation</td>
+ </tr>
+ </table>
+
+ <h4 id="le_rpa_offload-remove_irk_to_list_sub_command">LE_RPA_offload:
+ Remove_IRK_to_list_sub_Command</h4>
+ <p>Sub OCF: 0x03</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Address_Type</code></td>
+ <td>1 octet</td>
+ <td>0: Public address<br/>
+ 1: Random address</td>
+ </tr>
+ <tr>
+ <td><code>LE_Device_Address</code></td>
+ <td>6 octets</td>
+ <td>Public or random address that associates to
+ the IRK</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_cust_specific_feature_opcode</code></td>
+ <td>1 octet</td>
+ <td> 0x03 [Remove IRK from the list]</td>
+ </tr>
+ <tr>
+ <td><code>LE_IrkList_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Available IRL list entries after current operation</td>
+ </tr>
+ </table>
+
+ <h4 id="le_rpa_offload-clear_irk_list_sub_command">LE_RPA_offload:
+ Clear_IRK_list_sub_Command</h4>
+ <p>Sub OCF: 0x04</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td>None</td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+
+ <p> A Command Complete event will be generated for this command.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_cust_specific_feature_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x04 [Clear IRK List]</td>
+ </tr>
+ <tr>
+ <td><code>LE_IrkList_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Available IRL list entries after current
+ operation [<code>max_irk_list_sz]</code></td>
+ </tr>
+ </table>
+
+ <h4 id="le_rpa_offload-read_irk_list_sub_command">LE_RPA_offload:
+ Read_IRK_list_sub_Command</h4>
+ <p>Sub OCF: 0x05</p>
+
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>LE_read_IRK_list_entry-index</code></td>
+ <td>1 octet</td>
+ <td>Index of the IRK list [0, <code>max_irk_list_sz-1]</code></td>
+ </tr>
+ </table>
+
+ <p> A Command Complete event will be generated for this command.
+ </p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Event_cust_specific_feature_opcode</code></td>
+ <td>1 octet</td>
+ <td> 0x05 [Read IRK List Entry]</td>
+ </tr>
+ <tr>
+ <td><code>LE_Read_IRK_List_entry</code></td>
+ <td>1 octet</td>
+ <td>Index of the IRK that the host wants to read back (maximum
+ IRK list size is 32)</td>
+ </tr>
+ <tr>
+ <td><code>LE_IRK</code></td>
+ <td>16 octets</td>
+ <td>IRK value</td>
+ </tr>
+ <tr>
+ <td><code>Address_Type</code></td>
+ <td>1 octet</td>
+ <td>0: Public address<br/>
+ 1: Random address</td>
+ </tr>
+ <tr>
+ <td><code>LE_Device_Address</code></td>
+ <td>6 octets</td>
+ <td>Public or random address associated to the IRK</td>
+ </tr>
+ <tr>
+ <td><code>LE_Resolved_Private_Address</code></td>
+ <td>6 octets</td>
+ <td>Current resolved resolvable private address of this IRK</td>
+ </tr>
+ </table>
+
+ <h2 id="batching-of-scan-results">Batching of scan results</h2>
+ <p>A design goal is to enhance how the Bluetooth LE Scan Response event
+ notifications are delivered to the host, in order to save power in the
+ host.</p>
+
+ <p>By reducing how often the controller notifies the host application
+ processor to scan results, the host application processor can stay in
+ idle/sleep longer. This reduces power consumption in the host. The
+ return parameter <code>total_scan_results_storage</code> of
+ <code>LE_Get_Vendor_Capabilities_Command</code> indicates the chip
+ capability for storage of scan results.</p>
+
+ <p>This feature focuses on the management and configuration of the LE
+ Scan Results storage facility in the Bluetooth controller. The storage
+ is used to temporarily batch advertisement data and scan data and
+ metadata that are received by the controller for later delivery to the
+ host.</p>
+
+ <p>Firmware shall support two types of batching, which can be engaged
+ simultaneously:</p>
+
+ <ul>
+ <li>Truncated. Contains the following information elements: {MAC,
+ TX Power, RSSI, Timestamp}</li>
+ <li>Full. Contains the following information elements:
+ {MAC, TX Power, RSSI, Timestamp, Adv Data, Scan Response}</li>
+ </ul>
+
+ <h3 id="le_batch_scan_command">LE_Batch_Scan_Command</h3>
+ <p>OCF: 0x156</p>
+
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x1 - Enable customer-specific feature<br/>
+ 0x2 - Set Batch Scan Storage parameters<br/>
+ 0x3 - Set Batch Scan parameters<br/>
+ 0x4 - Read Batch Scan Result parameters</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.
+ Enabling the customer-specific feature does not start the scan.</p>
+
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x1 - Enable customer-specific feature<br/>
+ 0x2 - Set Batch Scan Storage parameters<br/>
+ 0x3 - Set Batch Scan parameters<br/>
+ 0x4 - Read Batch Scan Result parameters</td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_batch_scan_command-enable-customer-specific-feature">LE_Batch_Scan_Command:
+ Enable Customer Specific feature</h4>
+ <p>Sub OCF: 0x01</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>enable_customer_specific_feature_set</code></td>
+ <td>1 octet</td>
+ <td>0x01 - Enable Batch Scan feature<br/>
+ 0x00 - Disable Batch Scan feature</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x1 - Enable customer-specific feature<br/>
+ 0x2 - Set Batch Scan Storage parameters<br/>
+ 0x3 - Set Batch Scan parameters<br/>
+ 0x4 - Read Batch Scan Result parameters</td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_batch_scan_command-set-batch-scan-storage-param-subcommand">LE_Batch_Scan_Command:
+ Set Batch Scan Storage Param subcommand</h4>
+ <p>Sub OCF: 0x02</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_Full_Max</code></td>
+ <td>1 octet</td>
+ <td>Max storage space (in %) allocated to full style [Range:
+ 0-100]</td>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_Truncated_Max</code></td>
+ <td>1 octet</td>
+ <td>Max storage space (in %) allocated to truncated style [Range:
+ 0-100]</td>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_Notify_Threshold</code></td>
+ <td>1 octet</td>
+ <td>Setup notification level (in %) for individual storage pool
+ [Range: 0-100].<br/>
+ Setting to 0 will disable notification.
+ Vendor-specific HCI event is generated (Storage threshold breach
+ subevent)</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Batch_scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x02 [Set Batch Scan parameters]</td>
+ </tr>
+ </table>
+
+ <h4
+ id="le_batch_scan_command-set-batch-scan-param-subcommand">LE_Batch_Scan_Command:
+ Set Batch Scan Param subcommand</h4>
+ <p>Sub OCF: 0x03</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_Mode</code></td>
+ <td>1 octet</td>
+ <td>0x00 – Batch scan is disabled<br/>
+ 0x01 – Truncated mode is enabled<br/>
+ 0x02 – Full mode is enabled<br/>
+ 0x03 – Truncated and Full mode are enabled</td>
+ </tr>
+ <tr>
+ <td><code>Duty_cycle_scan_window</code></td>
+ <td>4 octets</td>
+ <td>Batch Scan scan time (# of slot)</td>
+ </tr>
+ <tr>
+ <td><code>Duty_cyle_scan_interval</code></td>
+ <td>4 octets</td>
+ <td>Batch Scan interval period (# of slot)</td>
+ </tr>
+ <tr>
+ <td><code>own_address_type</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Public device address<br/>
+ 0x01 - Random device address</td>
+ </tr>
+ <tr>
+ <td><code>Batch_scan_Discard_Rule</code></td>
+ <td>1 octet</td>
+ <td>0 - Discard oldest advertisement<br/>
+ 1 - Discard advertisement with weakest RSSI</td>
+ </tr>
+ </table>
+
+ <p> This sub-command will start batch scanning, if enabled. In
+ Truncated scanning, results are stored in truncated form where the
+ unique key for Truncated style = {<code>BD_ADDR,</code>
+ scan_interval}. This means only one <code>BD_ADDR will</code> be
+ recorded for each scan interval. The record to keep for Truncated
+ mode is the following: {<code>BD_ADDR,</code> Tx Power, RSSI,
+ Timestamp} </p>
+
+ <p> When Full mode is enabled, active scanning will be used and Scan
+ Responses will be recorded. The Full style unique key = {MAC, Ad
+ packet}, irrespective of scan interval. The record to keep for Full
+ mode is {<code>BD_ADDR,</code> Tx Power, RSSI, Timestamp, Ad packet,
+ Scan Response}. In Full style, the same AD packet, when seen
+ multiple times across different scan intervals, is recorded only
+ once. However, in Truncated mode, it is the visibility of
+ <code>BA_ADDR </code>across different scan intervals that is of
+ interest (once per scan interval). The RSSI is the averaged value of
+ all duplicates of a unique advertisement within a scan interval.</p>
+
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Batch_scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x03 [Set Batch Scan Parameters]</td>
+ </tr>
+ </table>
+
+ <h4 id="le_batch_scan_command-read-batch-scan-results-sub-command">
+ LE_Batch_Scan_Command: Read Batch Scan Results sub-command</h4>
+ <p>Sub OCF: 0x04</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_Data_read</code></td>
+ <td>1 octet</td>
+ <td>0x01 – Truncated mode data<br/>
+ 0x02 – Full mode data</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.
+ When the host issues this command, all the results in the controller
+ may not fit in one Command Complete event. The host will iterate
+ issuing this command until the corresponding results in the Command
+ Complete event indicate 0 in the number of records, which indicates
+ the controller has no more records to communicate to the host. Each
+ Command Complete event could contain multiple records of only one
+ type of data (Full or Truncated).</p>
+
+ <p>Controller and host time references are not synchronized. Thus
+ the timestamp needs special explanation. The unit of the timestamp
+ is 50ms. The value of the timestamp is based off when the
+ <code>Read_Batch_Scan_Results_Sub_cmd </code>is given by the host.
+ If a command arrival time is <code>T_c</code> in the firmware, then
+ the actual time the timestamp was taken in the firmware is
+ <code>T_fw.</code> The reporting time will be: (<code>T_c</code> -
+ <code>T_fw)</code>. <code>T_c</code> and <code>T_fw </code>are in
+ the firmware time domain. This lets the host compute how long ago
+ the event happened.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>Batch_scan_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x03 [Set Batch Scan parameters]</td>
+ </tr>
+ <tr>
+ <td><code>Batch_Scan_data_read</code></td>
+ <td>1 octet</td>
+ <td>Identifies the format (Truncated or Full)</td>
+ </tr>
+ <tr>
+ <td><code>num_of_records</code></td>
+ <td>1 octet</td>
+ <td>Number of records of <code>Batch_Scan_data_read</code></td>
+ </tr>
+ <tr>
+ <td><code>format_of_data</code></td>
+ <td>Variable</td>
+ <td><span style="text-decoration:underline;">Truncated
+ Mode:</span><br/>
+ Address[0]: 6 octets<br/>
+ Address_Type[0]: 1 octet<br/>
+ Tx_Pwr[0]: 1 octet<br/>
+ RSSI[0] : 1 octet<br/>
+ Timestamp[0]: 2 octets<br/>
+ [multiple records (<code>num_of_records)</code>
+ with above format]<br/>
+ <br/>
+ <span style="text-decoration:underline;">Full
+ Mode:</span><br/>
+ Address[0]: 6 octets<br/>
+ Address_Type[0]: 1 octet<br/>
+ Tx_Pwr[0]: 1 octet<br/>
+ RSSI[0]: 1 octet<br/>
+ Timestamp[0]: 2 octets<br/>
+ Adv packet_len[0]: 1 octet<br/>
+ Adv_packet[0]: Adv_packet_len octets<br/>
+ Scan_data_resp_len[0]: 1 octet<br/>
+ Scan_data_resp[0]: <code>Scan_data_resp </code>octets<br/>
+ [multiple records with above format
+ (<code>num_of_records)]</code></td>
+ </tr>
+ </table>
+ <h2 id="advertisement-packet-content-filter">Advertisement packet content
+ filte</h2>
+ <p>Use this to enable/disable/setup the
+ Advertising Packet Content Filter (APCF) in the controller.</p>
+
+ <h3 id="le_apcf_command">LE_APCF_Command</h3>
+ <p>OCF: 0x157</p>
+ <table>
+ <tr>
+ <th>Command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x00 - APCF Enable<br/>
+ 0x01 - APCF Set Filtering parameters<br/>
+ 0x02 - APCF Broadcaster Address<br/>
+ 0x03 - APCF Service UUID<br/>
+ 0x04 - APCF Service Solicitation UUID<br/>
+ 0x05 - APCF Local Name<br/>
+ 0x06 - APCF Manufacturer Data<br/>
+ 0x07 - APCF Service Data</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Return status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x00 - APCF Enable<br/>
+ 0x01 - APCF Set Filtering parameters<br/>
+ 0x02 - APCF Broadcaster Address<br/>
+ 0x03 - APCF Service UUID<br/>
+ 0x04 - APCF Service Solicitation UUID<br/>
+ 0x05 - APCF Local Name<br/>
+ 0x06 - APCF Manufacturer Data<br/>
+ 0x07 - APCF Service Data</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-enable_sub_cmd"> LE_APCF_Command:
+ Enable_sub_cmd</h4>
+ <p>Sub OCF: 0x00</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_enable</code></td>
+ <td>1 octet</td>
+ <td>0x01 - Enable APCF feature<br/>
+ 0x00 - Disable APCF feature</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x0 - APCF Enable</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Enable</code></td>
+ <td>1 octet</td>
+ <td>Enable/disable is set via <code>APCF_enable</code></td>
+ </tr>
+ </table>
+ <h4
+ id="le_apcf_command-set_filtering_parameters_sub_cmd">LE_APCF_Command:
+ set_filtering_parameters_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a filter specification
+ or clear a filter list for on-chip filtering.</p>
+ <p>Sub OCF: 0x01</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/> Delete will clear the specific filter
+ along with associated feature entries in other tables.<br/>
+ Clear will clear all the filters and associated entries
+ in other tables.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td> <td>Filter index (0,
+ <code>max_filter-1)</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_Feature_Selection</code></td>
+ <td>2 octets</td>
+ <td>Bit masks for the selected features:<br/>
+ Bit 0: Set to enable Broadcast Address filter<br/>
+ Bit 1: Set to enable Service Data Change filter<br/>
+ Bit 2: Set to enable Service UUID check<br/>
+ Bit 3: Set to enable Service Solicitation UUID check<br/>
+ Bit 4: Set to enable Local Name check<br/>
+ Bit 5: Set to enable Manufacturer Data Check<br/>
+ Bit 6: Set to enable Service Data Check</td>
+ </tr>
+ <tr>
+ <td><code>APCF_List_Logic_Type</code></td>
+ <td>2 octets</td>
+ <td>Logic operation for each feature selection
+ (per bit position) specified in
+ <code>APCF_Feature_Selection.</code><br/>
+ Valid only when a feature is enabled.<br/>
+ Bit position value:<br/>
+ 0: OR<br/>
+ 1: AND<br/>
+ If "AND" logic is selected, an ADV packet will pass
+ the filter only if it contains ALL of the entries in the
+ list.<br/>
+ If "OR" logic is selected, an ADV packet will pass the
+ filter if it contains any of the entries in the list.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Logic_Type</code></td>
+ <td>1 octet</td>
+ <td>0x00: OR<br/>
+ 0x01: AND<br/>
+ Note: The logic type is N/A for the first three fields
+ of <code>APCF_Feature_Selection,</code> which is always "AND"
+ logic. They are only applicable for (Bit 3 ­Bit 6)
+ four fields of <code>APCF_Feature_Selection.</code></td>
+ </tr>
+ <tr>
+ <td><code>rssi_high_thresh</code></td>
+ <td>1 octet</td>
+ <td>[In dBm] the advertiser is considered seen only if the
+ signal is higher than the RSSI high threshold. Otherwise,
+ the firmware must behave as if it never saw it.</td>
+ </tr>
+ <tr>
+ <td><code>delivery_mode</code></td>
+ <td>1 octet</td>
+ <td>0x00 - <code>immediate</code><br/>
+ 0x01 - <code>on_found</code><br/>
+ 0x02 - <code>batched</code></td>
+ </tr>
+ <tr>
+ <td><code>onfound_timeout</code></td>
+ <td>2 octets</td>
+ <td>Valid only if <code>delivery_mode </code>is
+ <code>on_found</code><br/>
+ [in milliseconds]<br/>
+ Time for firmware to linger and collect additional
+ advertisements before reporting.</td>
+ </tr>
+ <tr>
+ <td><code>onfound_timeout_cnt</code></td>
+ <td>1 octet</td>
+ <td>Valid only if <code>delivery_mode</code> is
+ <code>on_found</code><br/>
+ [count]<br/>
+ If an advertisement in <code>onFound</code> lingers in
+ firmware for the <code>onfound_timeout </code>duration,
+ it will collect a few advertisements and the count is checked.
+ If the count exceeds <code>onfound_timeout_cnt</code>,
+ it's reported <code>OnFound</code>,
+ immediately thereafter.</td>
+ </tr>
+ <tr>
+ <td><code>rssi_low_thresh</code></td>
+ <td>1 octet</td> <td>Valid only if <code>delivery_mode</code>
+ is <code>on_found</code> [in dBm].<br/>
+ The advertiser packet is considered as not seen if the RSSI
+ of the received packet is not above the RSSI
+ low threshold.</td>
+ </tr>
+ <tr>
+ <td><code>onlost_timeout</code></td>
+ <td>2 octets</td>
+ <td>Valid only if <code>delivery_mode</code> is
+ <code>on_found</code><br/>
+ [in milliseconds]<br/>
+ If an advertisement, after being found, is not seen
+ contiguously for the <code>lost_timeout </code>period,
+ it will be reported lost. Reporting of lost is immediate.</td>
+ </tr>
+ <tr>
+ <td><code>num_of_tracking_entries</code></td>
+ <td>2 octets</td>
+ <td>Valid only if <code>delivery_mode</code> is
+ <code>on_found</code><br/> [count]<br/>
+ Total number of advertisers to track per filter.</td>
+ </tr>
+ </table>
+
+ <p> RSSI values must use 2's complement to represent negative
+ values. </p>
+
+ <p> Host shall be able to configure multiple filters with
+ <code>APCF_Application_Address_type</code> set to 0x02 (for all
+ broadcaster addresses) to manage various filter combinations. </p>
+
+ <p> Filtering, batching and reporting are inter-related concepts.
+ Every advertisement and related scan response will have to go
+ through all the filters, one after the other. Thus, resulting
+ actions (<code>delivery_mode)</code> are closely tied to filtering.
+ The delivery modes are the following:
+ <code>report_immediately,</code> <code>batch</code>, and
+ <code>onFound.</code> The <code>OnLost</code> value is related to
+ <code>OnFound</code> in the sense that it will come after
+ <code>OnFound</code> when lost. </p>
+
+ <p> The following processing flow depicts the conceptual model.
+ </p>
+ <img src="images/bt_filter_batch_report.png">
+ <p> When an advertisement (or scan response) frame is received, it
+ is applied to all the filters in serial order. It's possible that an
+ advertisement can cause immediate reporting based on one filter and
+ batching of the same due to a different filter action. </p>
+
+ <p> RSSI level thresholds (high and low) give the ability to control
+ when the frame is visible for filter processing, even when a valid
+ packet is received by the controller. In case of delivery mode being
+ set to immediate or batched, the RSSI of an considered for further
+ controller processing. Different apps need different reporting and
+ batching behavior. This allows multiple apps to have direct
+ reporting and/or batching of results in firmware, concurrently. An
+ example is a case when a batch scan is active from one app and later
+ a regular LE scan is issued by another app. Before a batch scan is
+ issued, the framework/app sets appropriate filters. Later, when the
+ second app issues a regular scan, previous batching continues.
+ However, due to the regular scan, it is akin to conceptually adding
+ a null filter (along with all the existing filters) along with the
+ LE scan command. The LE scan command parameters take precedence when
+ active. When the regular LE scan is disabled, the controller will
+ revert back to a previous batch scan, if it existed. </p>
+ <p> The <code>OnFound</code> delivery mode is based on configured
+ filters. A combination that triggers a filter's action to succeed is
+ considered the entity to track for <code>onLost</code>. The
+ corresponding event is the LE Advt tracking subevent. </p>
+ <p> The <code>OnFound/OnLost</code> transition for a filter (if
+ enabled) will look like the following: </p>
+ <img src="images/bt_onfound_onlost.png">
+ <p> A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x02 - APCF Set Filtering Parameters</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of available entries in the filters table</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-broadcast_address_sub_cmd">LE_APCF_Command:
+ broadcast_address_sub_cmd</h4>
+ <p>This subcommand is used to add or delete an advertiser address
+ or to clear the advertiser address list for on-chip filtering.</p>
+ <p>Sub OCF: 0x02</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the specified broadcaster address in
+ the specified filter.<br/>
+ Clear will clear all the broadcaster addresses in the
+ specified filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter index (0, <code>max_filter-1)</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_Broadcaster_Address</code></td>
+ <td>6 octet</td>
+ <td>6-byte device address to add to or delete from the
+ broadcaster address list</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Application_Address_type</code></td>
+ <td>1 octet</td>
+ <td>0x00: Public<br/>
+ 0x01: Random<br/>
+ 0x02: NA (addresses type not applicable)</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x02 - APCF Broadcaster Address</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available in the Broadcast
+ Address table</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-service_uuid_sub_cmd">LE_APCF_Command:
+ service_uuid_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a service UUID or to
+ clear a service UUID list for on-chip filtering.</p>
+ <p>Sub OCF: 0x03</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the specified service UUID
+ address in the specified filter.<br/>
+ Clear will clear all the
+ service UUIDs in the specified filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter index (0, <code>max_filter</code>-1)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_UUID</code></td>
+ <td>2,4,16 octet</td>
+ <td>The Service UUID (16-bit, 32-bit, or 128-bit) for adding
+ to, or deleting from, the list.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_UUID_MASK</code></td>
+ <td>2,4,16 octet</td>
+ <td>The Service UUID Mask (16-bit, 32-bit, or 128-bit) to add
+ to the list. It should have the same length as
+ <code>APCF_UUID.</code></td>
+ </tr>
+ </table>
+
+ <p> A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x03 - APCF Service UUID</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available in the Service UUID
+ table</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-solicitation_uuid_sub_cmd">LE_APCF_Command:
+ solicitation_uuid_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a solicitation UUID or
+ to clear a solicitation UUID list for on-chip filtering.</p>
+ <p>Sub OCF: 0x04</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the solicitation UUID address in
+ the specified filter.<br/>
+ Clear will clear all the
+ solicitation UUIDs in the specified filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter index (0, <code>max_filter</code>-1)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_UUID</code></td>
+ <td>2,4,16 octet</td>
+ <td>The Solicitation UUID (16-bit, 32-bit, or 128-bit) to
+ add to or delete from the list.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_UUID_MASK</code></td>
+ <td>2,4,16 octet</td>
+ <td>The Solicitation UUID Mask (16-bit, 32-bit,
+ or 128-bit) to add to the list. It should have the same
+ length as the <code>APCF_UUID.</code></td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x04 - APCF Solicitation UUID</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available in the Solicitation
+ UUID table</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-local_name_sub_cmd">LE_APCF_Command:
+ local_name_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a local name string or
+ to clear the local name string list for on-chip filtering.</p>
+ <p>Sub OCF: 0x05</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the specified local name string
+ in the specified filter.<br/>
+ Clear will clear all the local name strings in the
+ specified filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter index (0, <code>max_filter</code>-1)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_LocName_Mandata_or_SerData</code></td>
+ <td>Variable size</td>
+ <td>A character string for local name.<br/>
+ <br/>
+ Notes:<br/>
+ i) Currently the max number of characters in a local name
+ string is 29<br/>
+ ii) Not applicable when action is "Clear" (0x2)</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x05 - APCF Local Name</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available in the Local name
+ table.</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-manf_data_sub_cmd">LE_APCF_Command:
+ manf_data_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a manufacturer data
+ string or to clear the manufacturer data string list for on-chip
+ filtering.</p>
+ <p>Sub OCF: 0x06</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the specified manufacturer data
+ string in the specified filter.<br/>
+ Clear will clear all the manufacturer data strings in the
+ specified filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter Index (0, <code>max_filter</code>-1)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_LocName_Mandata_or_SerData</code></td>
+ <td>Variable size</td>
+ <td>A character string for manufacturer data.<br/>
+ <br/>
+ Notes:<br/>
+ i) Currently the max number of characters in a local name
+ string is 29<br/>
+ ii) Not applicable when action is "Clear" (0x2)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_ManData_Mask</code></td>
+ <td>Variable size</td>
+ <td>The manufacture data mask to add to the list. It should
+ have the same length as
+ <code>APCF_LocName_or_ManData_or_SerData</code>.</td>
+ </tr>
+ </table>
+
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x06 - APCF Manufacturer Data</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td> <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available in the Manufacturer
+ Data table.</td>
+ </tr>
+ </table>
+
+ <h4 id="le_apcf_command-service_data_sub_cmd">LE_APCF_Command:
+ service_data_sub_cmd</h4>
+ <p>This subcommand is used to add or delete a service data string
+ or to clear the service data string list for on-chip filtering.</p>
+ <p>Sub OCF: 0x07</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Add<br/>
+ 0x01 - Delete<br/>
+ 0x02 - Clear<br/>
+ Delete will delete the specified service data string in the
+ specified filter.<br/>
+ Clear will clear all the service data strings in the specified
+ filter.</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter Index (0, <code>max_filter</code>-1)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_LocName_Mandata_or_SerData</code></td>
+ <td>Variable size</td>
+ <td>A character string for service data.<br/>
+ <br/>
+ Notes:<br/>
+ i) Currently the max number of characters in a local name
+ string is 29<br/>
+ ii) Not applicable when action is "Clear" (0x2)</td>
+ </tr>
+ <tr>
+ <td><code>APCF_LocName_Mandata_or_SerData_Mask</code></td>
+ <td>Variable size</td>
+ <td>The service data mask to add to the list. It should have
+ the same length as
+ <code>APCF_LocName_or_ManData_or_SerData.</code></td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>APCF_opcode</code></td>
+ <td>1 octet</td>
+ <td>0x07 - APCF Service Data</td>
+ </tr>
+ <tr>
+ <td><code>APCF_Action</code></td>
+ <td>1 octet</td>
+ <td>Echo back command's <code>APCF_Action</code></td>
+ </tr>
+ <tr>
+ <td><code>APCF_AvailableSpaces</code></td>
+ <td>1 octet</td>
+ <td>Number of free entries still available for Service Data
+ table.</td>
+ </tr>
+ </table>
+
+ <h2 id="controller-activity-and-energy-information-command">Controller
+ activity and energy information command</h2>
+ <p>The objective of this information is for higher host system
+ functions to analyzethe total activities of all components, including
+ the BT controller and itsmacro state, in conjunction with what is
+ happening in the apps and framework. Todo this, the following
+ information is required from the BT stack and thecontroller: </p>
+ <ul>
+ <li>BT stack: Reporting the current macro-operational state of the
+ controller</li>
+ <li>Firmware: Reporting aggregate activity and
+ energy information</li>
+ </ul>
+ <p>BT host stack macro states, as determined at the user level:</p>
+ <ul>
+ <li>Idle: [page scan, LE advt, inquiry scan]</li>
+ <li>Scan: [paging/inquiry/trying to connect]</li>
+ <li>Active: [ACL link on, SCO link ongoing, sniff mode]</li>
+ </ul>
+ <p>The activities that the controller keeps track of over its life are
+ Tx time, Rx time, idle time, and total energy consumed. They are cleared
+ when read from the host.</p>
+ <p>Vendor-specific command:
+ <code>LE_Get_Controller_Activity_Energy_Info</code> </p>
+ <p>OCF: 0x159</p>
+ <table>
+ <tr>
+ <th>Sub-command Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td></td>
+ <td> NA</td>
+ <td>Empty command params</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ <tr>
+ <td><code>total_tx_time_ms</code></td>
+ <td>4 octets</td>
+ <td>Total time performing Tx</td>
+ </tr>
+ <tr>
+ <td><code>total_rx_time_ms</code></td>
+ <td>4 octets</td>
+ <td>Total time performing Rx</td>
+ </tr>
+ <tr>
+ <td><code>total_idle_time_ms</code></td>
+ <td>4 octets</td>
+ <td>Total time in idle (non-sleep low power states)</td>
+ </tr>
+ <tr>
+ <td><code>total_energy_used</code></td>
+ <td>4 octets</td>
+ <td>Total energy used [product of current (mA), voltage (V) and time
+ (ms)]</td>
+ </tr>
+ </table>
+
+ <h2 id="le-extended-set-scan-parameters-command">LE extended set scan
+ parameters command</h2>
+ <p>This command can be used to enable a larger scan window and interval
+ in the controller. Per the BT 4.1 core specification, a scan window and
+ interval have an upper bound limit of 10.24 seconds, which hampers
+ applications' longer scan intervals beyond 10.24 seconds.</p>
+ <p>Base reference: The BT 4.1 core specification, page 973 (LE Set Scan
+ Parameters Command)</p>
+ <p>OCF: 0x15A</p>
+ <table>
+ <tr>
+ <th>Cmd Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>LE_Ex_Scan_Type</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Passive scanning. No <code>SCAN_REQ </code>packets shall
+ be sent (default).<br/>
+ 0x01 - Active scanning.
+ <code>SCAN_REQ</code> packets may be sent.</td>
+ </tr>
+ <tr>
+ <td><code>LE_Ex_Scan_Interval</code></td>
+ <td>4 octets</td>
+ <td>Defined as the time interval from when the Controller started its
+ last LE scan until it begins the subsequent LE scan.<br/>
+ Range: 0x0004 to 0x00FFFFFF<br/>
+ Default: 0x0010 (10 ms)<br/>
+ Time = N * 0.625 ms<br/>
+ Time range: 2.5 ms to 10442.25 seconds</td>
+ </tr>
+ <tr>
+ <td><code>LE_Ex_Scan_Window</code></td>
+ <td>4 octets</td>
+ <td>The duration of the LE scan. <code>LE_Scan_Window</code>
+ shall be less than or equal to <code>LE_Scan_Interval</code>.<br/>
+ Range: 0x0004 to 0xFFFF<br/>
+ Default: 0x0010 (10 ms)<br/>
+ Time = N * 0.625 ms<br/>
+ Time Range: 2.5 ms to 40.95 seconds</td>
+ </tr>
+ <tr>
+ <td><code>Own_Address_Type</code></td>
+ <td>1 octet</td>
+ <td>0x00 - Public Device Address (default)<br/>
+ 0x01 - Random Device Address</td>
+ </tr>
+ <tr>
+ <td><code>LE_Ex_Scan_Filter_Policy</code></td>
+ <td></td>
+ <td>0x00 - Accept all advertisement packets (default).
+ Directed advertising packets which are not addressed for this
+ device shall be ignored.<br/>
+ 0x01 - Ignore advertisement packets from devices not
+ in the White List Only list.<br/>
+ Directed advertising packets which are not addressed for this
+ device shall be ignored.</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Status</code></td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ </table>
+
+ <h2 id="get-controller-debug-info-command">Get controller debug info
+ command</h2>
+ <p>The objective of this information element is to acquire controller
+ debug information by a host, in binary form, for post-processing and
+ analysis. This helps debug on-field issues and provides engineers with a
+ toolkit to log information for analysis. A Controller can provide the
+ information when requested by a host via the event (Controller Debug Info
+ sub event) or autonomously when desired by the controller. Example uses
+ could be to report firmware state information, crash dump information,
+ logging information, etc.</p>
+ <p>OCF: 0x15B</p>
+ <table>
+ <tr>
+ <th>Cmd Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td></td>
+ <td>N/A</td>
+ <td>Empty command parameter list</td>
+ </tr>
+ </table>
+ <p>A Command Complete event will be generated for this command.</p>
+ <table>
+ <tr>
+ <th>Return Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td>Status</td>
+ <td>1 octet</td>
+ <td>Command Complete status</td>
+ </tr>
+ </table>
+ <h2 id="hci-event-vendor-specific">HCI event (vendor-specific)</h2>
+ <p>Vendor-specific HCI events are required in some cases. Refer to
+ Figure 5.4 on page 486 of the BT 4.1 core specification. Event
+ parameter 0 will always contain the first sub-event code, based on which
+ the rest of the HCI event is decoded.</p>
+ <table>
+ <tr>
+ <th>Event Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>HCI_vendor_specific_event_code</code></td>
+ <td>1 octet</td>
+ <td>0xFF</td>
+ </tr>
+ <tr>
+ <td><code>sub_event_code</code></td>
+ <td>1 octet</td>
+ <td>A sub-event code will be 1 octet in size, the byte immediately
+ following Parameter Length in the HCI event packet.</td>
+ </tr>
+ </table>
+
+ <h3 id="storage-threshold-breach-subevent">Storage threshold breach
+ subevent</h3>
+ <p>This event indicates that the storage threshold has been breached.
+ </p>
+ <p>Sub-event code = 0x54</p>
+ <table>
+ <tr>
+ <th>Sub-event Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td>None</td>
+ <td></td>
+ <td></td>
+ </tr> </table>
+
+ <h3 id="le-multi-advertising-state-change-subevent">LE multi-advertising
+ state change subevent</h3>
+
+ <p>This event indicates that an advertising instance has changed its
+ state. At this time, this event is only used to indicate which
+ advertising instance was stopped as a result of a connection.</p>
+ <p>Sub-event code = 0x55</p>
+ <table>
+ <tr>
+ <th>Sub-event Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>Advertising_instance</code></td>
+ <td>1 octet</td>
+ <td>Identifies the specific advertising instance.<br/>
+ Valid values are 0 through <code>max_advt_instances</code> -1</td>
+ </tr>
+ <tr>
+ <td><code>State_Change_Reason</code></td>
+ <td>1 octet</td>
+ <td>0x00: Connection received</td>
+ </tr>
+ <tr>
+ <td><code>Connection_handle</code></td>
+ <td>2 octets</td>
+ <td>Identifies the connection that caused the <code>advt</code>
+ instance to be disabled (0xFFFF if invalid)</td>
+ </tr>
+ </table>
+
+ <h3 id="le-advertisement-tracking-subevent">LE advertisement tracking
+ subevent</h3>
+ <p>This event indicates when an advertiser is found or lost.</p>
+ <p>Sub event code = 0x56</p>
+ <table>
+ <tr>
+ <th>Sub Event Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>APCF_Filter_Index</code></td>
+ <td>1 octet</td>
+ <td>Filter Index (0, <code>max_filter-1)</code></td>
+ </tr>
+ <tr>
+ <td><code>Advertiser_State</code></td>
+ <td>1 octet</td>
+ <td>0x00: Advertiser found<br/>
+ 0x01: Advertiser lost</td>
+ </tr>
+ <tr>
+ <td><code>Advt_Info_Present</code></td>
+ <td>1 octet</td>
+ <td>0x00: Advertiser information (<code>Advt_Info)</code>
+ present<br/>
+ 0x01: Advertiser information (<code>Advt_Info)</code> not
+ present</td>
+ </tr>
+ <tr>
+ <td><code>Advertiser_Address</code></td>
+ <td>6 octets</td>
+ <td>Public or random address</td>
+ </tr>
+ <tr>
+ <td><code>Advertiser_Address_Type </code></td>
+ <td>1 octet</td>
+ <td>0x00: Public address<br/>
+ 0x01: Random address</td>
+ </tr>
+ <tr>
+ <td><code>Advt_Info</code></td>
+ <td></td>
+ <td><code>Tx_Pwr[0]</code>: 1 octet<br/>
+ <code>RSSI[0]</code>: 1 octet<br/>
+ <code>Timestamp[0]</code>: 2 octets<br/>
+ <code>Adv packet_len[0]</code>: 1 octet<br/>
+ <code>Adv_packet[0]</code>:
+ <code>Adv_packet_len</code> octets<br/>
+ <code>Scan_data_resp_len[0]</code>: 1 octet<br/>
+ <code>Scan_data_resp[0]</code>:
+ <code>Scan_data_resp </code>octets</td>
+ </tr>
+ </table>
+
+ <h3 id="controller-debug-info-subevent">Controller debug info
+ subevent</h3>
+ <p>This event is used by a Controller to provide binary debug
+ information to a host.</p>
+ <p>Sub event code = 0x57</p>
+ <table>
+ <tr>
+ <th>Sub Event Parameter</th>
+ <th>Size</th>
+ <th>Purpose</th>
+ </tr>
+ <tr>
+ <td><code>debug_block_byte_offset_start</code></td>
+ <td>2 octets</td>
+ <td>Debug block byte offset from the start</td>
+ </tr>
+ <tr>
+ <td><code>last_block</code></td>
+ <td>1 octet</td>
+ <td>0x00: More debug data present<br/>
+ 0x01: Last binary block; no more debug data</td>
+ </tr>
+ <tr>
+ <td><code>cur_pay_load_sz</code></td>
+ <td>2 octets</td>
+ <td>Binary block size in a current event</td>
+ </tr>
+ <tr>
+ <td><code>Debug_Data</code></td>
+ <td>Variable</td>
+ <td>Debug data of <code>cur_payload_sz</code></td>
+ </tr>
+ </table>
+ </body>
+
+</html>
diff --git a/en/devices/bluetooth/images/ape_fwk_bluetooth.png b/en/devices/bluetooth/images/ape_fwk_bluetooth.png
new file mode 100644
index 00000000..f94f0e09
--- /dev/null
+++ b/en/devices/bluetooth/images/ape_fwk_bluetooth.png
Binary files differ
diff --git a/en/devices/bluetooth/images/ape_fwk_hal_bluetooth.png b/en/devices/bluetooth/images/ape_fwk_hal_bluetooth.png
new file mode 100644
index 00000000..e9432e69
--- /dev/null
+++ b/en/devices/bluetooth/images/ape_fwk_hal_bluetooth.png
Binary files differ
diff --git a/en/devices/bluetooth/images/bt_filter_batch_report.png b/en/devices/bluetooth/images/bt_filter_batch_report.png
new file mode 100644
index 00000000..acdd7dfc
--- /dev/null
+++ b/en/devices/bluetooth/images/bt_filter_batch_report.png
Binary files differ
diff --git a/en/devices/bluetooth/images/bt_onfound_onlost.png b/en/devices/bluetooth/images/bt_onfound_onlost.png
new file mode 100644
index 00000000..dc4c65e6
--- /dev/null
+++ b/en/devices/bluetooth/images/bt_onfound_onlost.png
Binary files differ
diff --git a/en/devices/bluetooth/images/fluoride_architecture.png b/en/devices/bluetooth/images/fluoride_architecture.png
new file mode 100644
index 00000000..e6724176
--- /dev/null
+++ b/en/devices/bluetooth/images/fluoride_architecture.png
Binary files differ
diff --git a/en/devices/bluetooth/index.html b/en/devices/bluetooth/index.html
new file mode 100644
index 00000000..4f1e2518
--- /dev/null
+++ b/en/devices/bluetooth/index.html
@@ -0,0 +1,212 @@
+<html devsite>
+ <head>
+ <title>Bluetooth</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.
+ -->
+ <img style="float: right; margin: 0px 15px 15px 15px;"
+ src="/devices/bluetooth/images/ape_fwk_hal_bluetooth.png" alt="Android Bluetooth HAL icon"/>
+
+ <p>
+ Android provides a default Bluetooth stack that supports both Classic Bluetooth
+ and Bluetooth Low Energy. Using Bluetooth, Android devices can create personal
+ area networks to send and receive data with nearby Bluetooth devices.
+ </p>
+
+ <p>
+ In Android 4.3 and later, the Android Bluetooth stack provides the ability to
+ implement Bluetooth Low Energy (BLE). To fully leverage the BLE APIs, follow
+ the <a
+ href="/devices/bluetooth/hci_requirements.html">Android
+ Bluetooth HCI Requirements</a>.
+ Android devices with a qualified chipset can implement either Classic
+ Bluetooth or both Classic Bluetooth and BLE. BLE is not backwards compatible
+ with older Bluetooth chipsets.
+ </p>
+
+ <p>
+ In Android 8.0, the native Bluetooth stack is fully qualified for Bluetooth 5.
+ To use available Bluetooth 5 features, the device needs to have a Bluetooth 5
+ qualified chipset.
+ </p>
+
+ <aside class="note"><strong>Note</strong>: The largest change in the native
+ Bluetooth stack between Android 8.0 and previous versions is the use of
+ <a href="/devices/architecture/treble.html">Treble</a>. Vendor implementations in
+ Android 8.0 must use HIDL instead of <code>libbt-vendor</code>.</aside>
+
+ <h2 id="architecture-android-80">Android 8.0 architecture</h2>
+
+ <p>
+ A Bluetooth application communicates with the Bluetooth process through
+ Binder. The Bluetooth process uses JNI to communicate with the Bluetooth stack
+ and provides developers with access to various Bluetooth profiles. This
+ diagram shows the general structure of the Bluetooth stack:
+ </p>
+
+ <img src="/devices/bluetooth/images/fluoride_architecture.png"
+ alt="Android 8.0 Bluetooth architecture" id="figure1"/>
+ <p class="img-caption">
+ <strong>Figure 1.</strong> Android 8.0 Bluetooth architecture
+ </p>
+
+ <dl>
+ <dt>Application framework</dt>
+ <dd>
+ At the application framework level is application code,
+ which uses the <a
+ href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
+ android.bluetooth</a>
+ APIs to interact with the Bluetooth hardware. Internally, this code calls
+ the Bluetooth process through the Binder IPC mechanism.
+ </dd>
+
+ <dt>Bluetooth system service</dt>
+ <dd>
+ The Bluetooth system service, located in <code>packages/apps/Bluetooth</code>,
+ is packaged as an Android app and implements the Bluetooth services
+ and profiles at the Android framework layer. This app calls into the native
+ Bluetooth stack via JNI.
+ </dd>
+
+ <dt>JNI</dt>
+ <dd>
+ The JNI code associated with android.bluetooth is located in
+ <code>packages/apps/Bluetooth/jni</code>. The JNI code calls into the
+ Bluetooth stack when certain Bluetooth operations occur, such as when
+ devices are discovered.
+ </dd>
+
+ <dt>Bluetooth stack</dt>
+ <dd>
+ The default Bluetooth stack is provided in AOSP and is located in
+ <code>system/bt</code>. The stack implements the generic Bluetooth HAL and
+ customizes it with extensions and configuration changes.
+ </dd>
+
+ <dt>Vendor implementation</dt>
+ <dd>
+ Vendor devices interact with the Bluetooth stack using the Hardware Interface
+ Design Language (HIDL).
+ </dd>
+ </dl>
+
+ <h3 id="hidl">HIDL</h3>
+ <p>
+ <a href="/devices/architecture/hidl.html">HIDL</a>
+ defines the interface between the Bluetooth stack and the vendor
+ implementation. To generate the Bluetooth HIDL files, pass the Bluetooth
+ interface files into the HIDL generation tool. The interface files are located
+ in <code>hardware/interfaces/bluetooth</code>.
+ </p>
+
+ <h3 id="bluetooth-stack-development">Bluetooth stack development</h3>
+ <p>
+ The Android 8.0 Bluetooth stack is a fully qualified Bluetooth stack. The
+ qualification listing is on the Bluetooth SIG website under <a
+ href="https://www.bluetooth.org/tpg/QLI_viewQDL.cfm?qid=35890">QDID 97584</a>.
+ </p>
+
+ <p>
+ The core Bluetooth stack resides in
+ <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master">
+ system/bt</a></code>.
+ Development happens in AOSP, and contributions are welcome.
+ </p>
+
+ <h2 id="architecture-android-7x-and-earlier">Android 7.x and earlier
+ architecture</h2>
+ <p>A Bluetooth system service communicates with the Bluetooth stack
+ through JNI and with applications through Binder IPC. The system service
+ provides developers with access to various Bluetooth profiles. This
+ diagram shows the general structure of the Bluetooth stack:
+ </p>
+
+ <img src="/devices/bluetooth/images/ape_fwk_bluetooth.png"
+ alt="Android Bluetooth architecture" id="figure2" />
+ <p class="img-caption">
+ <strong>Figure 2.</strong> Android 7.x and earlier Bluetooth architecture
+ </p>
+
+ <dl>
+ <dt>Application framework</dt>
+ <dd>At the application framework level is application code, which
+ utilizes the <a
+ href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
+ android.bluetooth</a>
+ APIs to interact with the Bluetooth hardware. Internally, this code
+ calls the
+ Bluetooth process through the Binder IPC mechanism.
+ </dd>
+
+ <dt>Bluetooth system service</dt>
+ <dd>The Bluetooth system service, located in
+ <code>packages/apps/Bluetooth</code>, is packaged as an Android app and
+ implements the Bluetooth service and profiles at the Android framework layer.
+ This app calls into the HAL layer via JNI.
+ </dd>
+
+ <dt>JNI</dt>
+ <dd>The JNI code associated with <a
+ href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
+ android.bluetooth</a>
+ is located in <code>packages/apps/Bluetooth/jni</code>. The JNI code calls
+ into the HAL layer and receives callbacks from the HAL when certain Bluetooth
+ operations occur, such as when devices are discovered.
+ </dd>
+
+ <dt>HAL</dt>
+ <dd>The hardware abstraction layer defines the standard interface that
+ the <a
+ href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
+ android.bluetooth</a>
+ APIs and Bluetooth process call into and that you must implement to have
+ your Bluetooth hardware function correctly. The header file for the Bluetooth
+ HAL is <code>hardware/libhardware/include/hardware/bluetooth.h</code>.
+ Additionally, review all of the
+ <code>hardware/libhardware/include/hardware/bt_*.h</code> files.
+ </dd>
+
+ <dt>Bluetooth stack</dt>
+ <dd>The default Bluetooth stack is provided for you and is located in
+ <code>system/bt</code>. The stack implements the generic Bluetooth HAL
+ and customizes it with extensions and configuration changes.
+ </dd>
+
+ <dt>Vendor extensions</dt>
+ <dd>To add custom extensions and an HCI layer for tracing, you can create a
+ libbt-vendor module and specify these components.
+ </dd>
+
+ </dl>
+
+ <h3 id="implementing-the-hal">Implementing the HAL</h3>
+ <p>The Bluetooth HAL is located in
+ <code>/hardware/libhardware/include/hardware/bluetooth.h</code>.
+ The <code>bluetooth.h</code> file contains the basic interface for the
+ Bluetooth stack, and you must implement its functions.</p>
+
+ <p>Profile-specific files are located in the same directory. For details, see
+ the <a href="/reference/hal/dir_6b11132f1a015b03f2670f21bef1d871.html">
+ HAL File Reference</a>.
+ </p>
+
+ </body>
+</html>
diff --git a/en/devices/bluetooth/verifying_debugging.html b/en/devices/bluetooth/verifying_debugging.html
new file mode 100644
index 00000000..40fcfc34
--- /dev/null
+++ b/en/devices/bluetooth/verifying_debugging.html
@@ -0,0 +1,140 @@
+<html devsite>
+ <head>
+ <title>Verifying and Debugging</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 verify and debug the Bluetooth stack, use the tools provided in
+ AOSP and the Bluetooth Special Interest Group's (SIG) tests.</p>
+
+ <h2 id="testing-and-verifying">Testing and verifying</h2>
+ <p>To test the Bluetooth stack, AOSP provides a mix of unit tests,
+ CTS tests, and tools for the Bluetooth Profile Tuning Suite.</p>
+
+ <h3 id="unit-tests-in-aosp">Unit tests in AOSP</h3>
+ <p>AOSP includes functional and unit tests for the default
+ Bluetooth stack. These tests are located in <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master/test/">
+ system/bt/test</a></code>.
+ To run the AOSP tests, do the following:</p>
+
+ <ol>
+ <li>Stop the Android runtime:
+ <pre class="devsite-terminal devsite-click-to-copy">adb shell stop</pre></li>
+ <li>From the test directory, run the shell executable file and
+ include options if you want to run a specific test or test suite:
+ <pre class="devsite-terminal devsite-click-to-copy">./run_unit_tests.sh <var>TEST_GROUP_NAME</var> <var>TEST_NAME</var> <var>OPTIONS</var></pre></li>
+ <li>When the tests finish, re-enable the Android runtime:
+ <pre class="devsite-terminal devsite-click-to-copy">adb shell start</pre></li>
+ </ol>
+
+ <p>The list of test names can be found in the file <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master/test/run_unit_tests.sh">
+ system/bt/test/run_unit_tests.sh</a></code>.</p>
+
+ <h3 id="android-comms-test-suite">Android Comms Test Suite</h3>
+ <p>The Android Comms Test Suite (ACTS) performs automated testing of
+ connectivity stacks, such as Wi-Fi, Bluetooth, and cellular services.
+ The testing tool requires adb and python, and it can be found in
+ <code><a
+ href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts">
+ tools/test/connectivity/acts</a></code>.</p>
+
+ <p>The ACTS tests for Bluetooth and Bluetooth Low Energy are found in
+ <code><a
+ href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts/tests/google/bt/">
+ tools/test/connectivity/acts/tests/google/bt</a></code>
+ and <code><a
+ href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts/tests/google/ble">
+ tools/test/connectivity/acts/tests/google/ble</a></code>
+ respectively.</p>
+
+ <h3 id="profile-tuning-suite">Profile Tuning Suite</h3>
+ <p>The Bluetooth SIG provides the Bluetooth Profile Tuning Suite (PTS),
+ a testing tool for protocol and profile interoperability.
+ For more information, see the <a
+ href="https://www.bluetooth.com/develop-with-bluetooth/test-tools/profile-tuning-suite">
+ Bluetooth Profile Tuning Suite</a> site.</p>
+
+ <p>AOSP provides additional tools to complement the Bluetooth PTS.
+ These tools are located in <code><a
+ href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts/tests/google/bt/pts/">
+ tools/test/connectivity/acts/tests/google/bt/pts</a></code>.</p>
+
+ <h3 id="cts-tests">CTS Tests</h3>
+ <p>The <a href="https://source.android.com/compatibility/cts/">
+ Compatibility Test Suite</a> (CTS) includes tests for the
+ Bluetooth stack. These are located in <code><a
+ href="https://android.googlesource.com/platform/cts/+/master/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/">
+ cts/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth</a></code>.</p>
+
+ <h2 id="debugging-options">Debugging options</h2>
+ <p>AOSP provides different methods of debugging a device's
+ Bluetooth stack, including logs and bug reports. These methods may
+ not work for issues that cannot be reproduced or for audio issues,
+ which can be affected by multiple parts of the platform and device.
+ </p>
+
+ <h3 id="debugging-with-bug-reports">Debugging with bug reports</h3>
+ <p>To check the Bluetooth service status using <code>dumpsys</code>,
+ use the following command:</p>
+
+ <pre class="devsite-terminal devsite-click-to-copy">adb shell dumpsys bluetooth_manager</pre>
+
+ <p>By default, all log messages are trace level 2.
+ To find out more about the logging levels and change the logging levels
+ for different profiles, look in <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master/conf/bt_stack.conf">
+ system/bt/conf/bt_stack.conf</a></code>.</p>
+
+ <p>To extract snoop logs from the bug report, use the
+ <code>btsnooz</code> script.</p>
+
+ <ol>
+ <li>Get <code><a
+ href="https://android.googlesource.com/platform/system/bt/+/master/tools/scripts/btsnooz.py">
+ btsnooz.py</a></code>.</li>
+ <li>Extract the text version of the bug report.</li>
+ <li>Run <code>btsnooz.py</code> on the text version of the bug report:
+ <pre class="devsite-terminal devsite-click-to-copy">btsnooz.py <em>BUG_REPORT</em>.txt &gt; <em>BTSNOOP</em>.log</pre>
+ </li>
+ </ol>
+
+ <h3 id="debugging-with-logs">Debugging with logs</h3>
+ <p>In Android 4.4 and later, you can manually collect BTSnoop logs,
+ which resemble the snoop format in RFC 1761. These logs capture the
+ Host Controller Interface (HCI) packets.
+ For most Android devices, the logs are stored in
+ <code>data/misc/bluetooth/logs</code>.</p>
+
+ <p>For privacy reasons, always-on, "in-memory" BTSnoop only logs
+ non-personal information and events. To log all data, the user needs
+ to enable Bluetooth HCI snoop by doing the following:</p>
+
+ <ol>
+ <li>Enable <strong>Developer options</strong> on the device.</li>
+ <li>In the <strong>Developer options</strong> menu, activate the
+ <strong>Enable Bluetooth HCI snoop log</strong> toggle.</li>
+ <li>Restart Bluetooth for logging to take effect.</li>
+ </ol>
+
+ </body>
+
+</html>
diff --git a/en/devices/camera/versioning.html b/en/devices/camera/versioning.html
index e4a60626..43795121 100644
--- a/en/devices/camera/versioning.html
+++ b/en/devices/camera/versioning.html
@@ -240,6 +240,87 @@ if you have not made the updates indicated above.</p>
<a href="/compatibility/cts/camera-hal.html">Camera HAL Testing
Checklist</a>.</p>
+<h3 id="80">Android 8.0</h3>
+
+<p>
+The Android 8.0 release contains these key enhancements to the Camera service:
+</p>
+
+<ul>
+ <li>Shared surfaces - Enable multiple surfaces sharing the same
+ <code>OutputConfiguration</code></li>
+ <li>System API for custom camera modes</li>
+ <li><code>onCaptureQueueEmpty</code></li>
+</ul>
+
+<p>
+See the sections below for more information on these features.
+</p>
+
+<h4 id="shared-surfaces">Shared surfaces</h4>
+
+<p>
+This feature enables only one set of buffers to drive two outputs, such as
+preview and video encoding, which lowers power and memory consumption. To
+support this feature, device manufacturers need to ensure their camera HAL and
+gralloc HAL implementations can create gralloc buffers that will be used by
+multiple different consumers (such as the hardware composer/GPU and the video
+encoder), instead of just one consumer. The camera service will pass the
+consumer usage flags to the camera HAL and the gralloc HAL; they need to either
+allocate the right kinds of buffers, or the camera HAL needs to return an error
+that this combination of consumers is not supported.
+</p>
+
+<p>
+See the <code><a
+ href="https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#enableSurfaceSharing()">enableSurfaceSharing</a></code>
+developer documentation for additional details.</p>
+
+<h4 id="system-api-for-custom-camera-modes">System API for custom camera
+ modes</h4>
+
+<p>
+The public camera API defines two operating modes: normal and constrained
+high-speed recording. They have fairly different semantics; high-speed mode is
+limited to at most two specific outputs at once, etc. Various OEMs have
+expressed interest in defining other custom modes for hardware-specific
+capabilities. Under the hood, the mode is just an integer passed to the
+configure_streams. See:
+<code>hardware/libhardware/+/master/include/hardware/camera3.h#1736</code>
+</p>
+
+<p>
+This feature includes a system API call that OEM camera apps can use to enable a
+custom mode. These modes must start at integer value 0x8000 to avoid conflicting
+with future modes added to the public API.
+</p>
+
+<p>
+To support this feature, OEMs merely need to add the new mode to their HAL,
+triggered by this integer passed to the HAL on configure_streams, and then have
+their custom camera app use the system API.
+</p>
+
+<p>
+The method name is <code><a
+ href="https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.StateCallback.html#onCaptureQueueEmpty(android.hardware.camera2.CameraCaptureSession)">android.hardware.camera2.CameraDevice#createCustomCaptureSession</a></code>.
+See:
+<code>frameworks/base/core/java/android/hardware/camera2/CameraDevice.java#797</code>
+
+<p class="note"><strong>Note:</strong> In the Android 8.0 MR1 release, applications must be preinstalled on the system image to access this API.
+</p>
+
+<h4 id="oncapturequeueempty">onCaptureQueueEmpty</h4>
+
+<p>
+The purpose of this API is to reduce the latency of control changes like zoom by
+keeping the request queue as empty as possible. <code>onCaptureQueueEmpty</code>
+requires no HAL work; it was purely a framework-side addition. Applications that
+want to take advantage of it need to add a listener to that callback and respond
+appropriately. Generally that's by sending another capture request to the camera
+device.
+</p>
+
<h3 id="34">3.4</h3>
<p>Minor additions to supported metadata and changes to data_space support:</p>
@@ -255,7 +336,7 @@ definition, using the version 0 definition of dataspace encoding.</li>
<ul>
<li>
<a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#INFO_SUPPORTED_HARDWARE_LEVEL_3"><code>ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3</code>
- </a></li>
+ </a>
<li><code>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST</code></li>
<li><code>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE</code></li>
<li><code>ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL</code></li>
@@ -263,7 +344,7 @@ definition, using the version 0 definition of dataspace encoding.</li>
<li><code>ANDROID_SENSOR_OPAQUE_RAW_SIZE</code></li>
<li><code>ANDROID_SENSOR_OPTICAL_BLACK_REGIONS</code></li>
</ul>
- <li>
+ </li>
</ul>
<h3 id="33">3.3</h3>
diff --git a/en/devices/graphics/arch-sh.html b/en/devices/graphics/arch-sh.html
index c3c74dfe..3b597abb 100644
--- a/en/devices/graphics/arch-sh.html
+++ b/en/devices/graphics/arch-sh.html
@@ -60,9 +60,7 @@ hardware-accelerate the Canvas API. As you can see from the charts on the
Acceleration</a>
page, this was a bit of a bumpy ride. Note in particular that while the Canvas
provided to a View's <code>onDraw()</code> method may be hardware-accelerated, the Canvas
-obtained when an app locks a Surface directly with <code>lockCanvas()</code> never is.
-As of API 23, a hardware-accelerated Canvas can be obtained from a Surface using
-<code>lockHardwareCanvas()</code> instead.</p>
+obtained when an app locks a Surface directly with <code>lockCanvas()</code> never is.</p>
<p>When you lock a Surface for Canvas access, the "CPU renderer" connects to the
producer side of the BufferQueue and does not disconnect until the Surface is
diff --git a/en/devices/storage/config.html b/en/devices/storage/config.html
index f9f31c79..58a031a3 100644
--- a/en/devices/storage/config.html
+++ b/en/devices/storage/config.html
@@ -24,9 +24,13 @@
<p>External storage is managed by a combination of the <code>vold</code> init
-service and <code>StorageManagerService</code> system service. Mounting of physical
-external storage volumes is handled by <code>vold</code>, which performs
-staging operations to prepare the media before exposing it to apps.</p>
+service and <code>StorageManagerService</code> system service. Mounting of
+physical external storage volumes is handled by <code>vold</code>, which
+performs staging operations to prepare the media before exposing it to apps.</p>
+
+<p class="note"><strong>Note:</strong> In Android 8.0, the
+<code>MountService</code> class was renamed to
+<code>StorageManagerService</code>.</p>
<h2 id=file_mappings>File mappings</h2>
<p>For Android 4.2.2 and earlier, the device-specific <code>vold.fstab</code>
@@ -69,9 +73,9 @@ Other possible flags are <code>nonremovable</code>,
<h2 id=configuration_details>Configuration details</h2>
<p>External storage interactions at and above the framework level are handled
-through <code>MountService</code>. Due to configuration changes in Android 6.0 (like the
-removal of the storage_list.xml resource overlay), the configuration details
-are split into two categories.</p>
+through <code>StorageManagerService</code>. Due to configuration changes in
+Android 6.0 (like the removal of the storage_list.xml resource overlay), the
+configuration details are split into two categories.</p>
<h3 id=android_5_x_and_earlier>Android 5.x and earlier</h3>
diff --git a/en/devices/storage/faster-stats.html b/en/devices/storage/faster-stats.html
new file mode 100644
index 00000000..0e43a9e1
--- /dev/null
+++ b/en/devices/storage/faster-stats.html
@@ -0,0 +1,106 @@
+<html devsite>
+ <head>
+ <title>Faster Storage Statistics</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>
+In earlier versions of Android, the system traversed all files owned by a
+particular app to measure disk usage. This manual measurement could take minutes
+to compute before displaying the results to users in Settings.
+</p>
+<p>
+In addition, the internal algorithm to clear cached data files only looked at
+modified time across all apps. This allowed malicious apps to degrade the
+overall user experience by setting modified times far in the future to unfairly
+favor themselves over other apps.
+</p>
+<p>
+To improve these experiences, Android 8.0 offers to leverage the ext4 filesystem's
+"quota" support to return disk usage statistics almost instantly. This quota
+feature also improves system stability by preventing any single app from using
+more than 90% of disk space or 50% of inodes.
+</p>
+<h2 id="implementation">Implementation</h2>
+<p>
+The quota feature is part of the default implementation of <code>installd</code>.
+<code>installd</code> automatically uses the quota feature when enabled on a
+particular filesystem. The system automatically and transparently resumes
+manual calculation when the quota feature isn't enabled or supported on the
+block device being measured.
+</p>
+<p>
+To enable quota support on a particular block device:
+</p>
+<ol>
+<li>Enable the <code>CONFIG_QUOTA</code>, <code>CONFIG_QFMT_V2</code>, and
+<code>CONFIG_QUOTACTL</code> kernel options.</li>
+<li>Add the <code>quota</code> option to your userdata partition in your fstab
+file:
+<pre>
+/dev/block/platform/soc/624000.ufshc/by-name/userdata /data
+ext4 noatime,nosuid,nodev,barrier=1,noauto_da_alloc
+latemount,wait,check,formattable,fileencryption=ice<strong>,quota</strong></pre>
+</li>
+</ol>
+<p>
+The <code>fstab</code> option can safely be enabled or disabled on existing
+devices. During the first boot after changing the <code>fstab</code> option,
+<code>fsmgr</code> forces an <code>fsck</code> pass to update all quota data
+structures, which may cause that first boot to take slightly longer. Subsequent
+boots will not be affected.
+</p>
+<p>
+Quota support has only been tested on ext4 and Linux 3.18 or higher. If enabling
+on other filesystems, or on older kernel versions, device manufacturers are
+responsible for testing and vetting for statistics correctness.
+</p>
+<p>
+No special hardware support is required.
+</p>
+<h2 id="validation">Validation</h2>
+<p>
+There are CTS tests under <code>StorageHostTest</code>, which exercise public
+APIs for measuring disk usage. These APIs are expected to return correct values
+regardless of quota support being enabled or disabled.
+</p>
+<h3 id="debugging">Debugging</h3>
+<p>
+The test app carefully allocates disk space regions using unique prime numbers
+for the size. When debugging these tests, use this to determine the cause of any
+discrepancies. For example, if a test fails with a delta of 11MB, examine the
+<code>Utils.useSpace()</code> method to see that the 11MB blob was stored in
+<code>getExternalCacheDir()</code>.
+</p>
+<p>
+There are also some internal tests that may be useful for debugging, but they
+may require disabling security checks to pass:
+</p>
+
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">runtest -x frameworks/base/services/tests/servicestests/ \
+ src/com/android/server/pm/InstallerTest.java</code>
+<code class="devsite-terminal">adb shell /data/nativetest64/installd_utils_test/installd_utils_test</code>
+<code class="devsite-terminal">adb shell /data/nativetest64/installd_cache_test/installd_cache_test</code>
+<code class="devsite-terminal">adb shell /data/nativetest64/installd_service_test/installd_service_test</code>
+</pre>
+</body>
+</html>
diff --git a/en/devices/tech/config/ambient.html b/en/devices/tech/config/ambient.html
new file mode 100644
index 00000000..97f43f58
--- /dev/null
+++ b/en/devices/tech/config/ambient.html
@@ -0,0 +1,130 @@
+<html devsite>
+ <head>
+ <title>Implementing Ambient Capabilities</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>
+ Capabilities allow Linux processes to drop most root-like privileges, while
+ retaining the subset of privileges that they require to perform their function.
+ The original implementation of capabilities made it impossible for fork+exec'd
+ processes to inherit capabilities unless the files being executed had file
+ capabilities configured. File capabilities, in turn, present a security risk
+ since any process executing a file with file capabilities will be able to gain
+ those capabilities.
+ </p>
+ <p>
+ Ambient capabilities allows system services to configure capabilities in their
+ <code>.rc</code> files, bringing all their configuration into a single file,
+ instead of having to split capabilities configuration to the
+ <code>fs_config.c</code> file.
+ </p>
+ <h2 id="reference-implementation">Reference implementation</h2>
+ <p>
+ The reference implementation is the Android common kernel <a
+ href="https://android.googlesource.com/kernel/common/">https://android.googlesource.com/kernel/common/</a>
+ </p>
+ <h2 id="required-patches">Required patches</h2>
+ <p>
+ Required patches have been backported to all the relevant Android common kernel
+ branches.
+ </p>
+ <p>
+ The main ambient capabilities patch <a
+ href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=58319057b7847667f0c9585b9de0e8932b0fdb08">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=58319057b7847667f0c9585b9de0e8932b0fdb08</a>
+ has been backported in:
+ </p>
+ <ul>
+ <li>android-3.10 branch:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/bdcd4484f1b399dfcb2fd7dd82b6869b2b6b60cd">https://android.googlesource.com/kernel/common/+/bdcd4484f1b399dfcb2fd7dd82b6869b2b6b60cd</a>
+ </ul>
+ <li>android-3.14 branch:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/5440f16f1296ca05f33dfde51e8bb7ad48699640">https://android.googlesource.com/kernel/common/+/5440f16f1296ca05f33dfde51e8bb7ad48699640</a>
+ </ul>
+ <li>android-3.18:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/d6a9a74487e86b528c44965f871de75671b6adb0">https://android.googlesource.com/kernel/common/+/d6a9a74487e86b528c44965f871de75671b6adb0</a>
+ </ul>
+ <li>android-4.1:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/0381789d78d552462ef576d9759e9aa6fcaae3bb">https://android.googlesource.com/kernel/common/+/0381789d78d552462ef576d9759e9aa6fcaae3bb</a></li>
+ </ul>
+ </ul>
+
+ <p>
+ A small security fix <a
+ href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b7f76ea2ef6739ee484a165ffbac98deb855d3d3">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b7f76ea2ef6739ee484a165ffbac98deb855d3d3</a>
+ has been backported in:
+ </p>
+
+ <ul>
+ <li>android-3.10 branch:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/ef89def080c52eb7ea6a9455eb32b1b05867133b">https://android.googlesource.com/kernel/common/+/ef89def080c52eb7ea6a9455eb32b1b05867133b</a>
+ </ul>
+ <li>android-3.14 branch:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/f75626b3092fad4e0bd8f2aed06947352781eb77">https://android.googlesource.com/kernel/common/+/f75626b3092fad4e0bd8f2aed06947352781eb77</a>
+ </ul>
+ <li>android-3.18:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/7bc0ef844a537ebb786ba0574932bd65751818c6">https://android.googlesource.com/kernel/common/+/7bc0ef844a537ebb786ba0574932bd65751818c6</a>
+ </ul>
+ <li>android-4.1:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/dda568cc40d855bde2dfa9c04a7a1628c80b7f63">https://android.googlesource.com/kernel/common/+/dda568cc40d855bde2dfa9c04a7a1628c80b7f63</a></li>
+ </ul>
+ </ul>
+
+ <p>
+ A memory leak fix <a
+ href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d6f3328422a3bc56b0d8dd026a5de845d2abfa7">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d6f3328422a3bc56b0d8dd026a5de845d2abfa7</a>,
+ needed for kernels < 3.18, has been backported in:
+ </p>
+
+ <ul>
+ <li>android-3.10 branch:
+ <ul>
+ <li><a
+ href="https://android.googlesource.com/kernel/common/+/900e52782988ee11a1cb7d600e9edea48fc70f0f">https://android.googlesource.com/kernel/common/+/900e52782988ee11a1cb7d600e9edea48fc70f0f</a></li>
+ </ul>
+ </ul>
+
+ <h2 id="validation">Validation</h2>
+ <p>
+ <a
+ href="https://android.googlesource.com/platform/bionic/+/master#Running-the-tests">Bionic
+ unit tests</a> include unit tests for ambient capabilities. Beyond that, using
+ the "capabilities" keyword in Android init for a service, and then checking that
+ the service gets the expected capabilities would allow for runtime testing of
+ this feature.
+ </p>
+ </body>
+</html>
diff --git a/en/devices/tech/config/perms-whitelist.html b/en/devices/tech/config/perms-whitelist.html
new file mode 100644
index 00000000..79f03263
--- /dev/null
+++ b/en/devices/tech/config/perms-whitelist.html
@@ -0,0 +1,192 @@
+<html devsite>
+ <head>
+ <title>Privileged Permission Whitelist Requirement</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>
+ Historically device implementers had little control over which
+ signature|privileged permissions could be granted to privileged apps.
+ Privileged applications are system applications that are located in
+ <code>/system/priv-app</code> directory on the system image.
+ </p>
+
+ <p>
+ Starting in Android 8.0, all privileged apps must be explicitly whitelisted in
+ system configuration XML files in the <code>/etc/permissions</code> directory.
+ If they are not, then the device will boot, but the device implementation will
+ not pass CTS.
+ </p>
+
+ <h2 id="adding-the-whitelists">Adding the whitelists</h2>
+
+ <p>
+ Permission whitelists for applications can be listed in a single or multiple XML
+ files located in the <code>frameworks/base/etc/permissions</code> directory, as follows:
+ </p>
+
+ <ul>
+ <li><code>/etc/permissions/privapp-permissions-&lt;OEM_NAME&gt;.xml</code>
+ <li><code>/etc/permissions/privapp-permissions-&lt;DEVICE_NAME&gt;.xml</code>.
+ </ul>
+
+ <p>
+ There is no strict rule for organizing content, it can be decided by the device implementer as
+ long as all applications from <code>/system/priv-app</code> are whitelisted. For
+ example, Google has a single whitelist for all privileged applications developed
+ by Google.
+ </p>
+
+ <p>
+ The following organization is recommended:
+ </p>
+
+ <ul>
+ <li>Permissions for apps that are already included in AOSP tree are listed in
+ this file: <code>/etc/permissions/privapp-permissions-platform.xml</code>
+ <li>Permissions for Google applications are listed in this file:
+ <code>/etc/permissions/privapp-permissions-google.xml </code>
+ <li>For other applications, use files of the form:
+ <code>
+ /etc/permissions/privapp-permissions-&lt;device_name&gt;.xml</code></li>
+ </ul>
+
+ <h3 id="whitelist-generation-tool">Whitelist generation tool</h3>
+
+ <p>
+ A whitelist for all applications available on the system image can be
+ automatically generated using a command-line tool available in AOSP, at the
+ following location:
+ </p>
+
+ <pre
+ class="prettyprint">development/tools/privapp_permissions/privapp_permissions.py
+ </pre>
+
+ <p>
+ To generate an initial version of device-specific
+ <code>privapp-permissions.xml</code>, complete the following steps:
+
+ </p>
+ <ol>
+ <li>Build a system image, as follows:<br>
+ <pre>$ . build/envsetup.sh
+$ lunch product_name
+$ make -j</pre>
+ </li>
+
+ <li>Run the following tool to generate a <code>privapp-permissions.xml
+ </code>file that lists all signature|privileged permissions that are required to
+ be whitelisted.<br>
+ <pre>$ development/tools/privapp_permissions/privapp_permissions.py</pre><br>
+
+ This tool prints XML content that can be used as a single file or split into
+ multiple files in <code>/etc/permissions</code>.<br><br>
+ If device already includes whitelists in the <code>/etc/permissions</code> directory, the tool
+ prints the difference, that is, only the missing signature|privileged
+ permissions that need to be added to the whitelist. This is also useful for
+ audit purposes, when a new version of the app is added, the tool will detect the
+ additional permissions needed.
+ </li>
+ <li>Copy the generated files to the <code>/etc/permissions</code> directory, where the system
+ will read it during boot.</li>
+ </ol>
+ <h3 id="whitelist-format">Whitelist format</h3>
+ <ul>
+ <li>Since the implementation is already in AOSP, only customization is needed.
+ <li>Permissions for apps that are included in AOSP tree are already whitelisted
+ in <code>/etc/permissions/privapp-permissions-platform.xml</code>
+ </li>
+ </ul>
+
+
+
+ <pre class="prettyprint">&lt;!--
+ This XML file declares which signature|privileged permissions should be granted to privileged
+ applications that come with the platform
+ -->
+ &lt;permissions>
+ &lt;privapp-permissions package="com.android.backupconfirm">
+ &lt;permission name="android.permission.BACKUP"/>
+ &lt;permission name="android.permission.CRYPT_KEEPER"/>
+ &lt;/privapp-permissions>
+ &lt;privapp-permissions package="com.android.cellbroadcastreceiver">
+ &lt;permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ &lt;permission name="android.permission.MANAGE_USERS"/>
+ &lt;permission name="android.permission.MODIFY_PHONE_STATE"/>
+ &lt;permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ &lt;permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
+ &lt;/privapp-permissions>
+ ...</pre>
+
+ <h3 id="enabling-logs-to-find-missing-permissions">Enabling logs to find missing
+ permissions</h3>
+ <p>
+ When bringing up a new device, we recommend enabling transitional log-mode at
+ first, as follows:
+ </p>
+ <p>
+ <strong> <code>ro.control_privapp_permission=log</code> </strong>
+
+ <p>
+ The violations will be reported in the log file, but permissions will still be
+ granted. This will keep device in a working state, while providing the list of
+ violations.
+ </p>
+ <p>
+ Error message format is as follows:
+ </p>
+ <p>
+
+ <code>PackageManager: Privileged permission {PERMISSION_NAME} for package
+ {PACKAGE_NAME} - not in privapp-permissions whitelist</code>
+ </p>
+ <p>
+ All violations must be addressed by adding them to whitelists. Otherwise device
+ will not pass CTS tests.
+ </p>
+ <h2 id="cts-tests-for-whitelists">CTS tests for whitelists</h2>
+ <p>
+ Your device implementation will not pass CTS if it contains privileged apps that
+ do not appear in a whitelist at <code>/etc/permissions.</code>
+ </p>
+ <p>
+ <code>The </code>PrivappPermissionsTest.java test enforces the
+ signature|privileged permission whitelist, as follows:
+ </p><ul>
+ <li>Reports the permissions that are granted into the CTS log.
+ <li>Ensures all priv permissions are exclusively granted to applications
+ declared in <code>&lt;privapp-permissions&gt;,</code> i.e. it will fail if a
+ privileged application is requesting signature|privileged permission that is not
+ whitelisted or a whitelisted permission wasn't granted by the system.</li></ul>
+ <h2 id="run-time-enforcement-of-whitelists">Run-time enforcement of
+ whitelists</h2>
+ <p>
+ Once the whitelists are in place, run-time enforcement can be enabled by setting
+ a build property <code>ro.control_privapp_permission=enforce</code>.
+ </p>
+ <p>
+ <strong>Note: </strong>Please note that regardless of
+ <code>ro.control_privapp_permission</code> property state, only devices with
+ properly whitelisted privileged permissions for all privileged applications will
+ pass CTS tests.
+ </p>
+
+ </body>
+</html>
diff --git a/en/devices/tech/config/usb-hal.html b/en/devices/tech/config/usb-hal.html
new file mode 100644
index 00000000..0b17e847
--- /dev/null
+++ b/en/devices/tech/config/usb-hal.html
@@ -0,0 +1,94 @@
+<html devsite>
+ <head>
+ <title>Implementing USB 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>
+The Android O release moves handling of USB commands out of <code>init</code>
+scripts and into a native USB daemon for better configuration and code
+reliability. For the Gadget function configuration, <code>init</code> scripts
+(property triggers) are used to perform device-specific gadget operations.
+</p>
+
+<p>
+In previous releases, these device-specific configurations were achieved through
+device-specific <code>init</code> scripts (using property triggers). Moving to a
+Hardware Abstraction Layer (HAL) design results in a much cleaner implementation
+that solves these problems:
+</p>
+
+<ol>
+<li>Operations such as writes to the kernel sysfs nodes could fail but not be
+propagated back to the frameworks code that sets the property trigger. As a
+result, frameworks incorrectly assumes the operations have succeeded even though
+they have silently failed.</li>
+<li><code>init</code> scripts have a limited number of operations that could be
+executed.</li>
+</ol>
+
+<h2 id="hal-and-treble">HAL and Treble</h2>
+
+<p>
+The device-specific <code>init</code> scripts were used as a substitution for
+HAL layers to perform device-specific USB operations. USB (through ADB) is a
+primary interface for debugging system issues. Having a native daemon to perform
+USB configuration eliminates the dependency on the framework code so even if the
+framework crashes USB should be running.
+</p>
+
+<p>
+Under the <a
+href="https://android-developers.googleblog.com/2017/05/here-comes-treble-modular-base-for.html">Treble</a>
+model also introduced in Android O, all of the HALs are isolated from System
+services and are required to run in their own native daemons. This eliminates
+the requirement to have an exclusive USB daemon as the HAL layer nicely doubles
+as a USB daemon.
+</p>
+
+<p>
+The default HAL implementation takes care of all pre-O devices. Therefore, there
+wouldn't be any device-specific work for the pre-O devices. O uses the HAL
+interface to query the status of USB ports and to perform data role and power
+role swaps.
+</p>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+New USB HAL interface needs to be implemented on every device launching on O.
+The default implementation should take care of Pre-O devices. The default
+implementation is sufficient if the device uses the <code>dual_role_usb</code> class to report
+type-c port status. Trivial changes might be required in device-specific USB scripts
+to transfer ownership of the typc-c nodes to system.
+</p>
+
+<p>
+No new platform APIs are introduced.
+</p>
+
+<h2 id="validation">Validation</h2>
+
+<p>
+VTS will test the new USB HAL.
+</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/connect/oob-users.html b/en/devices/tech/connect/oob-users.html
new file mode 100644
index 00000000..323bb594
--- /dev/null
+++ b/en/devices/tech/connect/oob-users.html
@@ -0,0 +1,170 @@
+<html devsite>
+ <head>
+ <title>Customizing Device Behavior for Out-of-Balance Users</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.
+ -->
+
+<h2 id="introduction">Introduction</h2>
+
+<p>Android devices with no data balance allow network traffic through, requiring
+carriers and telcos to implement mitigation protocols. This feature implements a
+generic solution that allows carriers and telcos to indicate when a device has
+run out of balance.</p>
+
+<p>Android platform provides a default carrier app with a default behaviour for
+traffic mitigation based on captive-portal detection signal. It also provides
+carriers and OEMs the opportunity to customize the behaviour with low cost and
+great flexibility.</p>
+
+<h2 id="examples-and-source">Examples and source</h2>
+
+<p>The default carrier app is located at
+<code>platform/frameworks/base/packages/CarrierDefaultApp/</code>.</p>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>The default carrier app is configured to provide a better experience for
+unconfigured carriers out of the box. Carriers can use this default behavior.
+They can also override the default behavior by adding signal-action mappings to
+the carrier config XML file. They can decide not to use the default app and
+instead use UICC privileges with their own standalone carrier app.</p>
+
+<h3 id="implementation-introduction">Implementation introduction</h3>
+
+<h4 id="signals">Signals</h4>
+
+<p>Android framework supports configuring actions to the following parameterized
+signals:</p>
+
+<ul>
+<li><code>TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED</code>
+<li><code>TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED</code></li>
+</ul>
+
+<p>These signals are located in
+<code>frameworks/base/telephony/java/com/android/internal/telephony/TelephonyIntents.java</code>.</p>
+
+<h4 id="supported-actions">Supported actions</h4>
+
+<p>The default carrier app defines a set of supported actions that can be mapped to
+supported signals. These are defined in <code>CarrierActionUtils.java</code>:</p>
+
+<pre class="devsite-click-to-copy">
+ public static final int CARRIER_ACTION_ENABLE_METERED_APNS = 0;
+ public static final int CARRIER_ACTION_DISABLE_METERED_APNS = 1;
+ public static final int CARRIER_ACTION_DISABLE_RADIO = 2;
+ public static final int CARRIER_ACTION_ENABLE_RADIO = 3;
+ public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION = 4;
+ public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
+ public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS = 6;
+</pre>
+
+<p class="note"><strong>Note:</strong> If a carrier implements their own standalone app, then
+they can implement support for signals other than those mentioned in this
+section. They can define and configure their own actions as well.</p>
+
+<h3 id="default-signal-action-mappings">Default signal-action mappings</h3>
+
+<p>Configure default actions by following this process:</p>
+
+<ol>
+<li>Define a key for supported signals.
+<p>The default signal to action mappings are defined in <code>CarrierConfigManager.java</code>.
+Each of the supported signals has a key:</p>
+
+<pre class="devsite-click-to-copy">
+public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY = "carrier_default_actions_on_redirection_string_array";
+public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DCFAILURE_STRING_ARRAY =
+"carrier_default_actions_on_dcfailure_string_array";
+</pre></li>
+
+<li>Associate default actions to signal keys.
+<p>The default action ids are associated to the signal keys:</p>
+
+<pre class="devsite-click-to-copy">
+sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY, new String[]{
+ "1, 4"
+ //1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
+ //4: CARRIER_ACTION_DISABLE_METERED_APNS
+ });
+</pre>
+
+<p>The telephony framework maps these actions to the corresponding signals.</p>
+</li>
+</ol>
+
+<h3>Overriding default actions </h3>
+
+<p>You can define custom actions for supported signals in the carrier config XML
+file by associating action IDs to the signal keys (defined in
+<code>CarrierConfigManager.java</code>). For example, the following mapping
+disables metered APNs and shows a portal notification on redirection:</p>
+
+<pre class="devsite-click-to-copy">
+&lt;string-array name="carrier_default_actions_on_redirection_string_array" num="2"&gt;
+ &lt;item value="1" /&gt;
+ &lt;item value="4" /&gt;
+&lt;/string-array&gt;
+</pre>
+
+<p>The telephony framework loads these configurations and overrides default
+actions.</p>
+
+<h2 id="validation">Validation</h2>
+
+<p>There are no CTS, CTS Verifier, or GTS tests for this feature.</p>
+
+<p>Use these manual validation tests to validate the feature:</p>
+
+<ol>
+<li>Validate telco's device out-of-balance signal notification.
+<li>Verify traffic redirect throttling during out-of-balance state and Wi-Fi
+off.
+<li>Verify network traffic is turned down and notification UI appears during out
+of balance state.
+<li>Validate voice call/VoLTE function during out-of-balance state.
+<li>Verify video calling is blocked in out-of-balance state.
+<li>With Wi-Fi on, verify user can continue web browsing, and the browsing
+traffic does not turn on network traffic while in the out-of-balance state.
+<li>Validate Wi-Fi, WFC, and Bluetooth functions during out-of-balance state.
+<li>Turn Wi-Fi off. Verify the out-of-balance notification UI, and that ordinary
+browsing traffic is not redirected to the telco registration web site. Verify
+clicking the link in the notification UI brings the browser to the telco
+registration web site.
+<li>Verify that toggling airplane mode does not reset the traffic throttling
+state.
+<li>Verify that swapping an in-service SIM resets the network traffic state.
+<li>Verify that re-inserting the out-of-balance SIM restarts traffic redirection
+and obtains network traffic throttling again.
+<li>Verify that rebooting the phone reactivates redirection and brings back the
+traffic throttle and notification UI.
+<li>Tap on the "captiveportal" notification. Verify a restricted network
+connection is established to allow the user to add credits.
+<li>Verify that SIM balance refill or reactivation causes cellular network
+traffic to recover, and the Telco link and no balance notification to go away.
+<li>Sanity test after data service recovery.
+</ol>
+
+<p>The default app provides a few examples of unit tests and a script to run them
+(see <code>tests/runtest.sh</code>). When you implement a customized version or
+behavior, you should mirror those customizations into dedicated unit tests.</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/dalvik/improvements.html b/en/devices/tech/dalvik/improvements.html
new file mode 100644
index 00000000..1461aff1
--- /dev/null
+++ b/en/devices/tech/dalvik/improvements.html
@@ -0,0 +1,206 @@
+<html devsite>
+ <head>
+ <title>Android 8.0 ART Improvements</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>
+The Android runtime (ART) has been improved significantly in the Android 8.0
+release. The list below summarizes enhancements device manufacturers can expect
+in ART.
+</p>
+
+<h2 id="loop-optimizations">Loop optimizations</h2>
+
+<p>
+A wide variety of loop optimizations are employed by ART in the Android 8.0
+release:
+</p>
+ <ul>
+ <li>Bounds check eliminations
+ <ul>
+ <li>Static: ranges are proven to be within bounds at compile-time
+ <li>Dynamic: run-time tests ensure loops stay within bounds (deopt otherwise)
+ </ul>
+ <li>Induction variable eliminations
+ <ul>
+ <li>Remove dead induction
+ <li>Replace induction that is used only after the loop by closed-form expressions
+ </ul>
+ <li>Dead code elimination inside the loop-body, removal of whole loops that
+become dead
+ <li>Strength reduction
+ <li>Loop transformations: reversal, interchanging, splitting, unrolling,
+unimodular, etc.
+ <li>SIMDization (also called vectorization)</li>
+ </ul>
+
+<p>
+The loop optimizer resides in its own optimization pass in the ART compiler.
+Most loop optimizations are similar to optimizations and simplification
+elsewhere. Challenges arise with some optimizations that rewrite the CFG in a
+more than usual elaborate way, because most CFG utilities (see nodes.h) focus on
+building a CFG, not rewriting one.
+</p>
+
+<h2 id="class-hierarchy-analysis">Class hierarchy analysis</h2>
+
+<p>
+ART in Android 8.0 uses Class Hierarchy Analysis (CHA), a compiler optimization
+that devirtualizes virtual calls into direct calls based on the information
+generated by analyzing class hierarchies. Virtual calls are expensive since they
+are implemented around a vtable lookup, and they take a couple of dependent
+loads. Also virtual calls cannot be inlined.
+</p>
+
+<p>
+Here is a summary of related enhancements:
+</p>
+ <ul>
+ <li>Dynamic single-implementation method status updating - At the end of class
+linking time, when vtable has been populated, ART conducts an entry-by-entry
+comparison to the vtable of the super class.</li>
+ <li>Compiler optimization - The compiler will take advantage of the
+single-implementation info of a method. If a method A.foo has
+single-implementation flag set, compiler will devirtualize the virtual call into
+a direct call, and further try to inline the direct call as a result.</li>
+ <li>Compiled code invalidation - Also at the end of class linking time when
+single-implementation info is updated, if method A.foo that previously had
+single-implementation but that status is now invalidated, all compiled code that
+depends on the assumption that method A.foo has single-implementation needs to
+have their compiled code invalidated.</li>
+ <li>Deoptimization - For live compiled code that's on stack, deoptimization will
+be initiated to force the invalidated compiled code into interpreter mode to
+guarantee correctness. A new mechanism of deoptimization which is a hybrid of
+synchronous and asynchronous deoptimization will be used.</li>
+</ul>
+
+<h2 id="inline-caches-in-oat-files">Inline caches in .oat files</h2>
+
+<p>
+ART now employs inline caches and optimizes the call sites for which enough data
+exists. The inline caches feature records additional runtime information into
+profiles and uses it to add dynamic optimizations to ahead of time compilation.
+</p>
+
+<h2 id="dexlayout">Dexlayout</h2>
+
+<p>
+Dexlayout is a library introduced in Android 8.0 to analyze dex files and reorder
+them according to a profile. Dexlayout aims to use runtime profiling information
+to reorder sections of the dex file during idle maintenance compilation on
+device. By grouping together parts of the dex file that are often accessed
+together, programs can have better memory access patterns from improved
+locality, saving RAM and shortening start up time.
+</p>
+
+<p>
+Since profile information is currently available only after apps have been run,
+dexlayout is integrated in dex2oat's on-device compilation during idle
+maintenance.
+</p>
+
+<h2 id="dex-cache-removal">Dex cache removal</h2>
+
+<p>
+Up to Android 7.0, the DexCache object owned four large arrays, proportional to the
+number of certain elements in the DexFile, namely:
+</p>
+
+<ul>
+ <li>
+ strings (one reference per DexFile::StringId),
+ </li>
+ <li>
+ types (one reference per DexFile::TypeId),
+ </li>
+ <li>
+ methods (one native pointer per DexFile::MethodId),
+ </li>
+ <li>
+ fields (one native pointer per DexFile::FieldId).
+ </li>
+</ul>
+
+<p>
+ These arrays were used for fast retrieval of objects that we previously
+ resolved. In Android 8.0, all arrays have been removed except the methods array.
+</p>
+
+<h2 id="interpreter-performance">Interpreter performance</h2>
+
+<p>
+Interpreter performance significantly improved in the Android 7.0 release with the
+introduction of "mterp" - an interpreter featuring a core fetch/decode/interpret
+mechanism written in assembly language. Mterp is modelled after the fast Dalvik
+interpreter, and supports arm, arm64, x86, x86_64, mips and mips64. For
+computational code, Art's mterp is roughly comparable to Dalvik's fast
+interpreter. However, in some situations it can be significantly - and even
+dramatically - slower:
+</p>
+
+ <ol>
+ <li>Invoke performance.</li>
+ <li>String manipulation, and other heavy users of methods recognized as
+intrinsics in Dalvik.</li>
+ <li>Higher stack memory usage.</li>
+ </ol>
+
+<p>
+Android 8.0 addresses these issues.
+</p>
+
+<h2 id="more-inlining">More inlining</h2>
+
+<p>
+Since Android 6.0, ART can inline any call within the same dex files, but could
+only inline leaf methods from different dex files. There were two reasons for
+this limitation:
+</p>
+
+ <ol>
+ <li>Inlining from another dex file requires to use the dex cache of that other
+dex file, unlike same dex file inlining, which could just re-use the dex cache
+of the caller. The dex cache is needed in compiled code for a couple of
+instructions like static calls, string load, or class load.
+ <li>The stack maps are only encoding a method index within the current dex
+file.</li>
+ </ol>
+
+<p>
+To address these limitations, Android 8.0:
+</p>
+
+ <ol>
+ <li>Removes dex cache access from compiled code (also see section "Dex cache
+removal")</li>
+ <li>Extends stack map encoding.</li>
+ </ol>
+
+<h2 id="synchronization-improvements">Synchronization improvements</h2>
+
+<p>
+The ART team tuned the MonitorEnter/MonitorExit code paths, and reduced our
+reliance on traditional memory barriers on ARMv8, replacing them with newer
+(acquire/release) instructions where possible.
+</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/debug/rescue-party.html b/en/devices/tech/debug/rescue-party.html
new file mode 100644
index 00000000..21386957
--- /dev/null
+++ b/en/devices/tech/debug/rescue-party.html
@@ -0,0 +1,107 @@
+<html devsite>
+ <head>
+ <title>Rescue Party</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>
+Many users heavily depend on their phones and require a working device at all
+time. However, sometimes devices end up in reboot loops, which cause users to
+file support tickets or warranty inquiries. This process is frustrating for
+users and expensive for device manufacturers and carriers.
+</p>
+<p>
+Android 8.0 includes a feature that sends out a "rescue party" when it notices
+core system components stuck in crash loops. Rescue Party then escalates through
+a series of actions to recover the device. As a last resort, Rescue Party
+reboots the device into recovery mode and prompts the user to perform a factory
+reset.
+</p>
+<p>
+These rescue features are not required by the <a href="/compatibility/android-cdd">Android
+Compatibility Definition Document</a>, but may still be useful to reduce support cases.
+</p>
+
+<h2 id="implementation">Implementation</h2>
+<p>
+Rescue Party is enabled by default in Android 8.0, and the implementation lives in
+<code>/services/core/java/com/android/server/RescueParty.java</code>.
+Rescue Party receives information about boot and crash events and starts if:
+</p>
+<ul>
+ <li>The system_server restarts more than 5 times in 5 minutes.</li>
+ <li>A persistent system app crashes more than 5 times in 30 seconds.</li>
+</ul>
+<p>
+When one of these situations is detected, Rescue Party escalates to the next
+rescue level, processes the task associated with that level, and lets the device
+proceed to see if it recovers. Each level is progressively more aggressive in
+what it clears or resets. The final level prompts the user to factory reset the
+device.
+</p>
+<p>
+No special hardware support is required to support Rescue Party. If implemented,
+a device's recovery system must respond to the
+<code>--prompt_and_wipe_data</code> command and devices must
+surface a way for users to confirm any destruction of user data before
+proceeding. The recovery system should also give the user the option of
+attempting to boot their device again.
+</p>
+<p>
+Because each rescue level can add up to 5 minutes before a device is operable
+again, device manufacturers should not add custom rescue levels. Increased time
+with an inoperable device makes users more likely to initiate a support or
+warranty inquiry instead of self-recovering their device.
+</p>
+<h2 id="validation">Validation</h2>
+<p>
+All rescue events are suppressed when the device has an active USB data
+connection because that's a strong signal that someone is debugging the device.
+</p>
+<p>
+To override this suppression, run:
+</p>
+
+
+<pre class="devsite-terminal devsite-click-to-copy">adb shell setprop persist.sys.enable_rescue 1</pre>
+<p>
+From there, you can trigger a system or UI crash loop.
+</p>
+<p>
+To trigger a low-level <code>system_server</code> crash loop, run:
+</p>
+
+
+<pre class="devsite-terminal devsite-click-to-copy">adb shell setprop debug.crash_system 1</pre>
+<p>
+To trigger a mid-level SystemUI crash loop, run:
+</p>
+
+
+<pre class="devsite-terminal devsite-click-to-copy">adb shell setprop debug.crash_sysui 1</pre>
+<p>
+Both crash loops initiate the rescue logic. All rescue operations are also
+logged to the persistent PackageManager logs stored at
+<code>/data/system/uiderrors.txt</code> for later inspection and debugging.
+These persistent logs are also included in every bug report under the "Package
+warning messages" section.
+</p>
+</body>
+</html>
diff --git a/en/devices/tech/debug/sanitizers.html b/en/devices/tech/debug/sanitizers.html
new file mode 100644
index 00000000..5e0914bb
--- /dev/null
+++ b/en/devices/tech/debug/sanitizers.html
@@ -0,0 +1,356 @@
+<html devsite>
+ <head>
+ <title>LLVM Sanitizers</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>
+LLVM, the compiler infrastructure used to build Android, contains multiple
+components that perform static and dynamic analysis. Of these components, the
+sanitizers—specifically AddressSanitizer and UndefinedBehaviorSanitizer—can be
+used extensively to analyze Android. Sanitizers are compiler-based
+instrumentation components contained in external/compiler-rt that can be used
+during development and testing to push out bugs and make Android better.
+Android's current set of sanitizers can discover and diagnose many memory misuse
+bugs and potentially dangerous undefined behavior.
+</p>
+<p>
+It's best practice for Android builds to boot and run with sanitizers
+enabled, such as AddressSanitizer and UndefinedBehaviorSanitizer. This page
+introduces AddressSanitizer, UndefinedBehaviorSanitizer, and
+KernelAddressSanitizer, shows how they can be used within the Android build
+system, and gives example Android.mk and Android.bp files that build native
+components with these sanitizers enabled.
+</p>
+
+<h2 id="addresssanitizer">AddressSanitizer</h2>
+<p>
+<a href="https://clang.llvm.org/docs/AddressSanitizer.html">AddressSanitizer</a>
+(ASan) is a compiler-based instrumentation capability that detects many types of
+memory errors in C/C++ code at runtime. ASan can detect many classes of memory
+errors, including:
+</p>
+<ul>
+ <li>Out-of-bounds memory access</li>
+ <li>Double free</li>
+ <li>Use-after-free</li>
+</ul>
+<p>
+Android allows for
+<a href="/devices/tech/debug/asan">ASan
+instrumentation</a> at the full-build level and the <a
+href="/devices/tech/debug/asan#addresssanitizer_in_the_apps">app
+level</a> with asanwrapper.
+</p>
+<p>
+AddressSanitizer combines instrumentation of all memory-related function
+calls—including alloca, malloc, and free—and padding all variables and allocated
+memory regions with memory that triggers an ASan callback when it is read or
+written to.
+</p>
+<p>
+The instrumentation lets ASan detect invalid memory usage bugs, including
+double-free, and use-after scope, return, and free, while the memory-region
+padding detects out-of-bounds read or writes. If a read or write to this padding
+region occurs, ASan catches it and outputs information to help diagnosing the
+memory violation, including the call stack, shadow memory map, the type of
+memory violation, what was read or written, the instruction that caused the
+violation, and the memory contents.
+</p>
+
+
+<pre class="devsite-click-to-copy">
+pixel-xl:/ # sanitizer-status
+=================================================================
+==14164==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x0032000054b0 at pc 0x005df16ffc3c bp 0x007fc236fdf0 sp 0x007fc236fdd0
+WRITE of size 1 at 0x0032000054b0 thread T0
+ #0 0x5df16ffc3b in test_crash_malloc sanitizer-status/sanitizer-status.c:36:13
+ #1 0x5df17004e3 in main sanitizer-status/sanitizer-status.c:76:7
+ #2 0x794cf665f3 in __libc_init (/system/lib64/libc.so+0x1b5f3)
+ #3 0x5df16ffa53 in do_arm64_start (/system/bin/sanitizer-status+0xa53)
+
+0x0032000054b0 is located 0 bytes to the right of 32-byte region [0x003200005490,0x0032000054b0)
+allocated by thread T0 here:
+ #0 0x794d0bdc67 in malloc (/system/lib64/libclang_rt.asan-aarch64-android.so+0x74c67)
+ #1 0x5df16ffb47 in test_crash_malloc sanitizer-status/sanitizer-status.c:34:25
+ #2 0x5df17004e3 in main sanitizer-status/sanitizer-status.c:76:7
+ #3 0x794cf665f3 in __libc_init (/system/lib64/libc.so+0x1b5f3)
+ #4 0x5df16ffa53 in do_arm64_start (/system/bin/sanitizer-status+0xa53)
+ #5 0x794df78893 (&lt;unknown module&gt;)
+
+SUMMARY: AddressSanitizer: heap-buffer-overflow sanitizer-status/sanitizer-status.c:36:13 in test_crash_malloc
+</pre>
+
+<p>
+Sometimes, the bug discovery process can appear to be non-deterministic,
+especially for bugs that require special setup or more advanced techniques, such
+as heap priming or race condition exploitation. Many of these bugs are not
+immediately apparent, and could surface thousands of instructions away from the
+memory violation that was the actual root cause. ASan instruments all
+memory-related functions and pads data with areas that cannot be accessed
+without triggering an ASan callback. This means that memory violations are
+caught the instant they occur, instead of waiting for a crash-inducing
+corruption. This is extremely useful in bug discovery and root cause diagnosis.
+</p>
+<p>
+To verify that ASAN is functional on a target device, Android has included the
+asan_test executable. The asan_test executable tests and validates the ASAN
+functionality on a target device, giving diagnostics messages with the status of
+each test. When using an ASAN Android build, it is located in
+<code>/data/nativetest/asan_test/asan_test</code> or
+<code>/data/nativetest64/asan_test/asan_test</code> by default.
+</p>
+
+<h2 id="undefinedbehaviorsanitizer">UndefinedBehaviorSanitizer</h2>
+<p>
+UndefinedBehaviorSanitizer (UBSan) performs compile-time instrumentation to
+check for various types of undefined behavior. While UBSan is capable of
+detecting
+<a href="https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html">many
+undefined behaviors</a>, Android supports alignment, bool, bounds, enum,
+float-cast-overflow, float-divide-by-zero, integer-divide-by-zero,
+nonnull-attribute, null, return, returns-nonnull-attribute, shift-base,
+shift-exponent, signed-integer-overflow, unreachable, unsigned-integer-overflow,
+and vla-bound. unsigned-integer-overflow, while not technically an undefined
+behavior, is included in the sanitizer and used in many Android modules,
+including the mediaserver components, to eliminate any latent integer-overflow
+vulnerabilities.
+</p>
+
+<h3 id="ubsan-implementation">Implementation</h3>
+<p>
+In the Android build system, you can enable UBSan globally or locally. To enable
+UBSan globally, set SANITIZE_TARGET in Android.mk. To enable UBSan at a
+per-module level, set LOCAL_SANITIZE and specify the undefined behaviors that
+you want to look for in Android.mk. For example:
+</p>
+
+<pre class="devsite-click-to-copy">LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0
+
+LOCAL_SRC_FILES:= sanitizer-status.c
+
+LOCAL_MODULE:= sanitizer-status
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_SANITIZE := alignment bounds null unreachable integer
+LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer
+
+include $(BUILD_EXECUTABLE)
+</pre>
+
+<p>
+The Android build system does not yet support as detailed diagnostics in
+blueprint files as it does makefiles. Here is the closest equivalent written as
+a blueprint (Android.bp):
+</p>
+
+
+<pre class="devsite-click-to-copy">cc_binary {
+
+ cflags: [
+ "-std=c11",
+ "-Wall",
+ "-Werror",
+ "-O0",
+ ],
+
+ srcs: ["sanitizer-status.c"],
+
+ name: "sanitizer-status",
+ tags: ["debug"],
+
+ sanitize: {
+ misc_undefined: [
+ "alignment",
+ "bounds",
+ "null",
+ "unreachable",
+ "integer",
+ ],
+ diag: {
+ undefined : true
+ },
+ },
+
+}
+</pre>
+
+<h3 id="ubsan-shortcuts">UBSan shortcuts</h3>
+<p>
+Android also has two shortcuts, <code>integer</code> and
+<code>default-ub</code>, to enable a set of sanitizers at the same time. integer
+enables<code> integer-divide-by-zero</code>,
+<code>signed-integer-overflow</code> and <code>unsigned-integer-overflow</code>.
+<code>default-ub</code> enables the checks that have minimal compiler
+performance issues: bool, integer-divide-by-zero, return,
+returns-nonnull-attribute, shift-exponent, unreachable and vla-bound. The
+integer sanitizer class can be used with SANITIZE_TARGET and LOCAL_SANITIZE,
+while default-ub can only be used with SANITIZE_TARGET.
+</p>
+
+<h3 id="better-error-reporting">Better error reporting</h3>
+<p>
+Android's default UBSan implementation invokes a specified function when
+undefined behavior is encountered. By default, this function is abort. However,
+starting in October 2016, UBSan on Android has an optional runtime library that
+gives more detailed error reporting, including type of undefined behavior
+encountered, file and source code line information. To enable this error
+reporting with integer checks add the following to an Android.mk file:
+</p>
+
+
+<pre class="devsite-click-to-copy">LOCAL_SANITIZE:=integer
+LOCAL_SANITIZE_DIAG:=integer
+</pre>
+
+<p>
+The LOCAL_SANITIZE value enables the sanitizer during the build.
+LOCAL_SANITIZE_DIAG turns on diagnostic mode for the specified sanitizer. It is
+possible to set LOCAL_SANITIZE and LOCAL_SANITIZE_DIAG to different values, but
+only those checks in LOCAL_SANITIZE are enabled. If a check is not specified in
+LOCAL_SANITIZE, but is specified in LOCAL_SANITIZE_DIAG, the check isn't enabled
+and diagnostic messages aren't given.
+</p>
+<p>
+Here is an example of the information provided by the UBSan runtime library:
+</p>
+
+<pre class="devsite-click-to-copy">pixel-xl:/ # sanitizer-status ubsan
+sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')
+</pre>
+
+<h2 id="kernel-address-sanitizer">Kernel Address Sanitizer</h2>
+<p>
+Similar to the LLVM-based sanitizers for userspace components, Android includes
+the Kernel Address Sanitizer (KASAN). KASAN is a combination of kernel and
+compile time modifications that result in an instrumented system that allows for
+simpler bug discovery and root cause analysis.
+</p>
+<p>
+KASAN can detect many types of memory violations in the kernel. It can also
+detect out-of-bound reads and writes on stack, heap and global variables, and
+can detect use-after-free and double frees.
+</p>
+<p>
+Similar to ASAN, KASAN uses a combination of memory-function instrumentation at
+compile time and shadow memory to track memory accesses at runtime. In KASAN, an
+eighth of the kernel memory space is dedicated to shadow memory, which
+determines if a memory access is valid or not.
+</p>
+<p>
+KASAN is supported on x86_64 and arm64 architectures. It has been part of the
+upstream kernel since 4.0, and has been backported to Android 3.18-based
+kernels. KASAN has been tested on Android kernels compiled with gcc based on
+4.9.2.
+</p>
+<p>
+In addition to KASAN, kcov is another kernel modification that is useful for
+testing. kcov was developed to allow for coverage-guided fuzz testing in the
+kernel. It measures coverage in terms of syscall inputs and is useful with
+fuzzing systems, such as <a
+href="https://github.com/google/syzkaller">syzkaller</a>.
+</p>
+
+<h3 id="kasan-implementation">Implementation</h3>
+<p>
+To compile a kernel with KASAN and kcov enabled, add the following build flags
+to your kernel build configuration:
+</p>
+<pre class="devsite-click-to-copy">
+CONFIG_KASAN
+CONFIG_KASAN_INLINE
+CONFIG_TEST_KASAN
+CONFIG_KCOV
+CONFIG_SLUB
+CONFIG_SLUB_DEBUG
+CONFIG_CC_OPTIMIZE_FOR_SIZE
+</pre>
+
+<p>
+And removing the following:
+</p>
+<pre class="devsite-click-to-copy">
+CONFIG_SLUB_DEBUG_ON
+CONFIG_SLUB_DEBUG_PANIC_ON
+CONFIG_KASAN_OUTLINE
+CONFIG_KERNEL_LZ4
+</pre>
+<p>
+Then build and flash your kernel as usual. The KASAN kernel is considerably
+larger than the original. If applicable, modify any boot parameters and
+bootloader settings to take this into consideration.
+</p>
+<p>
+After flashing the kernel, check the kernel boot logs to see if KASAN is enabled
+and running. The kernel will start up with memory map information for KASAN,
+such as:
+</p>
+
+<pre class="devsite-click-to-copy">
+...
+[ 0.000000] c0 0 Virtual kernel memory layout:
+[ 0.000000] c0 0 kasan : 0xffffff8000000000 - 0xffffff9000000000 ( 64 GB)
+[ 0.000000] c0 0 vmalloc : 0xffffff9000010000 - 0xffffffbdbfff0000 ( 182 GB)
+[ 0.000000] c0 0 vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 GB maximum)
+[ 0.000000] c0 0 0xffffffbdc0000000 - 0xffffffbdc3f95400 ( 63 MB actual)
+[ 0.000000] c0 0 PCI I/O : 0xffffffbffa000000 - 0xffffffbffb000000 ( 16 MB)
+[ 0.000000] c0 0 fixed : 0xffffffbffbdfd000 - 0xffffffbffbdff000 ( 8 KB)
+[ 0.000000] c0 0 modules : 0xffffffbffc000000 - 0xffffffc000000000 ( 64 MB)
+[ 0.000000] c0 0 memory : 0xffffffc000000000 - 0xffffffc0fe550000 ( 4069 MB)
+[ 0.000000] c0 0 .init : 0xffffffc001d33000 - 0xffffffc001dce000 ( 620 KB)
+[ 0.000000] c0 0 .text : 0xffffffc000080000 - 0xffffffc001d32284 ( 29385 KB)
+...
+</pre>
+
+<p>
+And this is how a bug will look:
+</p>
+
+<pre class="devsite-click-to-copy">
+[ 18.539668] c3 1 ==================================================================
+[ 18.547662] c3 1 BUG: KASAN: null-ptr-deref on address 0000000000000008
+[ 18.554689] c3 1 Read of size 8 by task swapper/0/1
+[ 18.559988] c3 1 CPU: 3 PID: 1 Comm: swapper/0 Tainted: G W 3.18.24-xxx #1
+[ 18.569275] c3 1 Hardware name: Android Device
+[ 18.577433] c3 1 Call trace:
+[ 18.580739] c3 1 [&lt;ffffffc00008b32c&gt;] dump_backtrace+0x0/0x2c4
+[ 18.586985] c3 1 [&lt;ffffffc00008b600&gt;] show_stack+0x10/0x1c
+[ 18.592889] c3 1 [&lt;ffffffc001481194&gt;] dump_stack+0x74/0xc8
+[ 18.598792] c3 1 [&lt;ffffffc000202ee0&gt;] kasan_report+0x11c/0x4d0
+[ 18.605038] c3 1 [&lt;ffffffc00020286c&gt;] __asan_load8+0x20/0x80
+[ 18.611115] c3 1 [&lt;ffffffc000bdefe8&gt;] android_verity_ctr+0x8cc/0x1024
+[ 18.617976] c3 1 [&lt;ffffffc000bcaa2c&gt;] dm_table_add_target+0x3dc/0x50c
+[ 18.624832] c3 1 [&lt;ffffffc001bdbe60&gt;] dm_run_setup+0x50c/0x678
+[ 18.631082] c3 1 [&lt;ffffffc001bda8c0&gt;] prepare_namespace+0x44/0x1ac
+[ 18.637676] c3 1 [&lt;ffffffc001bda170&gt;] kernel_init_freeable+0x328/0x364
+[ 18.644625] c3 1 [&lt;ffffffc001478e20&gt;] kernel_init+0x10/0xd8
+[ 18.650613] c3 1 ==================================================================
+</pre>
+
+<p>
+In addition, if modules are enabled in your kernel, you can load the test_kasan
+kernel module for further testing. The module attempts out-of-bounds memory
+accesses and use-after-free and is useful in testing KASAN on a target device.
+</p>
+</body>
+</html>
diff --git a/en/devices/tech/debug/storaged.html b/en/devices/tech/debug/storaged.html
new file mode 100644
index 00000000..be80947e
--- /dev/null
+++ b/en/devices/tech/debug/storaged.html
@@ -0,0 +1,96 @@
+<html devsite>
+ <head>
+ <title>Implementing storaged</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 adds support for <code>storaged</code>, an Android native daemon that
+collects and publishes storage metrics on Android devices.</p>
+
+<ul>
+<li>For daily diskstats, <code>storaged</code> periodically parses
+<code>/sys/block/mmcblk0/stat</code> (eMMC storage devices) or
+<code>/sys/block/sda/stat</code> (non-eMMC devices).</li>
+
+<li>For eMMC lifetime, <code>storaged</code> parses <code>/d/mmc0/mmc0:001/ext_csd</code> (if
+available).</li>
+
+<li>For application I/O blaming, <code>storaged</code> periodically traverses
+<code>/proc/uid_io/stats</code> and maintains parsed data, which includes data
+from all applications (not just running applications). <code>dumpsys</code> can
+call <code>storaged</code> to log the application I/O usage in a bug report.</li>
+</ul>
+
+<p>Diskstat (including stalled diskstats) and eMMC information is logged to the
+Android event log, where a platform checkin service collects the logs.</p>
+
+<p><code>storaged</code> operations occur automatically and are handled entirely by the Android
+framework, so you don't need to do any implementation work. This page
+describes the design of <code>storaged</code> (including new interfaces) and how to use it to
+get I/O status from the kernel.</p>
+
+<h2 id="storaged-design">storaged design</h2>
+
+<p>For accounting and permission flexibility, <code>storaged</code> is implemented as a kernel
+module that returns per-uid I/O information (instead of using standard
+<code>proc/PID/io</code>). Raw I/O data for each I/O request continues to be
+stored and updated in kernel <code>task_struct</code>, and the kernel keeps
+track of when a process exits so it doesn't miss I/O usage that occurs from the
+last <code>storaged</code> polling event.</p>
+
+<p>The module reads raw data and processes it only when the framework notifies it
+of a uid foreground/background switch or when the <code>storaged</code> daemon requests a
+report. At that time, the module exports a file node from kernel for
+communication with framework and <code>storaged</code> daemon.</p>
+
+<p><code>storaged</code> introduces the <code>/proc/uid_io/stats</code> interface, which returns
+a list of I/O stats for each UID in the system. The format is:</p>
+
+<pre>&lt;uid>: &lt;foreground read bytes> &lt;foreground write bytes> &lt;foreground read chars> &lt;foreground write chars> &lt;background read bytes> &lt;background write bytes> &lt;background read chars> &lt;background write chars>
+</pre>
+
+<ul>
+<li>read/write bytes are I/O events from a storage device.</li>
+<li>read/write chars (also in bytes) are data requested by read/write
+syscalls.</li>
+</ul>
+
+<h2 id="getting-i-o-status-from-the-kernel">Getting I/O status from the
+kernel</h2>
+
+<p>To dump I/O usage from the kernel, use the <code>storaged</code> command with
+the <strong><code>-u</code></strong> option.</p>
+
+<p>Command: <code>storaged -u</code></p>
+
+<p>Command output format: <code>name/uid fg_rchar fg_wchar fg_rbytes fg_wbytes
+bg_rchar bg_wchar bg_rbytes bg_wbytes fg_fsync bg_fsync</code></p>
+
+<p class="note"><strong>Note: </strong>This output is similar to the output for
+<code>proc/uid_io/stats</code>. This is because <code>storaged</code> processes data from
+<code>/proc/uid_io/stats</code> and generates its own data.</p>
+
+<p>Example output:</p>
+
+<pre>com.google.android.backuptransport 2269 60 0 0 1719845663 143912573 149065728 184180736
+com.android.vending 2170 60 0 0 219904796 38693092 174436352 18944000</pre>
+
+</body>
+</html>
diff --git a/en/devices/tech/display/adaptive-icons.html b/en/devices/tech/display/adaptive-icons.html
new file mode 100644
index 00000000..815e9b9c
--- /dev/null
+++ b/en/devices/tech/display/adaptive-icons.html
@@ -0,0 +1,148 @@
+<html devsite>
+ <head>
+ <title>Implementing Adaptive Icons</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>
+ Adaptive Icons maintain a consistent shape intra-device but vary from device to
+ device with only one icon asset provided by the developer. Additionally, icons
+ support two layers (foreground and background) that can be used for motion to
+ provide visual delight to users.
+ </p>
+ <p>
+ Device implementers provide a device mask that will decide the shape of all icons on a
+ device. This icon will be used on any system UI surfaces that use Launcher Icons
+ (e.g., launcher, overview, settings and share sheet).
+ </p>
+ <h2 id="examples-and-source">Examples and source</h2>
+ <p>
+ Code examples:
+ </p><ul>
+ <li><code>platform/development/samples/AdaptiveIconSample/</code></li></ul>
+ <p>
+
+ Developer documentation:
+ </p><ul>
+ <li><a
+ href="https://developer.android.com/preview/features/adaptive-icons.html">https://developer.android.com/preview/features/adaptive-icons.html</a>
+ <li><a
+ href="https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html">https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html</a>
+ <li><a
+ href="https://developer.android.com/reference/android/graphics/drawable/Icon.html#createWithAdaptiveBitmap(android.graphics.Bitmap)">https://developer.android.com/reference/android/graphics/drawable/Icon.html#createWithAdaptiveBitmap(android.graphics.Bitmap)</a></li></ul>
+ <p>
+
+ Source code:
+ </p><ul>
+ <li><code>platform/frameworks/base/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java</code></li></ul>
+ <h2 id="implementation">Implementation</h2>
+ <p>
+ To change the shape of the icon on a platform, overlay one string in
+ <code>framework/base/core/res/res/values/config.xml</code>, as follows:
+ </p>
+
+ <pre
+ class="prettyprint">&lt;!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
+ &lt;string name="config_icon_mask" translatable="false">"M50,0L100,0 100,100 0,100 0,0z"&lt;/string></pre>
+ <p>
+ The format and syntax of the string follow the <a
+ href="https://www.w3.org/TR/SVG/paths.html">W3, SVG standard for path
+ definition</a>. This format for PathData is what Android vector drawables
+ support as well.
+ </p>
+ <p>
+ This path should be convex and should respect the safezone (66/71 = 91%) within
+ the view bounds. This is enforced in one of the CTS tests.
+ </p>
+ <p>
+ If you decide to use a circle as the platform mask, make sure to also overlay
+ config_useRoundIcon = true. If not, set this config value false or do not
+ specify this config value.
+ </p>
+ <h2>Adaptive Icon API</h2>
+ <p>
+ The API for the <code>AdaptiveIconDrawable</code> class is shown below:
+ </p>
+
+
+ <pre
+ class="prettyprint">package android.graphics.drawable;
+ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback {
+ method public Drawable getBackground();
+ method public Drawable getForeground();
+ method public Path getIconMask();
+ method public Region getSafeZone();
+ method public float getExtraInsetFraction();
+ method public int getOpacity();
+ method public void invalidateDrawable(Drawable);
+ method public void scheduleDrawable(Drawable, Runnable, long);
+ method public void setAlpha(int);
+ method public void setColorFilter(ColorFilter);
+ method public void setOpacity(int);
+ method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+ }</pre>
+
+
+
+ <pre
+ class="prettyprint">public class Icon extends Parceleable {
+ method public Bitmap createWithAdaptiveBitmap();
+ }</pre>
+ <h2>Reference Implementation</h2>
+ <p>
+ Nothing needs to be done to render the static adaptive icons on any of the
+ System UI surfaces. When PackageManager returns a drawable, simply bind that to
+ an ImageView. This is how icons are already rendered in Pre-O platforms.
+ </p>
+ <p>
+ Regarding rendering dynamic motion effect, Launcher3
+ (platform/packages/apps/Launcher3) will have a reference implementation showing
+ how to achieve the effect in O-MR1.
+ </p>
+ <h2 id="validation">Validation</h2>
+ <p>
+ To validate the implementation, after overriding the mask of their liking, see
+ if icons are rendered correctly in Launcher3, Settings, Overview and Settings.
+ You may also run AdaptiveIconDrawableTest.java and AdaptiveIconMaskTest.java
+ inside graphics CTS TestCase to test the implementation.
+ </p>
+ <p>
+ A recommended manual test case can be found at:
+ platform/development/samples/AdaptiveIconSample/.
+ </p>
+ <h2>Known Issues</h2>
+ <p>
+ Known issues include the following:
+ </p><ul>
+ <li>Blurry icons, depending on how the mask path is defined.
+ <li>Zoomed-in shortcut icons if app developers do not use the
+ <code>Icon.createWithAdaptiveBitmap()</code> method, or do not use this method
+ properly. For this method to function properly, the passed in Bitmap should be
+ padded 25% on all four sides. </li></ul>
+ <p>
+ These issues can be addressed as follows:
+ </p><ul>
+ <li>The mask should be defined in [0, 100] x [0, 100] coordinate system.
+ <li>Make sure that images used for adaptive icons (launcher icons , shortcuts)
+ have sufficient padding (25%) on all four sides.</li></ul>
+
+ </body>
+</html>
diff --git a/en/devices/tech/display/images/split-screen-example-ux.png b/en/devices/tech/display/images/split-screen-example-ux.png
new file mode 100644
index 00000000..3fc9aee5
--- /dev/null
+++ b/en/devices/tech/display/images/split-screen-example-ux.png
Binary files differ
diff --git a/en/devices/tech/display/multi-window.html b/en/devices/tech/display/multi-window.html
index dbb8df30..5e1a9bd2 100644
--- a/en/devices/tech/display/multi-window.html
+++ b/en/devices/tech/display/multi-window.html
@@ -66,6 +66,11 @@ top-to-bottom, depending on the device orientation.
<p>
Then device manufacturers can choose if they want to enable freeform or PIP.
</p>
+<p>
+Android 8.0 improves split-screen by compressing the launcher when the user
+taps <strong>Home</strong>. For implementation details, see
+<a href="/devices/tech/display/split-screen">Split-screen Interactions</a>.
+</p>
<h3 id="freeform">Freeform</h3>
<p>
After enabling standard multi-window mode with the flag
@@ -97,7 +102,11 @@ device form factors may support this feature.
<p>
To support PIP, enable the PackageManager#FEATURE_PICTURE_IN_PICTURE system
feature in <a
-href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/content/pm/PackageManager.java">/android/frameworks/base/core/java/android/content/pm/PackageManager.java</a>.
+ href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/content/pm/PackageManager.java">/android/frameworks/base/core/java/android/content/pm/PackageManager.java</a>.
+</p>
+<p>
+For more PIP implementation details for devices running Android 8.0 and above,
+see the <a href="/devices/tech/display/pip">Picture-in-picture</a> page.
</p>
<h3 id="system-ui">System UI</h3>
<p>
diff --git a/en/devices/tech/display/night-light.html b/en/devices/tech/display/night-light.html
index 8c6609ff..2568b0ef 100644
--- a/en/devices/tech/display/night-light.html
+++ b/en/devices/tech/display/night-light.html
@@ -27,7 +27,8 @@
Research suggests that blue light from screens can have a negative impact on
sleep. Android 7.1.1 includes a feature called Night Light that reduces the
amount of blue light emitted by the device display to better match the natural
-light of the user's time of day and location.
+light of the user's time of day and location. Android 8.0 includes a feature
+that gives users more control over the intensity of the Night Light effect.
</p>
<p>
Night Light requires a
@@ -46,20 +47,28 @@ using the following flags defined in:
<pre class="devsite-click-to-copy">
&lt;!-- Control whether Night display is available. This should only be enabled
on devices with HWC 2 color transform support. --&gt;
- &lt;bool name="config_nightDisplayAvailable">false&lt;/bool&gt;
+ &lt;bool name="config_nightDisplayAvailable"&gt;false&lt;/bool&gt;
&lt;!-- Default mode to control how Night display is automatically activated.
One of the following values (see NightDisplayController.java):
0 - AUTO_MODE_DISABLED
1 - AUTO_MODE_CUSTOM
2 - AUTO_MODE_TWILIGHT
--&gt;
- &lt;integer name="config_defaultNightDisplayAutoMode">0&lt;/integer&gt;
+ &lt;integer name="config_defaultNightDisplayAutoMode"&gt;0&lt;/integer&gt;
&lt;!-- Default time when Night display is automatically activated.
Represented as milliseconds from midnight (e.g. 79200000 == 10pm). --&gt;
- &lt;integer name="config_defaultNightDisplayCustomStartTime">79200000&lt;/integer&gt;
+ &lt;integer name="config_defaultNightDisplayCustomStartTime"&gt;79200000&lt;/integer&gt;
&lt;!-- Default time when Night display is automatically deactivated.
Represented as milliseconds from midnight (e.g. 21600000 == 6am). --&gt;
- &lt;integer name="config_defaultNightDisplayCustomEndTime">21600000&lt;/integer&gt;
+ &lt;integer name="config_defaultNightDisplayCustomEndTime"&gt;21600000&lt;/integer&gt;
+
+ &lt;!-- Minimum color temperature, in Kelvin, supported by Night display. --&gt;
+ &lt;integer name="config_nightDisplayColorTemperatureMin"&gt;2596&lt;/integer&gt;
+ &lt;!-- Default color temperature, in Kelvin, to tint the screen when Night display is
+ activated. --&gt;
+ &lt;integer name="config_nightDisplayColorTemperatureDefault"&gt;2850&lt;/integer&gt;
+ &lt;!-- Maximum color temperature, in Kelvin, supported by Night display. --&gt;
+ &lt;integer name="config_nightDisplayColorTemperatureMax"&gt;4082&lt;/integer&gt;
</pre>
<p>
The code is divided between framework, system services, SystemUI, and Settings:
@@ -93,6 +102,7 @@ platform/packages/apps/Settings
├ src/com/android/settings/Settings.java
├ src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
├ src/com/android/settings/display/NightDisplayPreference.java
+├ src/com/android/settings/display/NightDisplayPreferenceController.java
└ src/com/android/settings/display/NightDisplaySettings.java
</pre>
@@ -103,7 +113,9 @@ it. There is a full implementation of the settings in the Android Open Source
Project (AOSP)
<a href="https://android.googlesource.com/platform/packages/apps/Settings/">packages/apps/Settings</a>
project that device manufacturers can reference for their Settings
-implementation.
+implementation. Implementers must handle the
+<code><a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_NIGHT_DISPLAY_SETTINGS">Settings.ACTION_NIGHT_DISPLAY_SETTINGS</a></code>
+intent to expose this setting.
</p>
<h3 id="settings">Settings</h3>
<p>
@@ -130,6 +142,10 @@ and turn it on or off.
at 10:30 p.m.), Night Light will still turn off at 6:30 a.m. And if Night
Light is toggled off at 5:30 a.m. (before it turns off at 6:30 a.m.), it will
still turn on at 10:30 p.m.</li>
+ <li><strong>Intensity</strong>:
+ <a href="https://developer.android.com/reference/android/widget/SeekBar.html">Seekbar</a>
+ that controls the tint level by sliding from warm to cool. The seekbar can be
+ disabled when Night Light is not activated.</li>
<li><strong>Informational text</strong>: Teaches the user what Night Light does
and why.</li>
</ul>
diff --git a/en/devices/tech/display/pip.html b/en/devices/tech/display/pip.html
new file mode 100644
index 00000000..b86306da
--- /dev/null
+++ b/en/devices/tech/display/pip.html
@@ -0,0 +1,181 @@
+<html devsite>
+ <head>
+ <title>Picture-in-picture</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 8.0 includes support for picture-in-picture (PIP) for Android handheld
+devices. PIP allows users to resize an app with an ongoing activity into a small
+window. PIP is especially useful for video apps because content continues to
+play while the user is free to perform other actions. Users can manipulate this
+window's position through the SystemUI and interact with the application currently
+in picture-in-picture with (up to three) app-provided actions.
+</p>
+<p>
+More information is available in the Android Developer
+<a href="https://developer.android.com/training/tv/playback/picture-in-picture.html">Picture-in-picture</a>
+documentation.
+</p>
+
+<h2 id="overview">Overview</h2>
+<p>
+PIP requires explicit opt-in from applications that support it and works on a
+per-activity basis. (A single application can have multiple activities, only one
+of which is in PIP.) Activities request to enter picture-in-picture by calling
+<code>enterPictureInPictureMode()</code>, and receive activity callbacks in the
+form of <code>onPictureInPictureModeChanged()</code>.
+</p>
+<p>
+Android 8.0 added additional methods, including
+<code>setPictureInPictureParams()</code>, which lets activities control their
+aspect ratio while in PIP and custom actions, which allow users to interact with
+the activity without having to expand it. In PIP, the activity is in a paused,
+but rendering, state and does not directly receive touch input or window focus.
+Only a single task can be in PIP at a time.
+</p>
+<h2 id="device-requirements">Device requirements</h2>
+<p>
+To support PIP, enable the
+<code>PackageManager#FEATURE_PICTURE_IN_PICTURE</code> system feature in
+<code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/content/pm/PackageManager.java">/android/frameworks/base/core/java/android/content/pm/PackageManager.java</a></code>.
+Devices that support PIP must have a screen that is larger than 220dp at its
+smallest width. Similar to split screen multi-window, PIP allows multiple
+activities to run on-screen at the same time. Therefore, devices should have
+sufficient CPU and RAM to support this use case.
+</p>
+<h2 id="implementation">Implementation</h2>
+<p>
+Most of the activity lifecycle management is done in system between
+<code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/am/">ActivityManager</a></code>
+and <code><a
+href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/">WindowManager</a></code>.
+The reference UI implementation is in the <code><a
+href="https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/">SystemUI</a></code>
+package.
+</p>
+
+<p>
+Modifications to the system should not affect its intrinsic behavior as defined
+by the <a href="#cts-tests">Compatibility Test Suite (CTS) tests</a>.
+The system logic for PIP mainly revolves around the management of tasks and
+activities within the "pinned" stack. Here is a quick class overview:
+</p>
+<ul>
+ <li><strong><code>ActivityRecord</code></strong>: tracks each activity's
+ picture-in-picture state. To prevent users from entering PIP in certain
+ circumstances, such as from the lock screen or during VR, add cases to
+ <code>checkEnterPictureInPictureState()</code>.</li>
+ <li><strong><code>ActivityManagerService</code></strong>: the primary interface
+ from the activity to request entering PIP and the interface to calls from
+ <code>WindowManager</code> and <code>SystemUI</code> to change the PIP activity
+ state.</li>
+ <li><strong><code>ActivityStackSupervisor</code></strong>: called from the
+ <code>ActivityManagerService</code> to move tasks in or out of the pinned stack,
+ updating the <code>WindowManager</code> as necessary.</li>
+ <li><strong><code>PinnedStackWindowController</code></strong>: the
+ <code>WindowManager</code> interface from <code>ActivityManager</code>.</li>
+ <li><strong><code>PinnedStackController</code></strong>: reports changes in the
+ system to <code>SystemUI</code>, such as IME shown/hidden, aspect ratio changed,
+ or actions changed.</li>
+ <li><strong><code>BoundsAnimationController</code></strong>: animates the PIP
+ activity windows in a way that does not trigger a configuration change while
+ resizing.</li>
+ <li><strong><code>PipSnapAlgorithm</code></strong>: a shared class used in both
+ the system and SystemUI that controls the snapping behaviour of the PIP window
+ near the edges of the screen.</li>
+</ul>
+
+<p>
+The reference <code><a
+href="https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/">SystemUI</a></code>
+provides a complete implementation of PIP that supports presenting custom
+actions to users and general manipulation, such as expansion and dismissal.
+Device manufacturers can build upon these changes, as long as they do not affect
+the intrinsic behaviours as defined by the CDD. Here is a quick class
+overview:</p>
+<ul>
+ <li><strong><code>PipManager</code></strong>: the <code>SystemUI</code>
+ component that is started with <code>SystemUI</code>.</li>
+ <li><strong><code>PipTouchHandler</code></strong>: the touch handler, which
+ controls the gestures that manipulate the PIP. This is only used while the input
+ consumer for the PIP is active (see <code>InputConsumerController</code>). New
+ gestures can be added here.</li>
+ <li><strong><code>PipMotionHelper</code></strong>: a convenience class that
+ tracks the PIP position, and allowable region on-screen. Calls through to
+ <code>ActivityManagerService</code> to update or animate the position and size
+ of the PIP.</li>
+ <li><strong><code>PipMenuActivityController</code></strong>: starts an activity
+ that shows the actions provided by the activity currently in PIP. This activity
+ is a task-overlay activity, and removes the overlaying input consumer to allow
+ it to be interactive.</li>
+ <li><strong><code>PipMenuActivity</code></strong>: the implementation for the
+ menu activity.</li>
+ <li><strong><code>PipMediaController</code></strong>: the listener that updates
+ <code>SystemUI</code> when the media session changes in a way that might affect
+ the default actions on the PIP.</li>
+ <li><strong><code>PipNotificationController</code></strong>: the controller that
+ ensures that a notification is active while a user is using the PIP feature.</li>
+ <li><strong><code>PipDismissViewController</code></strong>: the overlay shown to
+ users when they start interacting with the PIP to indicate that it can be
+ dismissed.</li>
+</ul>
+<h2 id="default-placement">Default placement</h2>
+<p>
+There are various system resources that control the default placement of the
+PIP:
+</p>
+<ul>
+ <li><strong><code>config_defaultPictureInPictureGravity</code></strong>: the <a
+ href="https://developer.android.com/reference/android/view/Gravity.html">gravity</a>
+ integer, which controls the corner to place the PIP, such as
+ <code>BOTTOM|RIGHT</code>.</li>
+ <li><strong><code>config_defaultPictureInPictureScreenEdgeInsets</code></strong>:
+ the offsets from the sides of the screen to place the PIP.</li>
+ <li><strong><code>config_pictureInPictureDefaultSizePercent</code></strong> and
+ <strong><code>config_pictureInPictureDefaultAspectRatio</code></strong>: the
+ combination of percentage of the screen width and the aspect ratio controls the
+ size of the PIP. The computed default PIP size should not be smaller than
+ <code>@dimen/default_minimal_size_pip_resizable_task</code>, as defined by CTS
+ and the CDD.</li>
+ <li><strong><code>config_pictureInPictureSnapMode</code></strong>: the snapping
+ behaviour as defined in <code>PipSnapAlgorithm</code>.</li>
+</ul>
+<p>
+Device implementations should not change the minimum and maximum aspect ratios
+that are defined in the CDD and CTS.
+</p>
+<h2 id="permissions">Permissions</h2>
+<p>
+Android 8.0 added a per-package "application operation"
+(<code>OP_PICTURE_IN_PICTURE</code>) to <code>AppOpsManager</code>
+(<code>master/core/java/android/app/AppOpsManager.java)</code>, which allows
+users to control PIP on a per-application level through the system settings.
+Device implementations need to respect this check when an activity requests to
+enter picture-in-picture mode.
+</p>
+<h2 id="cts-tests">Testing</h2>
+<p>
+To test PIP implementations, run all picture-in-picture related tests found in
+the host-side CTS tests under <code><a
+href="https://android.googlesource.com/platform/cts/+/master/hostsidetests/services/activitymanager/src/android/server/cts">/cts/hostsidetests/services/activitymanager</a></code>,
+particularly in <code>ActivityManagerPinnedStackTests.java</code>.
+</p>
+</body>
+</html>
diff --git a/en/devices/tech/display/split-screen.html b/en/devices/tech/display/split-screen.html
new file mode 100644
index 00000000..3aa2c126
--- /dev/null
+++ b/en/devices/tech/display/split-screen.html
@@ -0,0 +1,108 @@
+<html devsite>
+ <head>
+ <title>Split-Screen Interactions</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>
+In Android 7.0 and later, users can have multiple apps simultaneously displayed
+on their device screen with the platform feature <a
+href="/devices/tech/display/multi-window">multi-window</a>.
+The default mode is split-screen, which provides two activity panes for users to
+place apps.
+</p>
+<p>
+Android 8.0 improves split-screen by refining the feature and adding more
+functionality to it. In the default implementation, if a user taps
+<strong>Home</strong> after entering split-screen, the top pane compresses and
+the launcher resizes. This shows users that the top app is still open while
+maintaining their launcher layout so they can find and launch apps from their
+home screen.
+</p>
+<h2 id="examples-and-source">Examples and source</h2>
+<p>
+There is a reference implementation of this new functionality in the Launcher3
+code in <code>/platform/packages/apps/Launcher3/</code>
+</p>
+<p>
+These Change IDs are related to implementing split-screen in Launcher3, and can
+act as a reference for device manufacturers who want to make similar updates to
+their launchers.
+</p>
+<ul>
+ <li>Change-Id: <code>I48e5cb3bd15e70627d9bf007d93bc731612fba2e</code></li>
+ <li>Change-Id: <code>I86753bab5b24aafc417e0f77d8c471fc4c0dc7f0</code></li>
+ <li>Change-Id: <code>Id6557d070edb664aa1f4851de7abf494cf8a0677</code></li>
+ <li>Change-Id: <code>Icdaf73ecd89a30e57fe7f405292d793f2d6a3ee8</code></li>
+ <li>Change-Id: <code>Ie50279f4edb94812120dea492aefa4f18218162f</code></li>
+ <li>Change-Id: <code>I6f9ee7be12d3266f021796576c771f86f6120246</code></li>
+ <li>Change-Id: <code>I106fe12041565a090047f146a07d4bc80a074b4a</code></li>
+ <li>Change-Id: <code>Ibb49c56aab29d1223a0ab36476a32d565566eb25</code></li>
+ <li>Change-Id: <code>Id60c793730d982277c9d91860e9fb0e6a0df7d38</code></li>
+ <li>Change-Id: <code>I9d358e74ab403989929dee87542d3dde78c2f229</code></li>
+ <li>Change-Id: <code>I925d5ac9d29439c5d61cf089e7784065a8cb5ebd</code></li>
+ <li>Change-Id: <code>I776c6f710e081645cff891487022cf787869ee3f</code></li>
+ <li>Change-Id: <code>I2d17c89db2eb8d60b3393c2abc3b026e5574085d</code></li>
+ <li>Change-Id: <code>Id6ee68826c4f3cc579880540812fd8ed834f8267</code></li>
+</ul>
+<h2 id="example-ux">Example UX</h2>
+<p>
+Here are example screens that show the user experience for the default
+implementation of this feature.
+</p>
+<p><img src="/devices/tech/display/images/split-screen-example-ux.png"
+ alt="Example screens for launcher resizing behavior" />
+</p>
+<p class="img-caption"><strong>Figure 1</strong>. Example screens for launcher
+ resizing in split-screen mode.
+</p>
+<h2 id="implementation">Implementation</h2>
+<p>
+While Android 8.0 provides a reference implementation for this update to
+split-screen, it's up to device manufacturers to determine their implementations
+in their launchers. To support this feature:
+</p>
+<ul>
+ <li>Implement (or have an existing implementation of) multi-window that follows
+ the Android Compatibility Definition Document (CDD) <a
+ href="/compatibility/android-cdd#3814-multi-windows">requirements
+ for multi-window</a>.</li>
+ <li>Make the launcher resizable. The reference implementation in Launcher3
+ removes app names as the screen gets smaller, but implementations may vary
+ depending on how the launcher compresses, especially if there is custom launcher
+ code.</li>
+ <li>Set the minimum specified height in the launcher manifest. To do this,
+ adjust <code>task_height_of_minimized_mode</code> value in:
+ <code>frameworks/base/core/res/res/values/dimens.xml</code></li>
+</ul>
+<h2 id="testing">Testing</h2>
+<p>
+Use manual testing to ensure your implementation is working correctly.
+</p>
+<ol>
+ <li>Enter split-screen.</li>
+ <li>Press <strong>Home</strong>.</li>
+ <li>Observe resizable launcher.</li>
+</ol>
+<p>
+Ensure that the launcher resizes correctly in all device orientations that it
+supports.
+</p>
+</body>
+</html>
diff --git a/en/devices/tech/display/widgets-shortcuts.html b/en/devices/tech/display/widgets-shortcuts.html
new file mode 100644
index 00000000..17af11ac
--- /dev/null
+++ b/en/devices/tech/display/widgets-shortcuts.html
@@ -0,0 +1,90 @@
+<html devsite>
+ <head>
+ <title>Widgets/Shortcuts</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>
+ The new flow API for adding shortcuts and widgets in Android 8.0 allows
+ application developers to add shortcuts and widgets from inside the app instead
+ of relying on the widget tray. It also deprecates the old method (sending a
+ broadcast) of adding shortcuts for security reasons.
+ </p>
+ <p>
+ Launchers need to support this new implementation so that app developers can
+ rely on the system to add their shortcut or widget.
+ </p>
+ <h2 id="examples-and-source">Examples and source</h2>
+ <p>
+ Docs are available in various system class. References include the following:
+ </p>
+ <ul>
+ <li><b><a
+ href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html">ShortuctManager.java</a></b><br>
+ Publish Pinned shortcut section in header.
+ <li><b>Intent.java</b><br>Javadoc for ACTION_CREATE_SHORTCUT.</li>
+ <li><b>AppWidgetManager.java</b><br>Javadoc for requestPinAppWidget.</li>
+ </ul>
+ <h2 id="implementation">Implementation</h2>
+ <p>
+ Device implementers need to add an activity in their launcher with intent filter actions:
+ </p>
+ <ul>
+ <li><code>android.content.pm.action.CONFIRM_PIN_SHORTCUT</code></li>
+ <li><code>android.content.pm.action.CONFIRM_PIN_APPWIDGET</code></li>
+ </ul>
+ <p>
+ Refer to the <a
+ href="https://developer.android.com/reference/android/content/pm/LauncherApps.html">API
+ documentation</a> for more details.
+ </p>
+ <p>
+ This activity should display a confirmation prompt to the user to add the <a
+ href="https://developer.android.com/reference/android/content/pm/LauncherApps.html">requested
+ widget/shortcut</a> and upon accepting, add the corresponding widget/shortcut on
+ the homescreen.
+ </p>
+ <p>
+ In case of widgets, the <code>accept()</code> call should include the widget ID
+ of the newly added widget.
+ </p>
+ <h3 id="implementing-a-system-ui">Implementing a System UI</h3>
+ <p>
+ Partners need to update their Launcher app using the Launcher3 implementation
+ (<code>packages/apps/Launcher3</code>) as reference.
+ </p>
+ <p>
+ Relevant Launcher3 changes:
+ </p>
+ <ul>
+ <li>Change-Id: I664366822fe8088742faff2cce006239ab0771bc
+ <li>Change-Id: I905532ba44a8898c9c17476f9f75bc309eeb7b41
+ </ul>
+ <h2 id="validation">Validation</h2>
+ <p>
+ To validate the feature, try to add shortcuts from Chrome or the Contacts app
+ and verify that a proper confirmation prompt is shown. Upon accepting, the icon
+ should get added on the homescreen and Chrome should display a success toast.
+ </p>
+ </body>
+</html>
+
+
diff --git a/en/devices/tech/images/treble_latency_bubble.png b/en/devices/tech/images/treble_latency_bubble.png
new file mode 100644
index 00000000..72a83c05
--- /dev/null
+++ b/en/devices/tech/images/treble_latency_bubble.png
Binary files differ
diff --git a/en/devices/tech/images/treble_priority_inv_rta.png b/en/devices/tech/images/treble_priority_inv_rta.png
new file mode 100644
index 00000000..5ece38be
--- /dev/null
+++ b/en/devices/tech/images/treble_priority_inv_rta.png
Binary files differ
diff --git a/en/devices/tech/images/treble_priority_inv_rta_blocked.png b/en/devices/tech/images/treble_priority_inv_rta_blocked.png
new file mode 100644
index 00000000..fe218529
--- /dev/null
+++ b/en/devices/tech/images/treble_priority_inv_rta_blocked.png
Binary files differ
diff --git a/en/devices/tech/images/treble_systrace_binder_processes.png b/en/devices/tech/images/treble_systrace_binder_processes.png
new file mode 100644
index 00000000..425dcd07
--- /dev/null
+++ b/en/devices/tech/images/treble_systrace_binder_processes.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_dash_arch.png b/en/devices/tech/images/treble_vts_dash_arch.png
new file mode 100644
index 00000000..2ecbc395
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_dash_arch.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_dash_entity_ancestry.png b/en/devices/tech/images/treble_vts_dash_entity_ancestry.png
new file mode 100644
index 00000000..8fb5730f
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_dash_entity_ancestry.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_descend.png b/en/devices/tech/images/treble_vts_descend.png
new file mode 100644
index 00000000..7b5bf808
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_descend.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_descend_not.png b/en/devices/tech/images/treble_vts_descend_not.png
new file mode 100644
index 00000000..30a7f977
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_descend_not.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_coverage.png b/en/devices/tech/images/treble_vts_ui_coverage.png
new file mode 100644
index 00000000..480006e3
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_coverage.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_coverage_source.png b/en/devices/tech/images/treble_vts_ui_coverage_source.png
new file mode 100644
index 00000000..056e3402
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_coverage_source.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_favorites.png b/en/devices/tech/images/treble_vts_ui_favorites.png
new file mode 100644
index 00000000..800a886a
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_favorites.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_histogram.png b/en/devices/tech/images/treble_vts_ui_histogram.png
new file mode 100644
index 00000000..9af74601
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_histogram.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_main.png b/en/devices/tech/images/treble_vts_ui_main.png
new file mode 100644
index 00000000..3d3e77c2
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_main.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_performance.png b/en/devices/tech/images/treble_vts_ui_performance.png
new file mode 100644
index 00000000..a330e068
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_performance.png
Binary files differ
diff --git a/en/devices/tech/images/treble_vts_ui_results.png b/en/devices/tech/images/treble_vts_ui_results.png
new file mode 100644
index 00000000..042ace1f
--- /dev/null
+++ b/en/devices/tech/images/treble_vts_ui_results.png
Binary files differ
diff --git a/en/devices/tech/index.html b/en/devices/tech/index.html
index 45567c7e..aafb7e0b 100644
--- a/en/devices/tech/index.html
+++ b/en/devices/tech/index.html
@@ -83,12 +83,6 @@ dynamic range (HDR) video, night light, and retail demo mode.</p>
<p><a href="/devices/tech/display/index.html">&raquo; Display settings
information</a></p>
-<h2 id="HAL-technical-information">HAL File Reference</h2>
-<p>Android's Hardware Abstraction Layer (HAL) provides the interface between
-software APIs and hardware drivers. This section contains the commented code
-files of the HAL.</p>
-<p><a href="/reference/hal/">&raquo; HAL Reference</a></p>
-
<h2 id="ota-technical-information">OTA Updates</h2>
<p>Android devices in the field can receive and install over-the-air (OTA)
updates to the system and application software. This section describes the
@@ -97,6 +91,13 @@ developers building OTA updates for new and released Android devices.</p>
<p><a href="/devices/tech/ota/index.html">&raquo; OTA Information</a>
</p>
+<h2 id="performance">Performance</h2>
+<p>This section provides guidance for ensuring your Android devices minimize
+resource use and optimize performance. It includes details on optimizing boot
+times, managing flash wear, configuring for low ram devices, and more.</p>
+<p><a href="/devices/tech/perf/index.html">&raquo; Performance Information</a>
+</p>
+
<h2 id="power-technical-information">Power</h2>
<p>The framework provides battery usage statistics, keeping track of time spent
by different device components in different states. This section covers power
@@ -106,6 +107,14 @@ device and component power (and how to determine power values), and details the
<p><a href="/devices/tech/power/index.html">&raquo; Power
Information</a></p>
+<h2 id="settings">Settings</h2>
+<p>This section provides guidance on implementing features in Android Settings
+menu. It includes details on the patterns, components, and architecture of the
+Settings app, how to customize personalized settings, and how to add a setting
+to universal search.</p>
+<p><a href="/devices/tech/settings/index.html">&raquo; Settings Information</a>
+</p>
+
<h2 id="tradefed-test-infrastructure">Trade Federation Testing Infrastructure
</h2>
<p>Trade Federation is a continuous test framework for running tests on
@@ -115,5 +124,14 @@ infrastructures.</p>
<p><a href="/devices/tech/test_infra/tradefed/index.html">
&raquo; Trade Federation Testing Infrastructure Overview</a></p>
+
+<h2 id="vts">Vendor Test Suite (VTS)</h2>
+<p>The Android Vendor Test Suite (VTS) provides extensive new functionality for
+Android testing and promotes a test-driven development process. This section
+describes the testing tools and resources available to help the Android
+development community interact with test data.</p>
+<p><a href="/devices/tech/vts/index.html">&raquo; VTS Information</a>
+</p>
+
</body>
</html>
diff --git a/en/devices/tech/ota/inside_packages.html b/en/devices/tech/ota/inside_packages.html
index 5bf7c6ab..2cb23c00 100644
--- a/en/devices/tech/ota/inside_packages.html
+++ b/en/devices/tech/ota/inside_packages.html
@@ -140,12 +140,6 @@ applying binary patches.</dd>
syntactic sugar for this function in the special case of two arguments (but
the function form can take any number of expressions). The expressions must be
strings; it can't concatenate blobs.</dd>
-<dt><code>delete([<i>filename</i>, ...])</code></dt>
-<dd>Deletes all the <i>filename</i>s listed. Returns the number of files
-successfully deleted.</dd>
-<dt><code>delete_recursive([<i>dirname</i>, ...])</code></dt>
-<dd>Recursively deletes <i>dirname</i>s and all their contents. Returns the
-number of directories successfully deleted.</dd>
<dt><code>file_getprop(<i>filename</i>, <i>key</i>)</code></dt>
<dd>Reads the given <i>filename</i>, interprets it as a properties file (e.g.
<code>/system/build.prop</code>), and returns the value of the given <i>key</i>
@@ -215,25 +209,9 @@ it to <i>dest_file</i>, overwriting existing files if necessary. Without the
binary blob.</dd>
<dt><code>read_file(<i>filename</i>)</code></dt>
<dd>Reads <i>filename</i> and returns its contents as a binary blob.</dd>
-<dt><code>rename(<i>src_filename</i>, <i>tgt_filename</i>)</code></dt>
-<dd>Renames <i>src_filename</i> to <i>tgt_filename</i>. It automatically creates
-the necessary directories for the <i>tgt_filename</i>. Example: <code>
-rename("system/app/Hangouts/Hangouts.apk",
-"system/priv-app/Hangouts/Hangouts.apk")</code>.</dd>
<dt><code>run_program(<i>path</i>[, <i>arg</i>, ...])</code></dt>
<dd>Executes the binary at <i>path</i>, passing <i>arg</i>s. Returns the
program's exit status.</dd>
-<dt><code>set_metadata(<i>filename</i>, <i>key1</i>, <i>value1</i>[, <i>key2
-</i>, <i>value2</i>, ...])</code></dt>
-<dd>Sets the keys of the given <i>filename</i> to <i>values</i>. For example:
-<code>set_metadata("/system/bin/netcfg", "uid", 0, "gid", 3003, "mode", 02750,
-"selabel", "u:object_r:system_file:s0", "capabilities", 0x0)</code>.</dd>
-<dt><code>set_metadata_recursive(<i>dirname</i>, <i>key1</i>, <i>value1</i>[,
-<i>key2</i>, <i>value2</i>, ...])</code></dt>
-<dd>Recursively sets the keys of the given <i>dirname</i> and all its children
-to <i>values</i>. For example: <code>set_metadata_recursive("/system", "uid",
-0, "gid", 0, "fmode", 0644, "dmode", 0755, "selabel",
-"u:object_r:system_file:s0", "capabilities", 0x0)</code>.</dd>
<dt><code>set_progress(<i>frac</i>)</code></dt>
<dd>Sets the position of the progress meter within the chunk defined by the
most recent <code>show_progress()</code> call. <i>frac</i> must be in the
@@ -256,8 +234,6 @@ set_progress()</code> function defined above.</dd>
<dt><code>stdout(<i>expr</i>[, <i>expr</i>, ...])</code></dt>
<dd>Evaluates each expression and dumps its value to stdout. Useful for
debugging.</dd>
-<dt><code>symlink(<i>target</i>[, <i>source</i>, ...])</code></dt>
-<dd>Creates all <i>source</i>s as symlinks to <i>target</i>.</dd>
<dt><code>tune2fs(<i>device</i>[, <i>arg</i>, …])</code></dt>
<dd>Adjusts tunable parameters <i>args</i> on <i>device</i>.</dd>
<dt><code>ui_print([<i>text</i>, ...])</code></dt>
diff --git a/en/devices/tech/perf/boot-times.html b/en/devices/tech/perf/boot-times.html
new file mode 100644
index 00000000..4712cce0
--- /dev/null
+++ b/en/devices/tech/perf/boot-times.html
@@ -0,0 +1,635 @@
+<html devsite>
+ <head>
+ <title>Optimizing Boot Times</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>
+This document provides partner guidance for improving boot times for specific
+Android devices. Boot time is an important component of system performance as
+users must wait for boot to complete before they can use the device. For devices
+such as cars where cold boot-up happens more frequently, having a quick boot
+time is critical (no one likes waiting for dozens of seconds just to input a
+navigation destination).
+</p>
+
+<p>
+Android 8.0 allows for reduced boot times by supporting several improvements
+across a range of components. The following table summarizes these performance
+improvements (as measured on a Google Pixel and Pixel XL devices).
+</p>
+
+<table>
+ <tr>
+ <th>Component</th>
+ <th>Improvement</th>
+ </tr>
+ <tr>
+ <td>Bootloader
+ </td>
+ <td>
+ <ul>
+ <li>Saved 1.6s by removing UART log
+ <li>Saved 0.4s by changing to LZ4 from GZIP</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>Device kernel
+ </td>
+ <td>
+ <ul>
+ <li>Saved 0.3s by removing unused kernel configs and reducing driver size
+ <li>Saved 0.3s with dm-verity prefetch optimization
+ <li>Saved 0.15s to remove unnecessary wait/test in driver
+ <li>Saved 0.12s to remove CONFIG_CC_OPTIMIZE_FOR_SIZE</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>I/O tuning
+ </td>
+ <td>
+ <ul>
+ <li>Saved 2s on normal boot
+ <li>Saved 25s on first boot</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>init.*.rc
+ </td>
+ <td>
+ <ul>
+ <li>Saved 1.5s by paralleling init commands
+ <li>Saved 0.25s by starting zygote early
+ <li>Saved 0.22s by cpuset tune</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>Boot animation
+ </td>
+ <td>
+ <ul>
+ <li>Started 2s earlier on boot without fsck triggered, much bigger on boot with
+fsck triggered boot
+ <li>Saved 5s on Pixel XL with immediate shutdown of boot animation</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>SELinux policy
+ </td>
+ <td>Saved 0.2s on by genfscon
+ </td>
+ </tr>
+</table>
+
+<h2 id="optimizing-bootloader">Optimizing Bootloader</h2>
+
+<p>
+To optimize bootloader for improved boot times:
+</p>
+<ul>
+<li>For logging:
+ <ul>
+ <li>Disable log writing to UART as it can take a long time with lots of
+ logging. (On the Google Pixel devices, we found it slows the bootloader 1.5s).</li>
+ <li>Log only error situations and consider storing other information to memory
+ with a separate mechanism to retrieve.</li>
+ </ul>
+</li>
+<li>For kernel decompression, considering using LZ4 for contemporary hardware
+ instead of GZIP (example <a class="external"
+ href="https://patchwork.kernel.org/patch/6810841/">patch</a>). Keep in mind that
+ different kernel compression options can have different loading and
+ decompression times, and some options may work better than others for your
+ specific hardware.</li>
+<li>Check unnecessary wait times for debouncing/special mode entry and minimize
+ them.</li>
+<li>Pass boot time spent in bootloader to kernel as cmdline.</li>
+<li>Check CPU clock and consider parallelization (requires multi-core support)
+ for kernel loading and initializing I/O.</li>
+</ul>
+
+<h2 id="optimizing-kernel">Optimizing Kernel</h2>
+
+<p>
+Use the following tips to optimize the kernel for improved boot times.
+</p>
+
+<h3 id="minimizing-device-defconfig">Minimizing device defconfig</h3>
+
+<p>
+Minimizing kernel config can reduce kernel size for faster loading
+decompression, initialization and smaller attack surfaces. To optimize the
+device defconfig:
+</p>
+
+<ul>
+<li><strong>Identify unused drivers</strong>. Review the <code>/dev</code> and
+<code>/sys</code> directories and look for nodes with general SELinux labels
+(which indicates those nodes are not configured to be accessible by user space).
+Remove any such nodes if found.
+<li><strong>Unset unused CONFIGs</strong>. Review the .config file generated by
+kernel build to explicitly unset any unused CONFIG that was turned on by
+default. For example, we removed the following unused CONFIGs from the Google
+Pixel:
+
+<pre
+class="prettyprint">
+CONFIG_ANDROID_LOGGER=y
+CONFIG_IMX134=y
+CONFIG_IMX132=y
+CONFIG_OV9724=y
+CONFIG_OV5648=y
+CONFIG_GC0339=y
+CONFIG_OV8825=y
+CONFIG_OV8865=y
+CONFIG_s5k4e1=y
+CONFIG_OV12830=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y
+CONFIG_IKCONFIG=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_TI_DRV2667=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_MMC_CQ_HCI=y
+CONFIG_MSDOS_FS=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_EEPROM_AT24=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_HBTP_INPUT=y
+# CONFIG_VGA_ARB is not set
+CONFIG_USB_MON=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_SW_SYNC_USER=y
+CONFIG_SEEMP_CORE=y
+CONFIG_MSM_SMEM_LOGGING=y
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_DEBUG_TRACKING=y
+CONFIG_IOMMU_TESTS=y
+CONFIG_MOBICORE_DRIVER=y
+# CONFIG_DEBUG_PREEMPT is not set
+</pre>
+</li>
+</ul>
+
+<ul>
+<li><strong>Remove CONFIGs that lead to unnecessary test runs on every
+boot</strong>. While useful in development, such configs (i.e.
+CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST) should be removed in a production
+kernel.
+</li>
+</ul>
+
+<h3 id="minimizing-driver-size">Minimizing driver size</h3>
+
+<p>
+Some drivers in the device kernel can be removed if the function is not used to
+reduce kernel size further. For example, if WLAN is connected through PCIe, the
+SDIO support is not used and should be removed during compile time. For details,
+refer to the Google Pixel kernel: net: wireless: cnss: add option to disable
+SDIO support.
+
+</p>
+
+<h3 id="removing-compiler-optimization-for-size">Removing compiler optimization
+for size</h3>
+
+<p>
+Remove the kernel config for CONFIG_CC_OPTIMIZE_FOR_SIZE. This flag was
+originally introduced when the assumption was that smaller code size would yield
+hot cache hit (and thus be faster). However, this assumption is no longer valid
+as modern mobile SoCs have become more powerful.
+</p>
+
+<p>
+In addition, removing the flag can enable the compiler warning for uninitialized
+variables, which is suppressed in Linux kernels when the
+CONFIG_CC_OPTIMIZE_FOR_SIZE flag is present (making this change alone has helped
+us uncover many meaningful bugs in some Android device drivers).
+</p>
+
+<h3 id="deferring-initialization">Deferring initialization</h3>
+
+<p>
+Many processes launch during boot, but only components in critical path
+(bootloader > kernel > init > file system mount > zygote > system server)
+directly affect boot time. Use the early kernel log to identify
+peripheral/components that are not critical to the start init process, then
+delay those peripherals/components until later in the boot process.
+</p>
+
+<h2 id="optimizing-i-o-efficiency">Optimizing I/O efficiency</h2>
+
+<p>
+Improving I/O efficiency is critical to making boot time faster, and reading
+anything not necessary should be deferred until after boot (on a Google Pixel,
+about 1.2GB of data is read on boot).
+</p>
+
+<h3 id="tuning-the-filesystem">Tuning the filesystem</h3>
+
+<p>
+The Linux kernel read ahead kicks in when a file is read from beginning or when
+blocks are read sequentially, making it necessary to tune I/O scheduler
+parameters specifically for booting (which has a different workload
+characterization than normal applications).
+</p>
+
+<p>
+Devices that support seamless (A/B) updates benefit greatly from filesystem
+tuning on first time boot (e.g. 20s on Google Pixel). An an example, we tuned
+the following parameters for the Google Pixel:
+</p>
+
+<pre
+class="prettyprint">
+on late-fs
+ # boot time fs tune
+ # boot time fs tune
+ write /sys/block/sda/queue/iostats 0
+ write /sys/block/sda/queue/scheduler cfq
+ write /sys/block/sda/queue/iosched/slice_idle 0
+ write /sys/block/sda/queue/read_ahead_kb 2048
+ write /sys/block/sda/queue/nr_requests 256
+ write /sys/block/dm-0/queue/read_ahead_kb 2048
+ write /sys/block/dm-1/queue/read_ahead_kb 2048
+
+on property:sys.boot_completed=1
+ # end boot time fs tune
+ write /sys/block/sda/queue/read_ahead_kb 512
+ ...
+</pre>
+
+<h3 id="miscellaneous">Miscellaneous</h3>
+
+<ul>
+<li>Turn on the dm-verity hash prefetch size using kernel config
+DM_VERITY_HASH_PREFETCH_MIN_SIZE (default size is 128).
+<li>For better file system stability and a dropped forced check that occurs on
+every boot, use the new ext4 generation tool by setting TARGET_USES_MKE2FS in
+BoardConfig.mk.</li>
+</ul>
+
+<h3 id="analyzing-i-o">Analyzing I/O</h3>
+
+<p>
+To understand I/O activities during boot, use kernel ftrace data (also used by
+systrace):
+</p>
+
+<pre
+class="prettyprint">trace_event=block,ext4 in BOARD_KERNEL_CMDLINE</pre>
+<p>
+To breakdown file access for each file, make the following changes to the kernel
+(development kernel only; do not use in production kernels):
+</p>
+
+<pre
+class="prettyprint">
+diff --git a/fs/open.c b/fs/open.c
+index 1651f35..a808093 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -981,6 +981,25 @@
+ }
+ EXPORT_SYMBOL(file_open_root);
+
++static void _trace_do_sys_open(struct file *filp, int flags, int mode, long fd)
++{
++ char *buf;
++ char *fname;
++
++ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
++ if (!buf)
++ return;
++ fname = d_path(&filp-&lt;f_path, buf, PAGE_SIZE);
++
++ if (IS_ERR(fname))
++ goto out;
++
++ trace_printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n",
++ current-&lt;comm, fname, flags, mode, fd, filp-&lt;f_inode-&lt;i_ino);
++out:
++ kfree(buf);
++}
++
+long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
+ {
+ struct open_flags op;
+@@ -1003,6 +1022,7 @@
+ } else {
+ fsnotify_open(f);
+ fd_install(fd, f);
++ _trace_do_sys_open(f, flags, mode, fd);
+</pre>
+
+<p>
+Use the following scripts to help with analyzing boot performance.
+</p>
+<ul>
+<li><code>packages/services/Car/tools/bootanalyze/bootanalyze.py</code>
+Measures boot time with a breakdown of important steps in the boot process.
+<li><code>packages/services/Car/tools/io_analysis/check_file_read.py
+boot_trace</code> Provides access information per each file.
+<li><code>packages/services/Car/tools/io_analysis/check_io_trace_all.py
+boot_trace</code> Gives system-level breakdown.</li>
+</ul>
+
+<h2 id="optimizing-init-*-rc">Optimizing init.*.rc</h2>
+
+<p>
+Init is the bridge from the kernel till the framework is established, and
+devices usually spend a few seconds in different init stages.
+</p>
+
+<h3 id="running-tasks-in-parallel">Running tasks in parallel</h3>
+
+<p>
+While the current Android init is more or less a single threaded process, you
+can still perform some tasks in parallel.
+</p>
+
+<ul>
+<li>Execute slow commands in a shell script service and join that later by
+waiting for specific property. Android 8.0 supports this use case with a new
+<code>wait_for_property</code> command.
+<li>Identify slow operations in init. The system logs the init command
+exec/wait_for_prop or any action taking a long time (in Android 8.0, any command
+taking more than 50 ms). For example:
+
+<pre
+class="prettyprint">init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms</pre>
+
+<p>
+Reviewing this log may indicate opportunities for improvements.
+</p>
+
+<li>Start services and enable peripheral devices in critical path early. For
+example, some SOCs require starting security-related services before starting
+SurfaceFlinger. Review the system log when ServiceManager returns "wait for
+service" — this is usually a sign that a dependent service must be started
+first.
+<li>Remove any unused services and commands in init.*.rc. Anything not used in
+early stage init should be deferred to boot completed.</li></ul>
+</li>
+</ul>
+
+<h3 id="using-scheduler-tuning">Using scheduler tuning</h3>
+
+<p>
+Use scheduler tuning for early boot. Example from a Google Pixel:
+</p>
+
+<pre
+class="prettyprint">on init
+ # update cpusets now that processors are up
+ write /dev/cpuset/top-app/cpus 0-3
+ write /dev/cpuset/foreground/cpus 0-3
+ write /dev/cpuset/foreground/boost/cpus 0-3
+ write /dev/cpuset/background/cpus 0-3
+ write /dev/cpuset/system-background/cpus 0-3
+ # set default schedTune value for foreground/top-app (only affects EAS)
+ write /dev/stune/foreground/schedtune.prefer_idle 1
+ write /dev/stune/top-app/schedtune.boost 10
+ write /dev/stune/top-app/schedtune.prefer_idle 1</pre>
+
+<p>
+Some services may need a priority boost during boot. Example:
+</p>
+
+<pre
+class="prettyprint">
+init.zygote64.rc:
+service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
+ class main
+ priority -20
+ user root
+...</pre>
+
+<h3 id="starting-zygote-early">Starting zygote early</h3>
+
+<p>
+Devices with file-based encryption can start zygote earlier at the zygote-start
+trigger (by default, zygote is launched at class main, which is much later than
+zygote-start). When doing this, make sure to allow zygote to run in all CPUs (as
+the wrong cpuset setting may force zygote to run in specific CPUs).
+</p>
+
+<h2 id="optimizing-boot-animation">Optimizing boot animation</h2>
+
+<p>
+Use the following tips to optimize the boot animation.
+</p>
+
+<h3 id="configuring-early-start">Configuring early start</h3>
+
+<p>
+Android 8.0 enables starting boot animation early, before mounting userdata
+partition. However, even when using the new ext4 tool chain in Android 8.0, fsck
+is still triggered periodically due to safety reasons, causing a delay in
+starting the bootanimation service.
+</p>
+
+<p>
+To make bootanimation start early, split the fstab mount into two phases:
+</p>
+
+<ul>
+ <li>In the early phase, mount only the partitions (such as
+ <code>system/</code> and <code>vendor/</code>) that don't require run
+ checks, then start boot animation services and its dependencies (such as
+ servicemanager and surfaceflinger).
+ <li>In the second phase, mount partitions (such as <code>data/</code>) that
+ do require run checks.</li>
+</ul>
+
+<p>
+Boot animation will be started much faster (and in constant time) regardless of
+fsck.
+</p>
+
+<h3 id="finishing-clean">Finishing clean</h3>
+
+<p>
+After receiving the exit signal, bootanimation plays the last part, the length
+of which can slow boot time. A system that boots quickly has no need for lengthy
+animations which could effectively hide any improvements made. We recommend
+making both the repeating loop and finale short.
+</p>
+
+<h2 id="optimizing-selinux">Optimizing SELinux</h2>
+
+<p>
+Use the following tips to optimize SELinux for improved boot times.
+</p>
+
+<ul>
+<li><strong>Use clean regular expressions (regex)</strong>. Poorly-formed regex
+can lead to a lot of overhead when matching SELinux policy for
+<code>sys/devices</code> in <code>file_contexts</code>. For example, the regex
+<code>/sys/devices/.*abc.*(/.*)?</code> mistakenly forces a scan of all
+<code>/sys/devices</code> subdirectories that contain "abc", enabling matches
+for both <code>/sys/devices/abc</code> and <code>/sys/devices/xyz/abc</code>.
+Improving this regex to <code>/sys/devices/[^/]*abc[^/]*(/.*)?</code> will
+enable a match only for <code>/sys/devices/abc</code>.
+<li><strong>Move labels to </strong><a
+href="https://selinuxproject.org/page/FileStatements#genfscon">genfscon</a>.
+This existing SELinux feature passes file-matching prefixes into the kernel in
+the SELinux binary, where the kernel applies them to kernel-generated
+filesystems. This also helps fix mislabeled kernel-created files, preventing
+race conditions that can occur between userspace processes attempting to access
+these files before relabeling occurs.</li>
+</ul>
+
+<h2 id="tool-and-methods">Tool and methods</h2>
+
+<p>
+Use the following tools to help you collect data for optimization targets.
+</p>
+
+<h3 id="bootchart">Bootchart</h3>
+
+<p>
+Bootchart provides CPU and I/O load breakdown of all processes for the whole
+system. It doesn't require rebuilding system image and can be used as a quick
+sanity check before diving into systrace.
+</p>
+
+<p>
+To enable bootchart:
+</p>
+
+<pre>
+<code class="devsite-terminal">adb shell 'touch /data/bootchart/enabled'</code>
+<code class="devsite-terminal">adb reboot</code>
+</pre>
+
+<p>
+After boot up, fetch boot chart:
+</p>
+
+<pre
+class="prettyprint">$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh</pre>
+
+<p>
+When finished, delete <code>/data/bootchart/enabled</code> to prevent collecting
+the date every time.
+</p>
+
+<h3 id="systrace">Systrace</h3>
+
+<p>
+Systrace allows collecting both kernel and Android traces during boot up.
+Visualization of systrace can help in analyzing specific problem during the
+boot-up. (However, to check the average number or accumulated number during the
+entire boot, it is easier to look into kernel trace directly).
+</p>
+
+<p>
+To enable systrace during boot-up:
+</p>
+
+<ul>
+ <li> In <code>frameworks/native/atrace/atrace.rc</code>, change:
+
+<pre
+class="prettyprint">write /sys/kernel/debug/tracing/tracing_on 0</pre>
+<p>
+To:
+</p>
+
+<pre
+class="prettyprint">#write /sys/kernel/debug/tracing/tracing_on 0</pre>
+ </li>
+
+<p>
+This enables tracing (which is disabled by default).
+</p>
+
+<li>In the <code>device.mk</code> file, add the following line:
+
+<pre
+class="prettyprint">PRODUCT_PROPERTY_OVERRIDES += debug.atrace.tags.enableflags=802922</pre>
+</li>
+
+<li>In the device <code>BoardConfig.mk</code> file, add the following:
+
+<pre
+class="prettyprint">BOARD_KERNEL_CMDLINE := ... trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug</pre>
+</li>
+
+<p>
+For detailed I/O analysis, also add block and ext4.
+</p>
+
+<li>In the device-specific <code>init.rc</code> file, make the following
+ changes:
+ <ul>
+ <li><code>on property:sys.boot_completed=1</code> (this stops tracing on boot
+complete)</li>
+ <li><code>write /d/tracing/tracing_on 0</code></li>
+ <li><code>write /d/tracing/events/ext4/enable 0</code></li>
+ <li><code>write /d/tracing/events/block/enable 0</code></li>
+ </ul>
+</li>
+</ul>
+
+<p>
+After boot up, fetch trace:
+</p>
+
+
+<pre class="devsite-terminal">adb root && adb shell "cat /d/tracing/trace" &lt; boot_trace
+./external/chromium-trace/catapult/tracing/bin/trace2html boot_trace --output boot_trace.html
+</pre>
+
+<p class="note">
+<strong>Note:</strong> Chrome cannot handle files that are too large. Consider
+cutting the <code>boot_trace</code> file using <code>tail</code>,
+<code>head</code>, or <code>grep</code> for necessary portions. And
+I/O analysis often requires analyzing the captured <code>boot_trace</code>
+directly, as there are too many events.
+</p>
+</body>
+</html>
diff --git a/en/devices/tech/perf/flash-wear.html b/en/devices/tech/perf/flash-wear.html
new file mode 100644
index 00000000..5dc42512
--- /dev/null
+++ b/en/devices/tech/perf/flash-wear.html
@@ -0,0 +1,175 @@
+<html devsite>
+ <head>
+ <title>Flash Wear Management in Android Automotive</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 Automotive internal storage uses an Embedded MultiMediaCard (eMMC) with
+thousands of erase/write cycles; if the eMMC fails, the system can become
+unusable. As vehicles have long lifespans (typically 10+ years), the eMMC must
+be extremely reliable. This page describes eMMC behavior and how OEMs can
+lower the risk of a failing eMMC (and thus avoid failed Android Automotive
+systems).
+</p>
+
+<h2 id="emmc-behavior">eMMC behavior</h2>
+
+<p>
+eMMC devices use wear leveling techniques to work around erase/write limitations
+by arranging data and distributing writes evenly across the system (so no single
+block fails due to intensive writes). The estimated life of eMMC depends on:
+</p>
+
+<ul>
+<li><strong>Amount of writes</strong>. On phones, the amount of data written to
+internal storage can be more than 10GB per day. On Automotive implementations, we don't
+have real world data on how much data will be written due to limited
+applications. However, when users are streaming high quality music and using
+navigation, we observe 50MB data written to eMMC every minute. In the future, we
+may have other types of write-intensive apps, such as dashboard camera
+applications that continuously record and store videos. In addition, some cars
+will be shared vehicles used multiple hours everyday. For these reasons and
+others, we expect Android Automotive implementations to have more eMMC writes
+than a phone.</li>
+<li><strong>Write patterns</strong>. Writes and erasures are done in blocks.
+Writing data frequently in small chunks wears the eMMC faster than writing the
+same amount of data less frequently and in larger chunks.</li>
+<li><strong>Available size of eMMC</strong>. Larger storage size means the wear
+leveling algorithm can spread the writes across larger number of blocks.
+<li>Wear leveling techniques.</li>
+<li><strong>Environmental factors</strong>. Examples include an operating
+temperature range of usually -20 ~ 85 Celsius; temperature beyond this range
+could further shorten the lifespan of the eMMC.</li>
+</ul>
+
+<p>
+For an eMMC with 16GB usable space and 3k erase/write cycles, we estimate the
+following:
+</p>
+<table>
+ <tr>
+ <th>Daily writes
+ </th>
+ <td>16GB
+ </td>
+ <td>32GB
+ </td>
+ </tr>
+ <tr>
+ <th>Estimated life time
+ </th>
+ <td>10 years
+ </td>
+ <td>5 years
+ </td>
+ </tr>
+</table>
+
+<p>
+However, the system would stop functioning properly long before the eMMc
+completely wears out as the usable storage size decreases, and the eMMC may have
+an even shorter lifespan depending on the leveling techniques and the write
+patterns used. In addition, this estimate does not consider the effects of
+misbehaved or malicious apps, which could attack Automotive systems by writing
+large blocks of junk data to eMMC without special permissions.
+</p>
+
+<p>
+To detect the possible eMMC failure before it actually happens, proper storage
+health monitoring should be built in as part of the overall system health
+monitoring
+</p>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+Android O supports features that enable OEMs to protect and monitor the
+internal storage of Android Automotive and prolong its lifespan.
+</p>
+
+<h3 id="restricting-third-party-apps">Restricting third-party apps</h3>
+
+<p>
+To protect the internal storage of Android Automotive system, Android O enables
+OEMs to configure whether third-party apps can be installed on internal storage
+(apps can write only to the partition on which they were installed). To
+configure, set the following configuration in the resource overlay:
+</p>
+
+<pre
+class="prettyprint notranslate">&lt;bool name="config_allow3rdPartyAppOnInternal">false&lt;/bool>
+</pre>
+
+<h3 id="reducing-flash-wear">Reducing flash wear</h3>
+
+<p>
+OEMs concerned about flash wear on internal storage can also add an SD card that
+is fast enough to be used as adopted storage. The SD card has the following
+behavior:
+</p>
+
+<ul>
+<li>When adopted, the SD card will be encrypted and is safe for storing app
+data.</li>
+<li>SD card slot must be in a safe location (users are not expected to remove
+the SD card frequently).</li>
+<li>SD card cannot be used for transferring data between Automotive systems and
+a computer.</li>
+<li>Ejecting the SD card will not affect a running system. However, it should
+not be removed unless it needs to be replaced.</li>
+</ul>
+
+<p>
+To ensure second-party applications (those built by car app developers) can be
+installed on SD card if the car mandates, car app developers must include
+<code>android:<a
+href="https://developer.android.com/guide/topics/manifest/manifest-element.html#install">installLocation</a>=["auto"
+| "preferExternal"] </code>in the app's manifest file.
+</p>
+
+<p>
+If the car does not allow third-party apps to be installed on internal storage
+(as described in <a href="#restricting-third-party-apps">Restricting third-party
+apps</a>), without this flag (or if the <code><a
+href="https://developer.android.com/guide/topics/manifest/manifest-element.html#install">installLocation</a>=internalOnly</code>
+setting is configured), app installation will fail.
+</p>
+
+<h3 id="getting-disk-metrics-with-storaged">Getting disk metrics with
+storaged</h3>
+
+<p>
+Android O introduces <em>storaged</em>, a new system service that samples and
+publishes disk and eMMc metrics such as information about overall disk usage,
+eMMC lifetime estimation, and per application disk I/O stats. OEMs can use this
+information to warn users when the internal storage begins to fail or when
+specific applications are performing too many disk I/Os. For details, refer to <a
+href="/devices/tech/debug/storaged">Implementing storaged</a>.
+</p>
+
+<h2 id="validation">Validation</h2>
+
+<p>
+This feature is tested in the <code>PackageManager</code> tests.
+</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/perf/task-snapshots.html b/en/devices/tech/perf/task-snapshots.html
new file mode 100644
index 00000000..9e5b3829
--- /dev/null
+++ b/en/devices/tech/perf/task-snapshots.html
@@ -0,0 +1,115 @@
+<html devsite>
+ <head>
+ <title>Task Snapshots</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.
+ -->
+
+<h2 id="introduction">Introduction</h2>
+
+<p>
+<em>Task Snapshots</em> is infrastructure introduced in Android O that combines
+screenshots for <em>Recents Thumbnails</em> as well as <em>Saved Surfaces</em>
+from Window Manager. Recents Thumbnails represent the last state of a task in
+the Recents view.
+</p>
+
+<p>
+When an activity went into a stopped state, Window Manager didn't destroy the
+surfaces of the activity as long as that activity was on the top of the task. If
+this activity had to be shown again, Window Manager was able to start the
+animation without waiting for the activity to finish drawing its first frame, as
+it was able to use this Saved Surface.
+</p>
+<h2 id="architecture">Architecture</h2
+>
+
+<p>
+The two concepts of Recents Thumbnails and Saved Surfaces are unified with Task
+Snapshots. When a task goes into background, Window Manager places a screenshot
+of this task into a GraphicBuffer. As long as the application of the top
+activity of the task stays in memory, this GraphicBuffer will be retained in
+memory. Now, when the same activity is brought to the front again, Window
+Manager will create a starting window (TaskSnapshotSurface), and attach the
+GraphicBuffer without copying any memory to the buffer queue of the starting
+window. As soon as the activity has drawn its first frame, the Task Snapshot
+starting window will fade out smoothly like regular splash screens.
+</p>
+
+<p>
+The same GraphicBuffer is also sent over Binder to SystemUI to be used to draw
+the preview state of a task in the Recents view. Since this is just a reference
+to a buffer, sending it over binder expends few resources. When the
+GraphicBuffer arrives at SystemUI, it is wrapped into a hardware Bitmap and then
+drawn onto the screen without any memory uploading to the graphics memory.
+</p>
+
+<h2 id="benefits">Benefits</h2>
+
+<p>
+There are three main benefits to this new architecture:
+</p>
+
+<ul>
+<li>If the task snapshot is used as a starting window, there is a nice crossfade
+between the snapshot and the real content.</li>
+<li>When the task snapshot is drawn in SystemUI, it can be done so without any
+copying. Previously the bitmap had to be copied into Ashmem, then into graphics
+memory. Since this method stores the snapshot directly in graphics memory, no
+copying is needed.</li>
+<li>The state you see in Recents always matches the state you'll first see when
+reopening the app. Having the same buffer here also saves a lot of memory.
+That's why Recents is now able to show these images at full resolution.
+Previously, it was down sampled by 64% to save memory.</li>
+</ul>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+This feature exists entirely in the Android platform. No integration is
+required, and customization is not supported. Device manufacturers may, however,
+disable the Task Snapshots feature entirely.
+</p>
+
+<p>
+To disable this feature, modify this function:
+</p>
+
+<pre class="prettyprint">
+frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215
+</pre>
+
+<p>
+Note that if the feature is disabled, the Recents view will not show any
+thumbnails whatsoever. This feature is automatically disabled on low-RAM
+devices.
+</p>
+
+<h2 id="examples-and-source">Examples and source</h2>
+
+<p>
+Find the rest of the code for this feature within the TaskSnapshot* files in:
+</p>
+
+<pre class="prettyprint">
+frameworks/base/+/master/services/core/java/com/android/server/wm/
+</pre>
+
+</body>
+</html>
diff --git a/en/devices/tech/settings/info-architecture.html b/en/devices/tech/settings/info-architecture.html
new file mode 100644
index 00000000..d74ff5f8
--- /dev/null
+++ b/en/devices/tech/settings/info-architecture.html
@@ -0,0 +1,292 @@
+<html devsite>
+ <head>
+ <title>Updated Information Architecture</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 8.0 introduces a new information architecture for the Settings app. The
+goal of the new information architecture is to simplify the way settings are
+organized and make it easier for users to quickly find the settings needed to
+customize their Android devices.
+</p>
+
+<h2 id="examples-and-source">Examples and source</h2>
+
+<p>
+Most pages in Settings are currently implemented using the new framework. A good
+example is DisplaySettings:
+<code>packages/apps/Settings/src/com/android/settings/DisplaySettings.java</code>
+</p>
+
+<p>
+Files paths for important components are listed below:
+</p>
+
+<h3 id="categorykey">CategoryKey</h3>
+
+<code>packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java</code>
+
+<h3 id="dashboardfragmentregistry">DashboardFragmentRegistry</h3>
+
+<code>packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java</code>
+
+<h3 id="dashboardfragment">DashboardFragment</h3>
+
+<code>packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java</code>
+
+<h3 id="preferencecontrollers">AbstractPreferenceController and PreferenceController</h3>
+
+<code>frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java</code>
+
+<code>packages/apps/Settings/src/com/android/settings/core/PreferenceController.java</code>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+Device manufacturers are encouraged to adapt the existing Settings information
+architecture and insert additional settings pages as needed to accommodate
+partner-specific features. Moving preferences from legacy page (implemented as
+SettingsPreferencePage) to a new page (implemented using DashboardFragment) can
+be complicated. The preference from the legacy page is likely not implemented
+with a PreferenceController.
+</p>
+
+<p>
+So when moving it into a DashboardFragment, partners will need to create a
+PreferenceController and move the code into the controller before instantiating
+it in the new DashboardFragment. The refactor process is fairly straightforward
+since most of it is just moving existing code.
+</p>
+
+<p>
+Once done with refactoring, OEMs should submit patch CLs with tests to have
+their changes merged upstream.
+</p>
+
+<h3 id="plugin">Plugin-style information architecture</h3>
+
+<p>
+Each settings item is implemented as a Preference. A Preference can easily be
+moved from one page to another.
+</p>
+
+<p>
+To make it easier for multiple settings to be moved around, Android O introduces
+a plugin style host fragment that contains settings items. Settings items are
+modeled as plugin-style controllers. Hence, a settings page is constructed by a
+single host fragment and multiple setting controllers.
+</p>
+
+<h3 id="dashboard-fragment">DashboardFragment</h3>
+
+<p>
+This is the host of plugin-style preference controllers. The fragment inherits
+from PreferenceFragment and has hooks to inflate and update both static
+preference lists and dynamic preference lists.
+</p>
+
+<h3 id="static-preferences">Static preferences</h3>
+
+<p>
+A static preference list is defined in XML using the <Preference> tag. A
+DashboardFragment implementation uses the getPreferenceScreenResId() method to
+define which XML file contains the static list of preferences to display.
+</p>
+
+<h3 id="dynamic-preferences">Dynamic preferences</h3>
+
+<p>
+A dynamic item represents a tile with intent, leading to an external or internal
+Activity. Usually, the intent leads to a different setting page. For example,
+the "Google" setting item in the Settings homepage is a dynamic item. Dynamic
+items are defined in AndroidManifest (discussed below) and loaded through a
+FeatureProvider (defined as DashboardFeatureProvider).
+</p>
+
+<p>
+Note that dynamic settings are more heavyweight than statically configured
+settings, so normally developers should implement the setting as a static one.
+However the dynamic setting can be useful when any of the following is true:
+</p>
+
+<ul>
+<li>The setting is not directly implemented in the Settings app (such as
+injecting a setting implemented by OEM/Carrier apps).</li>
+<li>The setting should appear on the Settings homepage.</li>
+<li>You already have an Activity for the setting and don't want to implement the
+extra static config.</li>
+</ul>
+
+<p>
+To configure an Activity as a dynamic setting, you need to do a few things:
+</p>
+
+<ul>
+<li>Mark the activity as a dynamic setting. This is done by simply adding an
+intent-filter to the activity.</li>
+<li>Tell Settings app which category it belongs to. The category is a constant,
+defined in <strong>CategoryKey</strong>.</li>
+<li>Optional: Add a summary text when the setting is displayed.</li>
+</ul>
+
+<p>
+Here is an example taken from Settings app for DisplaySettings.
+</p>
+
+<pre
+class="prettyprint">
+&lt;activity android:name="Settings$DisplaySettingsActivity"
+ android:label="@string/display_settings"
+ android:icon="@drawable/ic_settings_display"&gt;
+ &lt;!-- Mark the activity as a dynamic setting --&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="com.android.settings.action.IA_SETTINGS" /&gt;
+ &lt;/intent-filter&gt;
+ &lt;!-- Tell Settings app which category it belongs to --&gt;
+ &lt;meta-data android:name="com.android.settings.category"
+ android:value="com.android.settings.category.ia.homepage" /&gt;
+ &lt;!-- Add a summary text when the setting is displayed --&gt;
+ &lt;meta-data android:name="com.android.settings.summary"
+ android:resource="@string/display_dashboard_summary"/&gt;
+ &lt;/activity&gt;
+</pre>
+
+<p>
+At render time, the fragment will ask for a list of Preferences from both static
+XML and dynamic settings defined in AndroidManifest. Regardless in which source
+a setting is loaded, DashboardFragment manages the handling logic of each
+setting through PreferenceController<strong> </strong>(discussed below). Then
+they will be displayed onto the UI as a mixed list.
+</p>
+
+<h3 id="preference-controller">PreferenceController</h3>
+
+<p>
+A PreferenceController contains all logic to interact with the preference,
+including displaying/updating/search indexing and so on.
+</p>
+
+<p>
+Correspondingly, the interface of PreferenceController has API of isAvailable(),
+displayPreference(), handlePreferenceTreeClicked() etc. Detailed documentation
+on each API can be found in the interface class.
+</p>
+
+<p>
+While installing a preference to the fragment, dashboard provides a method to
+attach a PreferenceController before display time. At install time, the
+controller will be wired up to the fragment so all future relevant events are
+sent to the controller.
+</p>
+
+<p>
+DashboardFragment will keep a list of PreferenceControllers in the screen. At
+fragment's onCreate(), all controllers will be invoked for the isAvailable()
+method, and if it returns true, displayPreference() will be invoked to process
+display logic.
+</p>
+
+<h2 id="using-dashboardfragment">Using DashboardFragment</h2>
+
+<h3 id="moving-preference">Moving preference from page A to B</h3>
+
+<p>
+If the preference is statically listed in the original page's preference XML
+file, follow the <strong>static </strong>path below. Otherwise, follow the
+<strong>dynamic</strong> path.
+</p>
+
+<h4 id="static-move">Static</h4>
+
+<ol>
+<li>Find the preference XML files for the original page and destination page.</li>
+You can find this information from the page's getPreferenceScreenResId() method.</li>
+<li>Remove the preference in the original page's XML.</li>
+<li>Add the preference to destination page's XML.</li>
+<li>Remove the PreferenceController for this preference in the original page's
+Java implementation. Usually it's in getPreferenceControllers().</li>
+<strong>Note</strong>: It is possible the preference does not have a
+PreferenceController.</li>
+<li>Instantiate the PreferenceController in the destination page's
+getPreferenceControllers().</li>
+</ol>
+
+<h4 id="dynamic-move">Dynamic</h4>
+
+<ol>
+<li>Find which category the original and destination page hosts. You can find
+this information in <code>DashboardFragmentRegistry</code>.</li>
+<li>Open the <code>AndroidManifest.xml</code> file that contains the setting you
+need to move and find the Activity entry representing this setting.</li>
+<li>Change the activity's metadata value for "com.android.settings.category",
+set the value point to the new page's category key.</li>
+</ol>
+
+<h3 id="creating-a-new-preference">Creating a new preference in a page</h3>
+
+<p>
+If the preference is statically listed in the original page's preference XML
+file, follow the <strong>static </strong>path below. Otherwise follow the
+<strong>dynamic</strong> path.
+</p>
+
+<h4 id="static-create">Static</h4>
+
+<ol>
+<li>Find the preference XML files for the page. You can find this information
+from the page's getPreferenceScreenResId() method.</li>
+<li>Add a new Preference item in the XML. Make sure it has a unique android:key.</li>
+<li>Instantiate a PreferenceController for this preference in the page's
+getPreferenceControllers() method.</li>
+If this preference already existed in other
+places, it's possible there is already a PreferenceController for it. You can
+reuse the PreferenceController without building a new one.</li>
+</ol>
+
+<h4 id="dynamic-create">Dynamic</h4>
+
+<ol>
+<li>Find which category the original and destination page hosts. You can find
+this information in <code>DashboardFragmentRegistry</code>.</li>
+<li>Create a new Activity in AndroidManifest, and add necessary metadata to
+define the setting. Make the metadata value for "com.android.settings.category"
+to be the same value defined in step 1.</li>
+</ol>
+
+<h3 id="create-new-page">Create a new page</h3>
+<ol>
+<li>Create a new fragment, inheriting from DashboardFragment.</li>
+<li>Define its category in <code>DashboardFragmentRegistry</code>.
+<p class="note"><strong>Note:</strong> This step is optional. If you do not need
+any dynamic preferences in this page, you don't need to provide a category key.</p></li>
+<li>Follow the steps for adding the settings needed for this page.</li>
+</ol>
+
+<h2 id="validation">Validation</h2>
+
+<ul>
+<li>Run the robolectric tests in Settings, all existing and new tests should
+pass.
+<li>Build and install Settings, manually open the page being modified; the page
+should update immediately.</li>
+</ul>
+</body>
+</html>
diff --git a/en/devices/tech/settings/patterns-components.html b/en/devices/tech/settings/patterns-components.html
new file mode 100644
index 00000000..90c730f4
--- /dev/null
+++ b/en/devices/tech/settings/patterns-components.html
@@ -0,0 +1,157 @@
+<html devsite>
+ <head>
+ <title>Patterns and Components</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>
+In Android 8.0, the Settings menu gains several components and widgets that
+cover common uses. Device manufacturers and developers are encouraged to use the
+common components when extending the Settings app so new user interfaces stay
+consistent with the existing Settings UI.
+</p>
+
+<p>
+Here is a summary of improvements:
+</p>
+
+<ul>
+<li>Divider behavior change in support library Preference framework. Divider is
+now drawn between categories.</li>
+<li>ActionBar theme change. The ActionBar now uses light color theme, with
+accent color text.</li>
+<li>New preference layout. The space for icons remains even when a preference
+has no icon.</li>
+</ul>
+
+<p>
+New widgets:
+</p>
+
+<ul>
+<li>A header widget for application details. Displays app icon, app label and
+other information.</li>
+<li>An expand button on some pages. Page can start as collapsed and hide less
+important items until user clicks expand button.</li>
+<li>Default app picker UI:
+ <ul>
+ <li>The UI for choosing default browser, default phone app, etc.</li>
+ <li>Formerly a dialog, now it's a full screen radio button-based UI.</li>
+ </ul>
+<li>A "MasterSwitch" style preference. This is a preference with two click
+targets. Left target leads to a subsetting fragment or intent. Right target is a
+switch toggle, controlling on/off for the entire page.</li>
+</ul>
+
+<h2 id="examples-and-source">Examples and source</h2>
+<ul>
+<li>Divider behavior
+ <ul>
+ <li>All pages in Settings are modified to use the new divider behavior.</li>
+ <li>The divider behavior is defined as a ThemeOverlay in:<br>
+<code>packages/apps/Settings/res/values/styles_preference.xml</code></li>
+ </ul>
+</li>
+<li>ActionBar theme change
+ <ul>
+ <li>All pages in Settings are modified to use the new ActionBar theme.</li>
+ <li>The theme is defined in Theme.DeviceDefault.Settings</li>
+ </ul>
+</li>
+<li>New preference layout
+ <ul>
+ <li>Many pages in Settings are now using the new preference layout.</li>
+ <li>You can find the code in:<br>
+<code>packages/apps/Settings/res/values/styles_preference.xml</code></li>
+ </ul>
+</li>
+<li>App header widget
+ <ul>
+ <li>Most application information pages in Settings are already implementing the
+new App header.</li>
+ <li>Examples and code can be found at:<br>
+<code>packages/apps/Settings/src/com/android/settings/applications/AppHeaderController.java</code></li>
+ </ul>
+</li>
+<li>Expand button
+ <ul>
+ <li>Examples and code can be found at:<br>
+<code>packages/apps/Settings/src/com/android/settings/dashboard/ProgressiveDisclosureMixin.java</code>
+<p class="note"><strong>Note:</strong> This component must be used together with
+DashboardFragment. (See more details about DashboardFragment in <a
+href="information-architecture.html">Updated Information Architecture</a>.)</p>
+ </li>
+ </ul>
+<li>Default app picker
+ <ul>
+ <li>You can find the code for base class in:<br>
+<code>packages/apps/Settings/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java</code> </li>
+ <li>There are several subclasses of DefaultAppPickerFragment, each implementing
+a picker for different intent.</li>
+ </ul>
+</li>
+<li><em>MasterSwitch</em> style preference
+ <ul>
+ <li>Code is at:
+<code>packages/apps/Settings/src/com/android/settings/widget/MasterSwitchPreference.java</code></li>
+ <li>An example use case is Wi-Fi master switch. You can find an example at:
+<code>packages/apps/Settings/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java</code></li>
+ </ul>
+</li>
+</ul>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+Device manufacturers can start using all of the new components out of the box.
+If OEMs decide to implement a new "MasterSwitch" style preference or default app
+picker, they should follow the examples in this document and the reference files
+(Javadoc) written with each component for more details.
+</p>
+
+<h2 id="customizing">Customizing</h2>
+
+<ul>
+<li>Divider behavior. To change how divider is drawn, update the style for Settings dividers and
+change the value for the following:
+ <ul>
+ <li>allowDividerAbove</li>
+ <li>allowDividerBelow</li>
+ <li>allowDividerAfterLastItem</li>
+ </ul>
+</li>
+<li>ActionBar theme color. Activities should use <code>Theme.DeviceDefault.Settings</code> as their theme, or
+create a custom theme using <code>Theme.DeviceDefault.Settings</code> as parent.
+</li>
+<li>App header widget. Use setters in AppHeaderController to customize each field and call build()
+once all fields are set.
+</li>
+<li>Expand button:
+ <ul>
+ <li>To fully disable the functionality, override the constructor for
+ProgressiveDisclosureMixin and set keepExpanded to true.</li>
+ <li>To customize how many items to show initially, call the
+<code>ProgressiveDisclosureMixin.setTileLimit()</code> method during fragment's
+<code>onAttach(Context)</code> method.</li>
+ </ul>
+</li>
+</ul>
+</body>
+</html>
diff --git a/en/devices/tech/settings/personalized.html b/en/devices/tech/settings/personalized.html
new file mode 100644
index 00000000..f0bda729
--- /dev/null
+++ b/en/devices/tech/settings/personalized.html
@@ -0,0 +1,77 @@
+<html devsite>
+ <head>
+ <title>Personalized Settings</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>
+The Android Settings app provides a list of suggestions to the users in Android 8.0.
+These suggestions typically promote features of the phone, and they are customizable
+(e.g., "Set Do Not Disturb schedule" or "Turn on Wi-Fi Calling"). This feature provides
+ranking for suggestions, based on any contextual signal or the user's past interactions
+with suggestions.
+</p>
+
+<p>
+The current default Android Open Source Project (AOSP) ranking model is based on
+user's previous interactions with the suggestion, which is a simple linear model
+trained with logistic regression to properly weight the interaction signals. The
+default implementation uses suggestions shown, clicked or dismissed as
+indicators along with the recency of these events to rank the suggestions and
+increase the chance of predicting a user's interaction with these suggestions.
+This model was built with a limited amount of logged user data. Device manufacturers
+(OEMs) can develop their own ranking model based on any collected data and potentially
+include contextual signals and calibrate the ranking.
+</p>
+
+<h2 id="implementation">Implementation</h2>
+
+<p>
+Find the default <code>packages/apps/Settings/src/com/android/settings/dashboard/suggestions/SuggestionRanker.java</code> implementation in AOSP.
+</p>
+
+<p>
+This feature is guarded by a flag, <code>isSmartSuggestionEnabled</code>, which
+is set to false by default. If enabled (set to true), the feature operates
+without additional modification using the default AOSP implementation. OEMs can
+either use the default implementation or introduce their own implementation to
+enable this feature.
+</p>
+
+<p>
+OEMs may customize the feature by implementing <code>platform/packages/apps/Settings/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
+</code> feature and Overriding the file's <code>rankSuggestions</code> method.
+This method gets two lists containing suggestion Tiles and the corresponding
+suggestionIds. This method should reorder the tiles in the list only according
+to the desired ranking score. The suggestionIds can be used to uniquely identify
+suggestions and extract the required past information about the suggestion,
+depending on the ranking implementation (e.g., recency of interaction with this
+particular suggestion).
+</p>
+
+<h2 id="validation">Validation</h2>
+
+<p>
+Implementers can ensure their version of the feature works as intended by
+writing their own unit tests similar to <code>packages/apps/Settings/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionRankerTest.java</code> to verify the ranking.
+</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/settings/universal-search.html b/en/devices/tech/settings/universal-search.html
new file mode 100644
index 00000000..0c59fcd0
--- /dev/null
+++ b/en/devices/tech/settings/universal-search.html
@@ -0,0 +1,199 @@
+<html devsite>
+ <head>
+ <title>Universal Search</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 8.0 adds expanded search capabilities for the <em>Settings</em> menu. This
+document describes how to add a setting and ensure it is properly indexed for
+Settings search.
+</p>
+
+<h2 id="indexable-settings">Creating indexable settings</h2>
+
+<p>
+Each Settings fragment that needs to be indexed implements the
+<code>Indexable</code>interface, AND requires the static
+field:
+
+<pre
+class="prettyprint">public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
+</pre>
+
+<p>
+Once you have your fragment set up for indexing, add it to
+<code>SearchIndexableResources</code> found at:<br>
+<code>packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java
+</code>
+</p>
+
+<h2 id="optional-methods">Optional methods</h2>
+
+<p>This <code>SearchIndexProvider</code>interface has four optional
+ methods.</p>
+
+<h3 id="getXmlResourcesToIndex">getXmlResourcesToIndex</h3>
+ <ul>
+ <li>Override this if your fragment content is from: <code>preference xml</code></li>
+ <li>Returns an XML preference as a list to be indexed.</li>
+ </ul>
+
+ <p>XML resources example:</p>
+
+<pre
+class="prettyprint">public List&lt;SearchIndexableResource&gt; getXmlResourcesToIndex(Context context, boolean enabled) {
+ ArrayList&lt;SearchIndexableResource&gt; result = new ArrayList&lt;SearchIndexableResource&gt;();
+SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.display_settings;
+ result.add(sir);
+
+ return result;
+}</pre>
+
+<h3 id="getRawDataToIndex">getRawDataToIndex</h3>
+ <ul>
+ <li>Override this if your fragment content is NOT from: <code>preference
+xml</code></li>
+ <li>Returns a list of Raw data (<code>SearchIndexableRaw</code>) to be indexed.</li>
+ </ul>
+
+<p>Raw data example:</p>
+
+<pre
+class="prettyprint">
+public List&lt;SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+ final List&lt;SearchIndexableRaw> result = new ArrayList&lt;>();
+ final Resources res = context.getResources();
+
+ // Add fragment title
+ SearchIndexableRaw data = new SearchIndexableRaw(context);
+ data.title = res.getString(R.string.wifi_settings);
+ data.screenTitle = res.getString(R.string.wifi_settings);
+ data.keywords = res.getString(R.string.keywords_wifi);
+ data.key = DATA_KEY_REFERENCE;
+ result.add(data);
+
+ return result;
+}
+</pre>
+
+<h3 id="getRawDataToIndex">getNonIndexableKeys</h3>
+ <ul>
+ <li>If your fragment is a <code>DashboardFragment</code>, you rarely need to
+override this.</li>
+ <li>Returns a list of keys that corresponds to results that should not show up
+for the given user, device, configuration, etc.The keys provided here should
+match the <em>KEY</em> field in <code>SearchIndexableResource</code> and
+<code>SearchIndexableRaw</code>.</li>
+ <li>For example: Data Usage should not show up for users who have never had a
+SIM card in their device.</li>
+ </ul>
+
+<p>Non-indexable keys example:</p>
+
+<pre
+class="prettyprint">
+public List&lt;String&gt; getNonIndexableKeys(Context context) {
+ final List&lt;String&gt; keys = super.getNonIndexableKeys(context);
+ if (!checkIntentAction(context, "android.settings.TERMS")) {
+ keys.add(KEY_TERMS);
+ }
+ if (!checkIntentAction(context, "android.settings.LICENSE")) {
+ keys.add(KEY_LICENSE);
+ }
+ if (!checkIntentAction(context, "android.settings.COPYRIGHT")) {
+ keys.add(KEY_COPYRIGHT);
+ }
+ if (!checkIntentAction(context, "android.settings.WEBVIEW_LICENSE")) {
+ keys.add(KEY_WEBVIEW_LICENSE);
+ }
+ return keys;
+}</pre>
+
+<h3 id="getPreferenceControllers">getPreferenceControllers</h3>
+
+<p>
+Returns a list of preference controllers associated with this fragment.
+This list is used to form inline results, update non-indexables, etc.
+</p>
+
+<p>
+Thus, everything you want to show up in search must be included in either
+<code>getXmlResourcesToIndex</code> or <code>getRawDataToIndex</code>.
+</p>
+
+<h2 id="keywords">Adding keywords for your settings</h2>
+
+<p>
+To ensure a setting is easily searchable, add keywords that are relevant for the
+setting that a user may use to search for the setting.
+</p>
+
+<p>
+Things to consider when adding keywords:
+</p>
+ <ul>
+ <li>Keywords are a list of words that the user does not necessarily see but may
+be part of their mental model for how the setting works.</li>
+ <li>These are words that the user might type to get to your setting.</li>
+ <li>They can be synonyms or any words associated to the setting can be used.</li>
+ <li>For example, "mute" might be used to find the Volume setting.</li>
+ </ul>
+
+<h2 id="duplication">Avoiding duplication</h2>
+
+<p>
+If you are unconditionally suppressing a settings page, remove the indexing of
+the original page to avoid duplication of results.
+</p>
+
+ <ol>
+ <li>Find the <code>PreferenceFragment</code> of the page you are suppressing.</li>
+ <li>Remove the <code>SearchIndexProvider</code>.</li>
+ </ol>
+
+<h2 id="validation">Validation</h2>
+
+<p>
+To test the searchability of a new setting:
+</p>
+
+ <ol>
+ <li>Instal a recent version of O on the device.</li>
+ <li>Reindex the database by selecting:</li>
+<em>Settings > Apps & Notifications > Apps info > Settings > Storage >
+<strong>Clear Data</strong></em></li>
+ <li>Verify the target settings shows up in search.<br>
+ Searching for a prefix of the title of a setting will match it.</li>
+ </ol>
+
+<p>
+These robolectric tests may be run to validate the implementation of this
+feature:<br>
+<code>packages/apps/Settings/tests/robotests/src/com/android/settings/search</code>
+</p>
+
+<p>
+The build target is: <code>RunSettingsRoboTests</code>
+</p>
+
+</body>
+</html>
diff --git a/en/devices/tech/vts/database.html b/en/devices/tech/vts/database.html
new file mode 100644
index 00000000..e0c285b1
--- /dev/null
+++ b/en/devices/tech/vts/database.html
@@ -0,0 +1,224 @@
+<html devsite>
+ <head>
+ <title>VTS Dashboard Database</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 support a continuous integration dashboard that is scalable, performant, and
+flexible, the VTS Dashboard backend must be carefully designed with a strong
+understanding of database functionality.
+<a href="https://cloud.google.com/datastore/docs/" class="external">Google Cloud
+Datastore</a> is a NoSQL database that offers transactional ACID guarantees and
+eventual consistency as well as strong consistency within entity groups.
+However, the structure is very different than SQLdatabases (and even Cloud
+Bigtable); instead of tables, rows, and cells there are kinds, entities, and
+properties.
+</p>
+<p>
+The following sections outline the data structure and querying patterns for
+creating an effective backend for the VTS Dashboard web service.
+</p>
+
+<h2 id=entities>Entities</h2>
+<p>
+The following entities store summaries and resources from VTS test runs:
+</p>
+<ul>
+<li><strong>Test Entity</strong>. The test entity stores metadata
+about test runs of a particular test. Its key is the test name and its
+properties include the failure count, passing count, and list of test case
+breakages from when the alert jobs update it.</li>
+<li><strong>Test Run Entity</strong>. The test run entity contains metadata
+from runs of a particular test. It must store the test start and end timestamps,
+the test build ID, the number of passing and failing test cases, the type of run
+(e.g. pre-submit, post-submit, or local), a list of log links, the host machine
+name, and coverage summary counts.</li>
+<li><strong>Device Information Entity</strong>. Device information entities
+contain details about the devices used during the test run. It includes the
+device build ID, product name, build target, branch, and ABI information. This
+is stored separately from the test run entity to support multi-device test runs
+in a one-to-many fashion.</li>
+<li><strong>Profiling Point Run Entity</strong>. The profiling point run entity
+summarizes the data gathered for a particular profiling point within a test
+run. It describes the axis labels, profiling point name, values, type, and
+regression mode of the profiling data.</li>
+<li><strong>Coverage Entity</strong>. Each coverage entity describes the
+coverage data gathered for one file. It contains the GIT project information,
+file path, and the list of coverage counts per line in the source file.
+<li><strong>Test Case Run Entity</strong>. A test case run describes the outcome
+of a particular test case from a test run, including the test case name and its
+result.</li>
+<li><strong>User Favorites Entity</strong>. Each user subscription can be
+represented in an entity containing a reference to the test and the user ID
+generated from the App Engine user service. This allows for efficient
+bi-directional querying (i.e. for all users subscribed to a test and for all
+tests favorited by a user).</li>
+</ul>
+
+<h2 id=entity-grouping>Entity grouping</h2>
+<p>
+When designing ancestry relationships, you must balance the need to provide
+effective and consistent querying mechanisms against the limitations enforced by
+the database.
+</p>
+
+<p>
+Each test module will represent the root of an entity group, with test run
+entities as children. Each test run entity is also a parent for device entities,
+profiling point entities, and coverage entities relevant to the respective test
+and test run ancestor.
+</p>
+<img src="../images/treble_vts_dash_entity_ancestry.png">
+<figcaption><strong>Figure 1</strong>. Test entity ancestry.</figcaption>
+
+<h3 id=benefits>Benefits</h3>
+<p>
+The consistency requirement ensures that future operations will not see the
+effects of a transaction until it commits, and that transactions in the past are
+visible to present operations. In Cloud Datastore, entity grouping creates
+islands of strong read and write consistency within the group, which in this
+case is all of test runs and data related to a test module. This offers the
+following benefits:
+</p>
+<ul>
+<li>Reads and updates to test module state by alert jobs can be treated as
+atomic</li>
+<li>Guaranteed consistent view of test case results within test modules</li>
+<li>Faster querying within ancestry trees</li>
+</ul>
+
+<h3 id=limitations>Limitations</h3>
+<p>
+Writing to an entity group at a rate faster than one entity per second is not
+advised as some writes may be rejected. As long as the alert jobs and the
+uploading does not happen at a rate faster than one write per second, the
+structure is solid and guarantees strong consistency.
+</p>
+<p>
+Ultimately, the cap of one write per test module per second is reasonable because
+test runs usually take at least one minute including the overhead of the VTS
+framework; unless a test is consistently being executed simultaneously on more
+than 60 different hosts, there cannot be a write bottleneck. This becomes even
+more unlikely given that each module is part of a test plan which often takes
+longer than one hour. However, anomalies can easily be handled if hosts run the
+tests at the same time, causing short bursts of writes to the same hosts (e.g.
+by catching write errors and trying again).
+</p>
+
+<h3 id=scaling>Scaling considerations</h3>
+<p>
+A test run doesn't necessarily need to have the test as its parent (e.g. it
+could take some other key and have test name, test start time as properties);
+however, this will exchange strong consistency for eventual consistency. For
+instance, the alert job may not see a mutually consistent snapshot of the most
+recent test runs within a test module, which means that the global state may not
+depict a fully accurate representation of sequence of test runs. This may also
+impact the display of test runs within a single test module, which may not
+necessarily be a consistent snapshot of the run sequence. Eventually the
+snapshot will be consistent, but there are no guarantees the freshest data
+will be.
+</p>
+
+<h2 id=test-cases>Test cases</h2>
+<p>
+Another potential bottleneck is large tests with many test cases. The two
+operative constraints are the write throughput maximum within of an entity group
+of one per second, along with a maximum transaction size of 500 entities.
+</p>
+<p>
+One natural approach would be to specify a test case that has a test run as an
+ancestor (similar to how coverage data, profiling data, and device information
+are stored):
+</p>
+<img src="../images/treble_vts_descend_not.png">
+<figcaption><strong>Figure 2</strong>. Test Cases descend from Test Runs (NOT
+RECOMMENDED).</figcaption>
+
+<p>While this approach offers atomicity and consistency, it imposes strong
+limitations on tests: If a transaction is limited to 500 entities, then a test
+can have no more than 498 test cases (assuming no coverage or profiling data).
+If a test were to exceed this, then a single transaction could not write all of
+the test case results at once, and dividing the test cases into separate
+transactions could exceed the maximum entity group write throughput of one
+iteration per second. As this solution will not scale well without sacrificing
+performance, it is not recommended.
+</p>
+
+<p>
+However, instead of storing the test case results as children of the test run,
+the test cases can be stored independently and their keys provided to the test
+run (a test run contains a list of identifiers to its test cases entities):
+</p>
+
+<img src="../images/treble_vts_descend.png">
+<figcaption><strong>Figure 3</strong>. Test Cases stored independently
+(RECOMMENDED).</figcaption>
+
+<p>
+At first glance, this may appear to break the strong consistency guarantee.
+However, if the client has a test run entity and a list of test case
+identifiers, it doesn't need to construct a query; it can instead directly get
+the test cases by their identifiers, which is always guaranteed to be
+consistent.
+</p>
+<p>
+This approach vastly alleviates the constraint on the number of test cases a
+test run may have while gaining strong consistency without threatening
+excessive writing within an entity group.
+</p>
+
+<h2 id=patterns>Data access patterns</h2>
+<p>
+The VTS Dashboard uses the following data access patterns:
+</p>
+<ul>
+<li><strong>User favorites</strong>. User favorites can be queried for by using
+an equality filter on user favorites entities having the particular App Engine
+User object as a property.</li>
+<li><strong>Test listing</strong>. Test listing is a simple query of test
+entities; to reduce bandwidth to render the home page, a projection can be used
+on passing and failing counts so as to omit the potentially long listing of
+failed test case IDs and other metadata used by the alerting jobs.</li>
+<li><strong>Test runs</strong>. Querying for test run entities requires a sort
+on the key (timestamp) and possible filtering on the test run properties such as
+build ID, passing count, etc. By performing an ancestor query with a test entity
+key, the read is strongly consistent. At this point, all of the test case
+results can be retrieved using the list of IDs stored in a test run property;
+this also is guaranteed to be a strongly consistent outcome by the nature of
+datastore get operations.</li>
+<li><strong>Profiling and coverage data</strong>. Querying for profiling or
+coverage data associated with a test can be done without also retrieving any
+other test run data (such as other profiling/coverage data, test case data,
+etc.). An ancestor query using the test test and test run entity keys will
+retrieve all profiling points recorded during the test run; by also filtering on
+the profiling point name or filename, a single profiling or coverage entity can
+be retrieved. By the nature of ancestor queries, this operation is strongly
+consistent.</li>
+</ul>
+
+<p>
+For details on the UI and screenshots of these data patterns in action, see
+<a href="/devices/architecture/testing/ui.html">VTS Dashboard UI</a>.
+</p>
+
+ </body>
+</html>
diff --git a/en/devices/tech/vts/index.html b/en/devices/tech/vts/index.html
new file mode 100644
index 00000000..510c1200
--- /dev/null
+++ b/en/devices/tech/vts/index.html
@@ -0,0 +1,58 @@
+<html devsite>
+ <head>
+ <title>Vendor Test Suite (VTS) &amp; Infrastructure</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>
+The Android Vendor Test Suite (VTS)</a> provides extensive new functionality for
+Android testing and promotes a test-driven development process. To help the
+Android development community interact with test data, Android O includes the
+following testing resources:</p>
+<ul>
+<li><a href="/devices/tech/test_infra/tradefed/fundamentals/vts.html">Systems
+Testing with VTS</a>. Describes how to use VTS to test an Android native system
+implementation, set up a testing environment, then test a patch using a VTS
+plan.</li>
+<li><strong>VTS Dashboard</strong>. Web-based user interface for viewing VTS
+results. Includes details on:
+ <ul>
+ <li><a href="/devices/tech/vts/database.html">Dashboard
+ database</a>. A scalable back-end to support the continuous integration
+ dashboard.</li>
+ <li><a href="/devices/tech/vts/ui.html">Dashboard UI</a>. A
+ cohesive user interface that uses material design to effectively display
+ information about test results, profiling, and coverage.</li>
+ <li><a href="/devices/tech/vts/setup.html">Dashboard setup</a>.
+ Instructions for setting up and configuring the VTS Dashboard.</li>
+ </ul>
+</li>
+<li><a href="/devices/tech/vts/performance.html">binder and hwbinder
+performance tests</a>. Tools for measuring throughput and latency.</li>
+</ul>
+
+<p>For additional details, refer to the
+<a href="https://codelabs.developers.google.com/codelabs/android-vts/#0" class="external">Android
+VTS v8.0 Codelab</a> on developer.android.com and the
+<a href="https://www.youtube.com/watch?v=7BX7oSHc7nk&list=PLWz5rJ2EKKc9JOMtoWWMJHFHgvXDoThva" class="external">Android VTS Products video</a> produced by Google Developers.</p>
+
+ </body>
+</html>
diff --git a/en/devices/tech/vts/performance.html b/en/devices/tech/vts/performance.html
new file mode 100644
index 00000000..0f05b234
--- /dev/null
+++ b/en/devices/tech/vts/performance.html
@@ -0,0 +1,473 @@
+<html devsite>
+ <head>
+ <title>Performance Testing</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 includes binder and hwbinder performance tests for throughput and
+latency. While many scenarios exist for detecting perceptible performance
+problems, running such scenarios can be time consuming and results are often
+unavailable until after a system is integrated. Using the provided performance
+tests makes it easier to test during development, detect serious problems
+earlier, and improve user experience.</p>
+
+<p>Performance tests include the following four categories:</p>
+<ul>
+<li>binder throughput (available in
+<code>system/libhwbinder/vts/performance/Benchmark_binder.cpp</code>)</li>
+<li>binder latency (available in
+<code>frameworks/native/libs/binder/tests/schd-dbg.cpp</code>)</li>
+<li>hwbinder throughput (available in
+<code>system/libhwbinder/vts/performance/Benchmark.cpp</code>)</li>
+<li>hwbinder latency (available in
+<code>system/libhwbinder/vts/performance/Latency.cpp</code>)</li>
+</ul>
+
+<h2 id=about>About binder and hwbinder</h2>
+<p>Binder and hwbinder are Android inter-process communication (IPC)
+infrastructures that share the same Linux driver but have the following
+qualitative differences:</p>
+
+<table>
+<tr>
+<th>Aspect</th>
+<th>binder</th>
+<th>hwbinder</th>
+</tr>
+
+<tr>
+<td>Purpose</td>
+<td>Provide a general purpose IPC scheme for framework</td>
+<td>Communicate with hardware</td>
+</tr>
+
+<tr>
+<td>Property</td>
+<td>Optimized for Android framework usage</td>
+<td>Minimum overhead low latency</td>
+</tr>
+
+<tr>
+<td>Change scheduling policy for foreground/background</td>
+<td>Yes</td>
+<td>No</td>
+</tr>
+
+<tr>
+<td>Arguments passing</td>
+<td>Uses serialization supported by Parcel object</td>
+<td>Uses scatter buffers and avoids the overhead to copy data required for
+Parcel serialization</td>
+</tr>
+
+<tr>
+<td>Priority inheritance</td>
+<td>No</td>
+<td>Yes</td>
+</tr>
+
+</table>
+
+<h3 id=transactions>Binder and hwbinder processes</h2>
+<p>A systrace visualizer displays transactions as follows:</p>
+<img src="../images/treble_systrace_binder_processes.png">
+<figcaption><strong>Figure 1.</strong> Systrace visualization of binder
+processes.</figcaption>
+
+<p>In the above example:</p>
+<ul>
+<li>The four (4) schd-dbg processes are client processes.</li>
+<li>The four (4) binder processes are server processes (name starts with
+<strong>Binder</strong> and ends with a sequence number).</li>
+<li>A client process is always paired with a server process, which is dedicated
+to its client.</li>
+<li>All the client-server process pairs are scheduled independently by kernel
+concurrently.</li>
+</ul>
+
+<p>In CPU 1, the OS kernel executes the client to issue the request. It then
+uses the same CPU whenever possible to wake up a server process, handle the
+request, and context switch back after the request is complete.</p>
+
+<h3 id=throughput-diffs>Throughput vs. latency</h3>
+<p>In a perfect transaction, where the client and server process switch
+seamlessly, throughput and latency tests do not produce substantially different
+messages. However, when the OS kernel is handling an interrupt request (IRQ)
+from hardware, waiting for locks, or simply choosing not to handle a message
+immediately, a latency bubble can form.</p>
+
+<img src="../images/treble_latency_bubble.png">
+<figcaption><strong>Figure 2.</strong> Latency bubble due to differences in
+throughput and latency.</figcaption>
+
+<p>The throughput test generates a large number of transactions with different
+payload sizes, providing a good estimation for the regular transaction time (in
+best case scenarios) and the maximum throughput the binder can achieve.</p>
+
+<p>In contrast, the latency test performs no actions on the payload to minimize
+the regular transaction time. We can use transaction time to estimate the binder
+overhead, make statistics for the worst case, and calculate the ratio of
+transactions whose latency meets a specified deadline.</p>
+
+<h3 id=priority-inversions>Handling priority inversions</h3>
+<p>A priority inversion occurs when a thread with higher priority is logically
+waiting for a thread with lower priority. Real-time (RT) applications have a
+priority inversion problem:</p>
+
+<img src="../images/treble_priority_inv_rta.png">
+<figcaption><strong>Figure 3.</strong> Priority inversion in real-time
+applications.</figcaption>
+
+<p>When using Linux Completely Fair Scheduler (CFS) scheduling, a thread always
+has a chance to run even when other threads have a higher priority. As a result,
+applications with CFS scheduling handle priority inversion as expected behavior
+and not as a problem. In cases where the Android framework needs RT scheduling
+to guarantee the privilege of high priority threads however, priority inversion
+must be resolved.</p>
+
+<p>Example priority inversion during a binder transaction (RT thread is
+logically blocked by other CFS threads when waiting for a binder thread to
+service):</p>
+<img src="../images/treble_priority_inv_rta_blocked.png">
+<figcaption><strong>Figure 4.</strong> Priority inversion, blocked real-time
+threads.</figcaption>
+
+<p>To avoid blockages, you can use priority inheritance to temporarily escalate
+the Binder thread to a RT thread when it services a request from a RT client.
+Keep in mind that RT scheduling has limited resources and should be used
+carefully. In a system with <em>n</em> CPUs, the maximum number of current RT
+threads is also <em>n</em>; additional RT threads might need to wait (and thus
+miss their deadlines) if all CPUs are taken by other RT threads.</p>
+
+<p>To resolve all possible priority inversions, you could use priority
+inheritance for both binder and hwbinder. However, as binder is widely used
+across the system, enabling priority inheritance for binder transactions might
+spam the system with more RT threads than it can service.</p>
+
+<h2 id=throughput>Running throughput tests</h2>
+<p>The throughput test is run against binder/hwbinder transaction throughput. In
+a system that is not overloaded, latency bubbles are rare and their impact
+can be eliminated as long as the number of iterations is high enough.</p>
+
+<ul>
+<li>The <strong>binder</strong> throughput test is in
+<code>system/libhwbinder/vts/performance/Benchmark_binder.cpp</code>.</li>
+<li>The <strong>hwbinder</strong> throughput test is in
+<code>system/libhwbinder/vts/performance/Benchmark.cpp</code>.</li>
+</ul>
+
+<h3 id=throughput-results>Test results</h3>
+<p>Example throughput test results for transactions using different payload
+sizes:</p>
+
+<pre class="prettyprint">
+Benchmark Time CPU Iterations
+---------------------------------------------------------------------
+BM_sendVec_binderize/4 70302 ns 32820 ns 21054
+BM_sendVec_binderize/8 69974 ns 32700 ns 21296
+BM_sendVec_binderize/16 70079 ns 32750 ns 21365
+BM_sendVec_binderize/32 69907 ns 32686 ns 21310
+BM_sendVec_binderize/64 70338 ns 32810 ns 21398
+BM_sendVec_binderize/128 70012 ns 32768 ns 21377
+BM_sendVec_binderize/256 69836 ns 32740 ns 21329
+BM_sendVec_binderize/512 69986 ns 32830 ns 21296
+BM_sendVec_binderize/1024 69714 ns 32757 ns 21319
+BM_sendVec_binderize/2k 75002 ns 34520 ns 20305
+BM_sendVec_binderize/4k 81955 ns 39116 ns 17895
+BM_sendVec_binderize/8k 95316 ns 45710 ns 15350
+BM_sendVec_binderize/16k 112751 ns 54417 ns 12679
+BM_sendVec_binderize/32k 146642 ns 71339 ns 9901
+BM_sendVec_binderize/64k 214796 ns 104665 ns 6495
+</pre>
+
+<ul>
+<li><strong>Time</strong> indicates the round trip delay measured in real time.
+</li>
+<li><strong>CPU</strong> indicates the accumulated time when CPUs are scheduled
+for the test.</li>
+<li><strong>Iterations</strong> indicates the number of times the test function
+executed.</li>
+</ul>
+
+<p>For example, for an 8-byte payload:</p>
+
+<pre class="prettyprint">
+BM_sendVec_binderize/8 69974 ns 32700 ns 21296
+</pre>
+<p>… the maximum throughput the binder can achieve is calculated as:</p>
+<p><em>MAX throughput with 8-byte payload = (8 * 21296)/69974 ~= 2.423 b/ns ~=
+2.268 Gb/s</em></p>
+
+<h3 id=throughput-options>Test options</h3>
+<p>To get results in .json, run the test with the
+<code>--benchmark_format=json</code> argument:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">libhwbinder_benchmark --benchmark_format=json</code>
+{
+ "context": {
+ "date": "2017-05-17 08:32:47",
+ "num_cpus": 4,
+ "mhz_per_cpu": 19,
+ "cpu_scaling_enabled": true,
+ "library_build_type": "release"
+ },
+ "benchmarks": [
+ {
+ "name": "BM_sendVec_binderize/4",
+ "iterations": 32342,
+ "real_time": 47809,
+ "cpu_time": 21906,
+ "time_unit": "ns"
+ },
+ ….
+}
+</pre>
+
+<h2 id=latency>Running latency tests</h2>
+<p>The latency test measures the time it takes for the client to begin
+initializing the transaction, switch to the server process for handling, and
+receive the result. The test also looks for known bad scheduler behaviors that
+can negatively impact transaction latency, such as a scheduler that does not
+support priority inheritance or honor the sync flag.</p>
+
+<ul>
+<li>The binder latency test is in
+<code>frameworks/native/libs/binder/tests/schd-dbg.cpp</code>.</li>
+<li>The hwbinder latency test is in
+<code>system/libhwbinder/vts/performance/Latency.cpp</code>.</li>
+</ul>
+
+<h3 id=latency-results>Test results</h3>
+<p>Results (in .json) show statistics for average/best/worst latency and the
+number of deadlines missed.</p>
+
+<h3 id=latency-options>Test options</h3>
+<p>Latency tests take the following options:</p>
+
+<table>
+<tr>
+<th>Command</th>
+<th>Description</th>
+</tr>
+
+<tr>
+<td><code>-i <em>value</em></code></td>
+<td>Specify number of iterations.</td>
+</tr>
+
+<tr>
+<td><code>-pair <em>value</em></code></td>
+<td>Specify the number of process pairs.</td>
+</tr>
+
+<tr>
+<td><code>-deadline_us 2500</code></td>
+<td>Specify the deadline in us.</td>
+</tr>
+
+<tr>
+<td><code>-v</code></td>
+<td>Get verbose (debugging) output.</td>
+</tr>
+
+<tr>
+<td><code>-trace</code></td>
+<td>Halt the trace on a deadline hit.</td>
+</tr>
+
+</table>
+
+<p>The following sections detail each option, describe usage, and provide
+example results.</p>
+
+<h4 id=iterations>Specifying iterations</h4>
+<p>Example with a large number of iterations and verbose output disabled:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">libhwbinder_latency -i 5000 -pair 3</code>
+{
+"cfg":{"pair":3,"iterations":5000,"deadline_us":2500},
+"P0":{"SYNC":"GOOD","S":9352,"I":10000,"R":0.9352,
+ "other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996},
+ "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
+},
+"P1":{"SYNC":"GOOD","S":9334,"I":10000,"R":0.9334,
+ "other_ms":{ "avg":0.19, "wst":2.9 , "bst":0.055, "miss":2, "meetR":0.9996},
+ "fifo_ms": { "avg":0.16, "wst":3.1 , "bst":0.066, "miss":1, "meetR":0.9998}
+},
+"P2":{"SYNC":"GOOD","S":9369,"I":10000,"R":0.9369,
+ "other_ms":{ "avg":0.19, "wst":4.8 , "bst":0.055, "miss":6, "meetR":0.9988},
+ "fifo_ms": { "avg":0.15, "wst":1.8 , "bst":0.067, "miss":0, "meetR":1}
+},
+"inheritance": "PASS"
+}
+</pre>
+<p>These test results show the following:</p>
+
+<dl>
+<dt><strong><code>"pair":3</code></strong></dt>
+<dd>Creates one client and server pair.</dd>
+
+<dt><strong><code>"iterations": 5000</code></strong></dt>
+<dd>Includes 5000 iterations.</dd>
+
+<dt><strong><code>"deadline_us":2500</code></strong></dt>
+<dd>Deadline is 2500us (2.5ms); most transactions are expected to meet this
+value.</dd>
+
+<dt><strong><code>"I": 10000</code></strong></dt>
+<dd>A single test iteration includes two (2) transactions:
+<ul>
+ <li>One transaction by normal priority (<code>CFS other</code>)</li>
+ <li>One transaction by real time priority (<code>RT-fifo</code>)</li>
+</ul>
+5000 iterations equals a total of 10000 transactions.</dd>
+
+<dt><strong><code>"S": 9352</code></strong></dt>
+<dd>9352 of the transactions are synced in the same CPU.</dd>
+
+<dt><strong><code>"R": 0.9352</code></strong></dt>
+<dd>Indicates the ratio at which the client and server are synced together in
+the same CPU.</dd>
+
+<dt><strong><code>"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2,
+"meetR":0.9996}</code></strong></dt>
+<dd>The average (<code>avg</code>), worst (<code>wst</code>), and the best
+(<code>bst</code>) case for all transactions issued by a normal priority caller.
+Two transactions <code>miss</code> the deadline, making the meet ratio
+(<code>meetR</code>) 0.9996.</dd>
+
+<dt><strong><code>"fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0,
+"meetR":1}</code></strong></dt>
+<dd>Similar to <code>other_ms</code>, but for transactions issued by client with
+<code>rt_fifo</code> priority. It's likely (but not required) that the
+<code>fifo_ms</code> has a better result than <code>other_ms</code>, with lower
+<code>avg</code> and <code>wst</code> values and a higher <code>meetR</code>
+(the difference can be even more significant with load in the background).</dd>
+
+</dl>
+
+<p class="note"><strong>Note:</strong> Background load may impact the throughput
+result and the <code>other_ms</code> tuple in the latency test. Only the
+<code>fifo_ms</code> may show similar results as long as the background load has
+a lower priority than <code>RT-fifo</code>.</p>
+
+<h4 id=pair-values>Specifying pair values</h4>
+<p>Each client process is paired with a server process dedicated for the client,
+and each pair may be scheduled independently to any CPU. However, the CPU
+migration should not happen during a transaction as long as the SYNC flag is
+<code>honor</code>.</p>
+
+<p>Ensure the system is not overloaded! While high latency in an overloaded
+system is expected, test results for an overloaded system do not provide useful
+information. To test a system with higher pressure, use <code>-pair
+#cpu-1</code> (or <code>-pair #cpu</code> with caution). Testing using
+<code>-pair <em>n</em></code> with <code><em>n</em> > #cpu</code> overloads the
+system and generates useless information.</p>
+
+<h4 id=deadline-values>Specifying deadline values</h4>
+<p>After extensive user scenario testing (running the latency test on a
+qualified product), we determined that 2.5ms is the deadline to meet. For new
+applications with higher requirements (such as 1000 photos/second), this
+deadline value will change.</p>
+
+<h4 id=verbose>Specifying verbose output</h4>
+<p>Using the <code>-v</code> option displays verbose output. Example:</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">libhwbinder_latency -i 1 -v</code>
+
+<div style="color: orange">--------------------------------------------------
+service pid: 8674 tid: 8674 cpu: 1
+SCHED_OTHER 0</div>
+--------------------------------------------------
+main pid: 8673 tid: 8673 cpu: 1
+
+--------------------------------------------------
+client pid: 8677 tid: 8677 cpu: 0
+SCHED_OTHER 0
+
+<div style="color: blue">--------------------------------------------------
+fifo-caller pid: 8677 tid: 8678 cpu: 0
+SCHED_FIFO 99
+
+--------------------------------------------------
+hwbinder pid: 8674 tid: 8676 cpu: 0
+??? 99</div>
+<div style="color: green">--------------------------------------------------
+other-caller pid: 8677 tid: 8677 cpu: 0
+SCHED_OTHER 0
+
+--------------------------------------------------
+hwbinder pid: 8674 tid: 8676 cpu: 0
+SCHED_OTHER 0</div>
+</pre>
+
+<ul>
+<li>The <font style="color:orange">service thread</font> is created with a
+<code>SCHED_OTHER</code> priority and run in <code>CPU:1</code> with <code>pid
+8674</code>.</li>
+<li>The <font style="color:blue">first transaction</font> is then started by a
+<code>fifo-caller</code>. To service this transaction, the hwbinder upgrades the
+priority of server (<code>pid: 8674 tid: 8676</code>) to be 99 and also marks it
+with a transient scheduling class (printed as <code>???</code>). The scheduler
+then puts the server process in <code>CPU:0</code> to run and syncs it with the
+same CPU with its client.</li>
+<li>The <font style="color:green">second transaction</font> caller has a
+<code>SCHED_OTHER</code> priority. The server downgrades itself and services the
+caller with <code>SCHED_OTHER</code> priority.</li>
+</ul>
+
+<h4 id=trace>Using trace for debugging</h4>
+<p>You can specify the <code>-trace</code> option to debug latency issues. When
+used, the latency test stops the tracelog recording at the moment when bad
+latency is detected. Example:</p>
+
+<pre class="prettyprint">
+<code class="devsite-terminal">atrace --async_start -b 8000 -c sched idle workq binder_driver sync freq</code>
+<code class="devsite-terminal">libhwbinder_latency -deadline_us 50000 -trace -i 50000 -pair 3</code>
+deadline triggered: halt &mp; stop trace
+log:/sys/kernel/debug/tracing/trace
+</pre>
+
+<p>The following components can impact latency:</p>
+
+<ul>
+<li><strong>Android build mode</strong>. Eng mode is usually slower than
+userdebug mode.</li>
+<li><strong>Framework</strong>. How does the framework service use
+<code>ioctl</code> to config to the binder?</li>
+<li><strong>Binder driver</strong>. Does the driver support fine-grained
+locking? Does the driver contain all performance turning patches?
+<li><strong>Kernel version</strong>. The better real time capability the kernel
+has, the better the results.</li>
+<li><strong>Kernel config</strong>. Does the kernel config contain
+<code>DEBUG</code> configs such as <code>DEBUG_PREEMPT</code> and
+<code>DEBUG_SPIN_LOCK</code>?</li>
+<li><strong>Kernel scheduler</strong>. Does the kernel have an Energy-Aware
+scheduler (EAS) or Heterogeneous Multi-Processing (HMP) scheduler? Are there
+kernel drivers (<code>cpu-freq</code> driver, <code>cpu-idle</code> driver,
+<code>cpu-hotplug</code>, etc.) that impact the scheduler?</li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/tech/vts/setup.html b/en/devices/tech/vts/setup.html
new file mode 100644
index 00000000..79bc79d7
--- /dev/null
+++ b/en/devices/tech/vts/setup.html
@@ -0,0 +1,198 @@
+<html devsite>
+ <head>
+ <title>VTS Dashboard Setup</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>
+The VTS Dashboard provides a user backend and user interface for viewing test
+results from the VTS continuous integration system. It supports test-driven
+development with tools such as test status notifications to help developers to
+locate and prevent regression areas during the development cycle (include test
+monitoring and
+triaging support).
+</p>
+
+<p>
+The user interface supports new features (such as native code coverage) provided
+by the VTS infrastructure and enables the development of tools with optimized
+and well-characterized performance by offering continuous performance
+monitoring.
+</p>
+
+<h2 id=requirements>Requirements</h2>
+<p>
+The following services are required to use the VTS Dashboard:
+</p>
+<ul>
+<li><a href="https://maven.apache.org/">Apache Maven</a>, for building and
+deployment</li>
+<li><a href="https://cloud.google.com/appengine">Google Cloud App Engine</a>,
+for web-service hosting</li>
+<li><a href="https://cloud.google.com/datastore/docs/">Google Cloud
+Datastore</a>, for storage</li>
+<li><a href="http://www.stackdriver.com/">Google Stackdriver</a>, for
+monitoring</li>
+</ul>
+
+<p>
+Viewing <a href="/devices/architecture/testing/ui.html#coverage">test
+coverage</a> relies on a REST API to a source code server (e.g. Gerrit), which
+enables the web service to fetch original source code according to existing
+access control lists.
+</p>
+
+<h2 id=arch>Architecture</h2>
+<p>
+The VTS Dashboard uses the following architecture:
+</p>
+<img src="../images/treble_vts_dash_arch.png" title="VTS Dashboard Architecture">
+<figcaption><strong>Figure 1</strong>. VTS Dashboard architecture.</figcaption>
+
+<p>
+Test status results are continuously uploaded to the Cloud Datastore database
+via a REST interface. The VTS runner automatically processes the results and
+serializes them using the Protobuf format.
+</p>
+<p>
+Web servlets form the primary access point for users, delivering and processing
+data from the Datastore database. The servlets include: a main servlet for
+delivering all of the tests, a preferences servlet for managing user favorites,
+a results servlet for populating a test table, a graph servlet for preparing
+profiling data, and a coverage servlet for preparing coverage data for the
+client.
+</p>
+<p>
+Each test module has its own Datastore ancestry tree and test results are
+indexed with the Unix timestamp of the test start time. Coverage data in the
+database is stored with the test results as a vector of counts (i.e. for each
+line in the original source file) and identifying information to fetch the
+source code from a source code server.
+</p>
+<p>
+The notification service runs using task queues, identifying test case status
+changes, and notifying subscribers. Stateful information is stored in a status
+table to keep track of data freshness and existing failures. This allows for the
+notification service to provide rich information about individual test case
+failures and fixes.
+</p>
+
+<h2 id=code-structure>Code structure</h2>
+<p>
+VTS Dashboard essential components include the servlets implemented in Java,
+the front-end JSPs, CSS stylesheets, and configuration files. The following list
+details the locations and descriptions of these components (all paths relative
+to <code>test/vts/web/dashboard</code>):
+</p>
+<ul>
+<li><code>pom.xml</code><br>Settings file where environment variables and
+dependencies are defined.</li>
+<li><code>src/main/java/com/android/vts/api/</code><br>Contains endpoints for
+interacting with the data via REST.</li>
+<li><code>src/main/java/com/android/vts/entity/</code><br>Contains Java models
+of the Datastore entities.</li>
+<li><code>src/main/java/com/android/vts/proto/</code><br>Contains Java files
+for Protobuf, including <code>VtsReportMessage.java</code>, which is a Java
+implementation of Protobuf type used to describe VTS test results.</li>
+<li><code>src/main/java/com/android/vts/servlet/</code><br>Contains Java
+files for servlets.</li>
+<li><code>src/main/java/com/android/vts/util/</code><br>Contains Java files
+for utility functions and classes used by the servlets.</li>
+<li><code>src/test/java/com/android/vts/</code><br>Contains UI tests for the
+servlets and utils.</li>
+<li><code>src/main/webapp/</code><br>Contains files related to the UI (JSP,
+CSS, XML):
+ <ul>
+ <li><code>js/</code>. Contains Javascript files used by the web pages.</li>
+ <li><code>WEB-INF/</code>. Contains configuration and UI files.</li>
+ <li><code>jsp/</code>. Contains the JSP files for each web page.</li>
+ </ul>
+</li>
+<li><code>appengine-web.xml</code><br>Settings file where environment
+variables are loaded into variables.</li>
+<li><code>web.xml</code><br>Settings file where servlet mappings and
+security constraints are defined.</li>
+<li><code>cron.xml</code><br>Settings file defining scheduled tasks (i.e.
+the notifications service).</li>
+</ul>
+
+<h2 id=setup>Setting up the Dashboard</h2>
+<p>
+To set up the VTS Dashboard:
+</p>
+<ol>
+<li>Create a Google Cloud App Engine Project.</li>
+<li>Set up the deployment host by installing:
+ <ul>
+ <li>Java 8</li>
+ <li>Google App Engine SDK</li>
+ <li>Maven</li>
+ </ul>
+</li>
+<li>Generate an OAuth 2.0 Client ID in the Google Cloud API Manager.</li>
+<li>Create a Service Account and create a keyfile.</li>
+<li>Add an email address to the App Engine Email API Authorized Senders List.</li>
+<li>Set up a Google Analytics Account.</li>
+<li>Specify environment variables in the Dashboard <code>pom.xml</code>:
+ <ul>
+ <li>Set the client ID with the OAuth 2.0 ID (from step 3).</li>
+ <li>Set the service client ID with the identifier included in the keyfile (from
+ step 4).</li>
+ <li>Specify the sender email address for alerts (from step 5).</li>
+ <li>Specify an email domain to which all emails will be sent.</li>
+ <li>Specify the address to the Gerrit REST server.</li>
+ <li>Specify the OAuth 2.0 scope to use for the Gerrit REST server.</li>
+ <li>Specify the Google Analytics ID (from step 6).</li>
+ <li>Build and deploy the project.</li>
+ </ul>
+</li>
+<li>In a terminal, run <code>mvn clean appengine:update</code></li>
+</ol>
+
+<p>
+For more information regarding Dashboard setup and configuration, refer to the
+<a href="https://codelabs.developers.google.com/codelabs/android-vts">Android
+VTS Code Lab</a>.
+</p>
+
+<h2 id=security>Security considerations</h2>
+<p>
+Robust coverage information requires access to the original source code.
+However, some code may be sensitive and an additional gateway to it may allow
+for exploitation of existing access control lists.
+</p>
+<p>
+To avoid this threat, instead of serving the source code with the coverage
+information, the Dashboard directly handles a coverage vector (i.e., a vector of
+execution counts mapping to the lines in a source file). Along with the coverage
+vector, the Dashboard receives a Git project name and path so that the client
+can fetch the code from an external source code API. The client browser receives
+this information and uses cross-origin resource sharing (CORS) in Javascript to
+query the source code server for the original source code; the resulting code is
+combined with the coverage vector to produce a display.
+</p>
+<p>
+This approach does not widen the attack surface because the Dashboard uses the
+user's cookies to authenticate with an outside service. A user who cannot access
+source code directly cannot exploit the Dashboard to view sensitive information.
+</p>
+
+ </body>
+</html>
diff --git a/en/devices/tech/vts/ui.html b/en/devices/tech/vts/ui.html
new file mode 100644
index 00000000..775ab372
--- /dev/null
+++ b/en/devices/tech/vts/ui.html
@@ -0,0 +1,161 @@
+<html devsite>
+ <head>
+ <title>VTS Dashboard UI</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>
+The VTS Dashboard provides a cohesive user interface that uses material design
+to effectively display information about test results, profiling, and coverage.
+Dashboard styling uses open-source Javascript libraries including Materialize
+CSS and jQueryUI to process data delivered by Java servlets in Google App
+Engine.
+</p>
+
+<h2>Dashboard home</h2>
+<p>
+The Dashboard home page displays a list of test suites a user has added to
+favorites.
+</p>
+<img src="../images/treble_vts_ui_main.png" title="VTS Dashboard landing page">
+<figcaption><strong>Figure 1.</strong> VTS Dashboard, home page.</figcaption>
+
+<p>
+From this list, users can:
+</p>
+<ul>
+<li>Select a test suite to view results for that suite.
+<li>Click <strong>SHOW ALL</strong> to view all VTS test names.
+<li>Select the <strong>Edit</strong> icon to modify the Favorites list.
+<img src="../images/treble_vts_ui_favorites.png" title="VTS Dashboard favorites">
+<figcaption><strong>Figure 2.</strong> VTS Dashboard, editing Favorites
+page.</figcaption></li>
+</ul>
+
+<h2 id=test-results>Test results</h2>
+<p>
+Test Results displays the latest information about the selected test suite,
+including a list of profiling points, a table of test case results in
+chronological order, and a pie chart displaying the result breakdown of the
+latest run (users can load older data by paging right).
+</p>
+
+<img src="../images/treble_vts_ui_results.png" title="VTS Dashboard results">
+<figcaption><strong>Figure 3.</strong> VTS Dashboard, test results.</figcaption>
+
+<p>
+Users can filter data using queries or by modifying the test type (pre-submit,
+post-submit, or both). Search queries support general tokens and field-specific
+qualifiers; supported search fields are: device build ID, branch, target name,
+device name, and test build ID. These are specified in the format:
+<var>FIELD-ID</var>="<var>SEARCH QUERY</var>". Quotes are used to treat multiple
+words as a single token to match with the data in the columns.
+</p>
+
+<h2 id=profiling>Data profiling</h2>
+<p>
+Users can select a profiling point to reach an interactive view of the
+quantitative data for that point in a <strong>line graph</strong> or
+<strong>histogram</strong> (examples below). By default, the view displays the
+latest information; users can use the date picker to load specific time windows.
+</p>
+<img src="../images/treble_vts_ui_performance.png" title="VTS Dashboard performance">
+<figcaption><strong>Figure 4.</strong> VTS Dashboard, line graph performance.
+</figcaption>
+<p>
+Line graphs display data from a collection of unordered performance values,
+which can be useful when a test of performance produces a vector of performance
+values that vary as a function of another variable (e.g., throughput versus
+message size).
+</p>
+<img src="../images/treble_vts_ui_histogram.png" title="VTS Dashboard histogram">
+<figcaption><strong>Figure 5.</strong> VTS Dashboard, histogram performance.</figcaption>
+
+<h2 id=coverage>Test coverage</h2>
+<p>
+Users can view coverage information from the coverage percent link in test
+results.
+<img src="../images/treble_vts_ui_coverage.png" title="VTS Dashboard coverage">
+<figcaption>
+<strong>Figure 6.</strong> VTS Dashboard, coverage percentages.</figcaption>
+
+<p>
+For each test case and source file, users can view an expandable element
+containing color-coded source code according to the coverage provided by the
+selected test:
+</p>
+<img src="../images/treble_vts_ui_coverage_source.png" title="VTS Dashboard coverage_source">
+<figcaption>
+<strong>Figure 7.</strong> VTS Dashboard, coverage source code.</figcaption>
+
+<ul>
+<li>Uncovered lines are highlighted <font style="color:red">red</font>.</li>
+<li>Covered lines are highlighted <font style="color:green">green</font>.</li>
+<li>Non-executable lines are <strong>uncolored</strong>.</li>
+</ul>
+
+<p>
+Coverage information is grouped depending into sections depending on how it was
+provided at run-time. Tests may upload coverage:
+</p>
+<ul>
+<li><strong>Per function</strong>. Section headers have the format "Coverage:
+<var>FUNCTION-NAME</var>".</li>
+<li><strong>In Total</strong> (provided at the end of the test run). Only one
+header is present: "Coverage: All".</li>
+</ul>
+
+<p>
+The Dashboard fetches source code client-side from a server, which uses the
+open-source
+<a href="https://gerrit-review.googlesource.com/Documentation/rest-api.html">Gerrit
+REST API</a>.
+</p>
+
+<h2 id=monitor>Monitoring &amp; testing</h2>
+<p>
+The VTS Dashboard provides the following monitors and unit tests.
+</p>
+<ul>
+<li><strong>Test email alerts</strong>. Alerts are configured in a Cron job that
+executes at a fixed interval of two (2) minutes. The job reads the VTS status
+table to determine if new data has been uploaded to each table, done by checking
+the test's raw data upload timestamp is newer than the last status update
+timestamp. If the upload timestamp is newer, the job queries for new data
+between now and the last raw data upload. New test case failures, continued test
+case failures, transient test case failures, test case fixes, an inactive tests
+are determined; this information is then sent in email format to the subscribers
+of each test.</li>
+<li><strong>Web service health</strong>. Google Stackdriver integrates with
+Google App Engine to provide easy monitoring of the VTS Dashboard. Simple uptime
+checks verify pages can be accessed while other tests can be created to verify
+latency on each page, servlet, or database. These checks ensure the Dashboard is
+always accessible (else an administrator will be notified).</li>
+<li><strong>Analytics</strong>. Each page on the VTS Dashboard supports
+integration with Google Cloud Analytics, provided that an Analytics ID is
+specified in the configuration. This provides more robust analysis of page
+usage, user interaction, locality, session statistics, etc. By simply providing
+the valid ID in the pom.xml file, analytics are automatically
+provided.</li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/reference/_toc.yaml b/en/reference/_toc.yaml
index ce976d22..e968aba4 100644
--- a/en/reference/_toc.yaml
+++ b/en/reference/_toc.yaml
@@ -1,27 +1,9 @@
toc:
-- title: API Reference
+- title: Reference
path: /reference/
-- title: Hardware Abstraction Layer
- style: accordion
- section:
- - title: Overview
- path: /reference/hal/
- - title: Data Structures
- path: /reference/hal/annotated
- - title: Data Structure Index
- path: /reference/hal/classes
- - title: Data Fields
- path: /reference/hal/functions
- - title: File List
- path: /reference/hal/files
- - title: Globals
- path: /reference/hal/globals
- - title: Deprecated
- path: /reference/hal/deprecated
+- title: HIDL
+ path: /reference/hidl/
+- title: Hardware Abstraction Layer (legacy)
+ path: /reference/hal/
- title: Trade Federation
- style: accordion
- section:
- - title: Class Index
- path: /reference/tradefed/classes
- - title: Package Index
- path: /reference/tradefed/packages
+ path: /reference/tradefed/
diff --git a/en/reference/index.html b/en/reference/index.html
index ab1071df..29f1a279 100644
--- a/en/reference/index.html
+++ b/en/reference/index.html
@@ -3,15 +3,35 @@
<title>Reference</title>
<meta name="project_path" value="/_project.yaml">
<meta name="book_path" value="/_book.yaml">
+ <meta name="full_width" value="true">
<meta name="hide_page_heading" value="true">
<meta name="hide_last_updated" value="true">
<link rel="stylesheet" href="/reference/assets/css/landing.css">
</head>
<body>
<section class="sac-landing-row sac-landing-row-2-up">
- <h2 id="api-documentation" class="hide-from-toc">API Reference</h2>
<div class="sac-landing-row-column">
- <div class="sac-landing-row-item sac-landing-row-item-no-image">
+
+ <div class="sac-landing-row-item sac-landing-row-item-no-image"><!--item begin-->
+ <a href="/reference/hidl/">
+ <div class="sac-landing-row-item-icon-container">
+ <div class="sac-landing-row-item-icon-white material-icons">settings_input_component</div>
+ </div>
+ </a>
+ <div class="sac-landing-row-item-description sac-landing-row-item-icon-description">
+ <a href="/reference/hidl/">
+ <h3 id="hidl" class="hide-from-toc">HIDL</h3>
+ </a>
+ The HAL Interface Description Language (HIDL) specifies the
+ interface between a HAL and its users. It defines types and method
+ calls, collected into interfaces and packages. HIDL is a system for
+ communicating between codebases that may be compiled independently
+ and is intended for inter-process communication. See the
+ <a href="/devices/architecture/hidl">HIDL guides</a>.
+ </div>
+ </div><!--item end-->
+
+ <div class="sac-landing-row-item sac-landing-row-item-no-image"><!--item begin-->
<a href="/reference/hal/">
<div class="sac-landing-row-item-icon-container">
<div class="sac-landing-row-item-icon-white material-icons">developer_board</div>
@@ -19,30 +39,36 @@
</a>
<div class="sac-landing-row-item-description sac-landing-row-item-icon-description">
<a href="/reference/hal/">
- <h3 id="hardware-abstraction-layer" class="hide-from-toc">Hardware Abstraction Layer</h3>
+ <h3 id="hardware-abstraction-layer" class="hide-from-toc">Hardware Abstraction Layer (legacy)</h3>
</a>
- Android gives you the freedom to implement your own device
- specifications and drivers. The hardware abstraction layer (HAL) provides
- a standard method for creating software hooks between the Android
- platform stack and your hardware.
+ A HAL defines a standard interface for hardware vendors to implement,
+ which enables Android to be agnostic about lower-level driver
+ implementations. Using a HAL allows you to implement functionality
+ without affecting or modifying the higher level system. For an
+ overview, see the <a href="/devices/architecture/hal">HAL guide</a>.
</div>
- </div><!--/sac-landing-row-item-->
+ </div><!--item end-->
+
</div><!--newline here breaks formatting--><div class="sac-landing-row-column">
- <div class="sac-landing-row-item sac-landing-row-item-no-image">
- <a href="/devices/tech/test_infra/tradefed/">
+
+ <div class="sac-landing-row-item sac-landing-row-item-no-image"><!--item begin-->
+ <a href="/reference/tradefed/classes">
<div class="sac-landing-row-item-icon-container">
<div class="sac-landing-row-item-icon-white material-icons">developer_mode</div>
</div>
</a>
<div class="sac-landing-row-item-description sac-landing-row-item-icon-description">
- <a href="/devices/tech/test_infra/tradefed/">
+ <a href="/reference/tradefed/classes">
<h3 id="trade-federation" class="hide-from-toc">Trade Federation</h3>
</a>
A continuous test framework designed for running tests on Android
devices. It's a Java application which runs on a host computer, and
communicates to one or more Android devices using ddmlib over adb.
+ For details, see the
+ <a href="/devices/tech/test_infra/tradefed/">Trade Federation Overview</a>.
</div>
- </div><!--/sac-landing-row-item-->
+ </div><!--item end-->
+
</div>
</section>
</body>
diff --git a/en/security/_toc.yaml b/en/security/_toc.yaml
index 2d20e410..f7dbdf22 100644
--- a/en/security/_toc.yaml
+++ b/en/security/_toc.yaml
@@ -117,7 +117,13 @@ toc:
path: /security/keystore/
- title: Features
path: /security/keystore/features
- - title: Implementer's Reference
+ - title: Key Attestation
+ path: /security/keystore/attestation
+ - title: Version Binding
+ path: /security/keystore/version-binding
+ - title: Authorization Tags
+ path: /security/keystore/tags
+ - title: Functions
path: /security/keystore/implementer-ref
- title: Trusty TEE
section:
diff --git a/en/security/bulletin/2017-04-01.html b/en/security/bulletin/2017-04-01.html
index e80bb6ed..dcbc4303 100644
--- a/en/security/bulletin/2017-04-01.html
+++ b/en/security/bulletin/2017-04-01.html
@@ -20,7 +20,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<p><em>Published April 03, 2017 | Updated April 27, 2017</em></p>
+<p><em>Published April 03, 2017 | Updated August 17, 2017</em></p>
<p>The Android Security Bulletin contains details of security vulnerabilities
affecting Android devices. Alongside the bulletin, we have released a security
update to Nexus devices through an over-the-air (OTA) update. The Google device
@@ -2445,136 +2445,119 @@ patch level. </p>
</tr>
<tr>
<td>CVE-2014-9931</td>
- <td>A-35445101**<br>
- QC-CR#612410</td>
+ <td>A-35445101**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9932</td>
- <td>A-35434683**<br>
- QC-CR#626734</td>
+ <td>A-35434683**</td>
<td>Critical</td>
<td>Pixel, Pixel XL</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9933</td>
- <td>A-35442512<br>
- QC-CR#675463</td>
+ <td>A-35442512**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9934</td>
- <td>A-35439275**<br>
- QC-CR#658249</td>
+ <td>A-35439275**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9935</td>
- <td>A-35444951**<br>
- QC-CR#717626</td>
+ <td>A-35444951**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9936</td>
- <td>A-35442420**<br>
- QC-CR#727389</td>
+ <td>A-35442420**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9937</td>
- <td>A-35445102**<br>
- QC-CR#734095</td>
+ <td>A-35445102**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-8995</td>
- <td>A-35445002**<br>
- QC-CR#733690</td>
+ <td>A-35445002**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-8996</td>
- <td>A-35444658**<br>
- QC-CR#734698</td>
+ <td>A-35444658**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-8997</td>
- <td>A-35432947**<br>
- QC-CR#734707</td>
+ <td>A-35432947**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-8998</td>
- <td>A-35441175**<br>
- QC-CR#735337</td>
+ <td>A-35441175**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-8999</td>
- <td>A-35445401**<br>
- QC-CR#736119</td>
+ <td>A-35445401**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9000</td>
- <td>A-35441076**<br>
- QC-CR#740632</td>
+ <td>A-35441076**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9001</td>
- <td>A-35445400**<br>
- QC-CR#736083</td>
+ <td>A-35445400**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9002</td>
- <td>A-35442421**<br>
- QC-CR#748428</td>
+ <td>A-35442421**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9003</td>
- <td>A-35440626**<br>
- QC-CR#749215</td>
+ <td>A-35440626**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2016-10242</td>
- <td>A-35434643**<br>
- QC-CR#985139</td>
+ <td>A-35434643**</td>
<td>Critical</td>
<td>None**</td>
<td>Qualcomm internal</td>
@@ -2682,6 +2665,7 @@ belongs. These prefixes map as follows:</p>
<li>April 05, 2017: Bulletin revised to include AOSP links.</li>
<li>April 21, 2017: Attribution for CVE-2016-10231 and CVE-2017-0586 corrected.</li>
<li>April 27, 2017: CVE-2017-0540 removed from bulletin.</li>
+ <li>August 17, 2017: Bulletin revised to update reference numbers.</li>
</ul>
</body>
diff --git a/en/security/bulletin/2017-05-01.html b/en/security/bulletin/2017-05-01.html
index 1e5ce812..c92e4ffd 100644
--- a/en/security/bulletin/2017-05-01.html
+++ b/en/security/bulletin/2017-05-01.html
@@ -22,7 +22,7 @@
-->
-<p><em>Published May 01, 2017 | Updated August 10, 2017</em></p>
+<p><em>Published May 01, 2017 | Updated August 17, 2017</em></p>
<p>The Android Security Bulletin contains details of security vulnerabilities
affecting Android devices. Alongside the bulletin, we have released a security
@@ -2774,48 +2774,42 @@ patch level.</p>
</tr>
<tr>
<td>CVE-2014-9923</td>
- <td>A-35434045**<br>
- QC-CR#403910</td>
+ <td>A-35434045**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9924</td>
- <td>A-35434631**<br>
- QC-CR#596102</td>
+ <td>A-35434631**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9925</td>
- <td>A-35444657**<br>
- QC-CR#638130</td>
+ <td>A-35444657**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9926</td>
- <td>A-35433784**<br>
- QC-CR#631527</td>
+ <td>A-35433784**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9927</td>
- <td>A-35433785**<br>
- QC-CR#661111</td>
+ <td>A-35433785**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9928</td>
- <td>A-35438623**<br>
- QC-CR#696972</td>
+ <td>A-35438623**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
@@ -2830,136 +2824,119 @@ patch level.</p>
</tr>
<tr>
<td>CVE-2014-9930</td>
- <td>A-35432946**<br>
- QC-CR#634637</td>
+ <td>A-35432946**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9005</td>
- <td>A-36393500**<br>
- QC-CR#741548</td>
+ <td>A-36393500**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9006</td>
- <td>A-36393450**<br>
- QC-CR#750559</td>
+ <td>A-36393450**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2015-9007</td>
- <td>A-36393700**<br>
- QC-CR#807173</td>
+ <td>A-36393700**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2016-10297</td>
- <td>A-36393451**<br>
- QC-CR#1061123</td>
+ <td>A-36393451**</td>
<td>Critical</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9941</td>
- <td>A-36385125**<br>
- QC-CR#509915</td>
+ <td>A-36385125**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9942</td>
- <td>A-36385319**<br>
- QC-CR#533283</td>
+ <td>A-36385319**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9943</td>
- <td>A-36385219**<br>
- QC-CR#546527</td>
+ <td>A-36385219**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9944</td>
- <td>A-36384534**<br>
- QC-CR#613175</td>
+ <td>A-36384534**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9945</td>
- <td>A-36386912**<br>
- QC-CR#623452</td>
+ <td>A-36386912**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9946</td>
- <td>A-36385281**<br>
- QC-CR#520149</td>
+ <td>A-36385281**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9947</td>
- <td>A-36392400**<br>
- QC-CR#650540</td>
+ <td>A-36392400**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9948</td>
- <td>A-36385126**<br>
- QC-CR#650500</td>
+ <td>A-36385126**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9949</td>
- <td>A-36390608**<br>
- QC-CR#652426</td>
+ <td>A-36390608**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9950</td>
- <td>A-36385321**<br>
- QC-CR#655530</td>
+ <td>A-36385321**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9951</td>
- <td>A-36389161**<br>
- QC-CR#525043</td>
+ <td>A-36389161**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
</tr>
<tr>
<td>CVE-2014-9952</td>
- <td>A-36387019**<br>
- QC-CR#674836</td>
+ <td>A-36387019**</td>
<td>High</td>
<td>None***</td>
<td>Qualcomm internal</td>
@@ -2968,7 +2945,7 @@ patch level.</p>
<p>* The severity rating for these vulnerabilities was determined by the vendor.</p>
-<p>* The patch for this issue is not publicly available. The update is contained
+<p>** The patch for this issue is not publicly available. The update is contained
in the latest binary drivers for Nexus devices available from the
<a href="https://developers.google.com/android/nexus/drivers">
Google Developer site</a>.</p>
@@ -3082,6 +3059,7 @@ belongs. These prefixes map as follows:</p>
<li>May 02, 2017: Bulletin revised to include AOSP links.</li>
<li>August 10, 2017: Bulletin revised to include additional AOSP link for
CVE-2017-0493.</li>
+<li>August 17, 2017: Bulletin revised to update reference numbers.</li>
</ul>
</body>
</html>
diff --git a/en/security/bulletin/2017-06-01.html b/en/security/bulletin/2017-06-01.html
index da3ff2ee..81f74ba5 100644
--- a/en/security/bulletin/2017-06-01.html
+++ b/en/security/bulletin/2017-06-01.html
@@ -20,7 +20,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<p><em>Published June 5, 2017 | Updated June 7, 2017</em></p>
+<p><em>Published June 5, 2017 | Updated August 17, 2017</em></p>
<p>The Android Security Bulletin contains details of security vulnerabilities
affecting Android devices. Security patch levels of June 05, 2017 or later
@@ -727,402 +727,350 @@ patch level. Fixes for these vulnerabilities are available directly from Qualcom
</tr>
<tr>
<td>CVE-2014-9960</td>
- <td>A-37280308<a href="#asterisk">*</a><br>
- QC-CR#381837</td>
+ <td>A-37280308<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9961</td>
- <td>A-37279724<a href="#asterisk">*</a><br>
- QC-CR#581093</td>
+ <td>A-37279724<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9953</td>
- <td>A-36714770<a href="#asterisk">*</a><br>
- QC-CR#642173</td>
+ <td>A-36714770<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9967</td>
- <td>A-37281466<a href="#asterisk">*</a><br>
- QC-CR#739110</td>
+ <td>A-37281466<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9026</td>
- <td>A-37277231<a href="#asterisk">*</a><br>
- QC-CR#748397</td>
+ <td>A-37277231<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9027</td>
- <td>A-37279124<a href="#asterisk">*</a><br>
- QC-CR#748407</td>
+ <td>A-37279124<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9008</td>
- <td>A-36384689<a href="#asterisk">*</a><br>
- QC-CR#762111</td>
+ <td>A-36384689<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9009</td>
- <td>A-36393600<a href="#asterisk">*</a><br>
- QC-CR#762182</td>
+ <td>A-36393600<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9010</td>
- <td>A-36393101<a href="#asterisk">*</a><br>
- QC-CR#758752</td>
+ <td>A-36393101<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9011</td>
- <td>A-36714882<a href="#asterisk">*</a><br>
- QC-CR#762167</td>
+ <td>A-36714882<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9024</td>
- <td>A-37265657<a href="#asterisk">*</a><br>
- QC-CR#740680</td>
+ <td>A-37265657<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9012</td>
- <td>A-36384691<a href="#asterisk">*</a><br>
- QC-CR#746617</td>
+ <td>A-36384691<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9013</td>
- <td>A-36393251<a href="#asterisk">*</a><br>
- QC-CR#814373</td>
+ <td>A-36393251<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9014</td>
- <td>A-36393750<a href="#asterisk">*</a><br>
- QC-CR#855220</td>
+ <td>A-36393750<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9015</td>
- <td>A-36714120<a href="#asterisk">*</a><br>
- QC-CR#701858</td>
+ <td>A-36714120<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9029</td>
- <td>A-37276981<a href="#asterisk">*</a><br>
- QC-CR#827837</td>
+ <td>A-37276981<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10338</td>
- <td>A-37277738<a href="#asterisk">*</a><br>
- QC-CR#987699</td>
+ <td>A-37277738<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10336</td>
- <td>A-37278436<a href="#asterisk">*</a><br>
- QC-CR#973605</td>
+ <td>A-37278436<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10333</td>
- <td>A-37280574<a href="#asterisk">*</a><br>
- QC-CR#947438</td>
+ <td>A-37280574<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10341</td>
- <td>A-37281667<a href="#asterisk">*</a><br>
- QC-CR#991476</td>
+ <td>A-37281667<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10335</td>
- <td>A-37282802<a href="#asterisk">*</a><br>
- QC-CR#961142</td>
+ <td>A-37282802<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10340</td>
- <td>A-37280614<a href="#asterisk">*</a><br>
- QC-CR#989028</td>
+ <td>A-37280614<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10334</td>
- <td>A-37280664<a href="#asterisk">*</a><br>
- QC-CR#949933</td>
+ <td>A-37280664<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10339</td>
- <td>A-37280575<a href="#asterisk">*</a><br>
- QC-CR#988502</td>
+ <td>A-37280575<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10298</td>
- <td>A-36393252<a href="#asterisk">*</a><br>
- QC-CR#1020465</td>
+ <td>A-36393252<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10299</td>
- <td>A-32577244<a href="#asterisk">*</a><br>
- QC-CR#1058511</td>
+ <td>A-32577244<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>Critical</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9954</td>
- <td>A-36388559<a href="#asterisk">*</a><br>
- QC-CR#552880</td>
+ <td>A-36388559<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9955</td>
- <td>A-36384686<a href="#asterisk">*</a><br>
- QC-CR#622701</td>
+ <td>A-36384686<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9956</td>
- <td>A-36389611<a href="#asterisk">*</a><br>
- QC-CR#638127</td>
+ <td>A-36389611<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9957</td>
- <td>A-36387564<a href="#asterisk">*</a><br>
- QC-CR#638984</td>
+ <td>A-36387564<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9958</td>
- <td>A-36384774<a href="#asterisk">*</a><br>
- QC-CR#638135</td>
+ <td>A-36384774<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9962</td>
- <td>A-37275888<a href="#asterisk">*</a><br>
- QC-CR#656267</td>
+ <td>A-37275888<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9963</td>
- <td>A-37276741<a href="#asterisk">*</a><br>
- QC-CR#657771</td>
+ <td>A-37276741<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9959</td>
- <td>A-36383694<a href="#asterisk">*</a><br>
- QC-CR#651900</td>
+ <td>A-36383694<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9964</td>
- <td>A-37280321<a href="#asterisk">*</a><br>
- QC-CR#680778</td>
+ <td>A-37280321<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9965</td>
- <td>A-37278233<a href="#asterisk">*</a><br>
- QC-CR#711585</td>
+ <td>A-37278233<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9966</td>
- <td>A-37282854<a href="#asterisk">*</a><br>
- QC-CR#727398</td>
+ <td>A-37282854<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9023</td>
- <td>A-37276138<a href="#asterisk">*</a><br>
- QC-CR#739802</td>
+ <td>A-37276138<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9020</td>
- <td>A-37276742<a href="#asterisk">*</a><br>
- QC-CR#733455</td>
+ <td>A-37276742<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9021</td>
- <td>A-37276743<a href="#asterisk">*</a><br>
- QC-CR#735148</td>
+ <td>A-37276743<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9025</td>
- <td>A-37276744<a href="#asterisk">*</a><br>
- QC-CR#743985</td>
+ <td>A-37276744<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9022</td>
- <td>A-37280226<a href="#asterisk">*</a><br>
- QC-CR#736146</td>
+ <td>A-37280226<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9028</td>
- <td>A-37277982<a href="#asterisk">*</a><br>
- QC-CR#762764</td>
+ <td>A-37277982<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9031</td>
- <td>A-37275889<a href="#asterisk">*</a><br>
- QC-CR#866015</td>
+ <td>A-37275889<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9032</td>
- <td>A-37279125<a href="#asterisk">*</a><br>
- QC-CR#873202</td>
+ <td>A-37279125<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9033</td>
- <td>A-37276139<a href="#asterisk">*</a><br>
- QC-CR#892541</td>
+ <td>A-37276139<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9030</td>
- <td>A-37282907<a href="#asterisk">*</a><br>
- QC-CR#854667</td>
+ <td>A-37282907<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10332</td>
- <td>A-37282801<a href="#asterisk">*</a><br>
- QC-CR#906713<br>
- QC-CR#917701<br>
- QC-CR#917702</td>
+ <td>A-37282801<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10337</td>
- <td>A-37280665<a href="#asterisk">*</a><br>
- QC-CR#977632</td>
+ <td>A-37280665<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10342</td>
- <td>A-37281763<a href="#asterisk">*</a><br>
- QC-CR#988941</td>
+ <td>A-37281763<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
<td>Closed-source component</td>
@@ -1413,6 +1361,11 @@ site</a>.</p>
<td>July 11, 2017</td>
<td>Bulletin revised to include CVE-2017-6249.</td>
</tr>
+ <tr>
+ <td>1.3</td>
+ <td>August 17, 2017</td>
+ <td>Bulletin revised to update reference numbers.</td>
+ </tr>
</table>
</body>
</html>
diff --git a/en/security/bulletin/2017-07-01.html b/en/security/bulletin/2017-07-01.html
index d03a6c71..0cfdf8a3 100644
--- a/en/security/bulletin/2017-07-01.html
+++ b/en/security/bulletin/2017-07-01.html
@@ -20,7 +20,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<p><em>Published July 5, 2017 | Updated July 6, 2017</em></p>
+<p><em>Published July 5, 2017 | Updated August 17, 2017</em></p>
<p>The Android Security Bulletin contains details of security vulnerabilities
affecting Android devices. Security patch levels of July 05, 2017 or later
@@ -1018,443 +1018,388 @@ from Qualcomm.</p>
</tr>
<tr>
<td>CVE-2014-9411</td>
- <td>A-37473054<a href="#asterisk">*</a><br>
- QC-CR#532956</td>
+ <td>A-37473054<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9968</td>
- <td>A-37304413<a href="#asterisk">*</a><br>
- QC-CR#642084</td>
+ <td>A-37304413<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9973</td>
- <td>A-37470982<a href="#asterisk">*</a><br>
- QC-CR#646919</td>
+ <td>A-37470982<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9974</td>
- <td>A-37471979<a href="#asterisk">*</a><br>
- QC-CR#654072</td>
+ <td>A-37471979<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9975</td>
- <td>A-37471230<a href="#asterisk">*</a><br>
- QC-CR#700125</td>
+ <td>A-37471230<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9977</td>
- <td>A-37471087<a href="#asterisk">*</a><br>
- QC-CR#703002</td>
+ <td>A-37471087<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9978</td>
- <td>A-37468982<a href="#asterisk">*</a><br>
- QC-CR#709939</td>
+ <td>A-37468982<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9979</td>
- <td>A-37471088<a href="#asterisk">*</a><br>
- QC-CR#717304</td>
+ <td>A-37471088<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2014-9980</td>
- <td>A-37471029<a href="#asterisk">*</a><br>
- QC-CR#709766</td>
+ <td>A-37471029<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-0575</td>
- <td>A-37296999<a href="#asterisk">*</a><br>
- QC-CR#715815</td>
+ <td>A-37296999<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-8592</td>
- <td>A-37470090<a href="#asterisk">*</a><br>
- QC-CR#775396</td>
+ <td>A-37470090<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Core</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-8595</td>
- <td>A-37472411<a href="#asterisk">*</a><br>
- QC-CR#790151</td>
+ <td>A-37472411<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-8596</td>
- <td>A-37472806<a href="#asterisk">*</a><br>
- QC-CR#802005</td>
+ <td>A-37472806<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9034</td>
- <td>A-37305706<a href="#asterisk">*</a><br>
- QC-CR#614512</td>
+ <td>A-37305706<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9035</td>
- <td>A-37303626<a href="#asterisk">*</a><br>
- QC-CR#750231</td>
+ <td>A-37303626<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9036</td>
- <td>A-37303519<a href="#asterisk">*</a><br>
- QC-CR#751831</td>
+ <td>A-37303519<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9037</td>
- <td>A-37304366<a href="#asterisk">*</a><br>
- QC-CR#753315</td>
+ <td>A-37304366<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9038</td>
- <td>A-37303027<a href="#asterisk">*</a><br>
- QC-CR#758328</td>
+ <td>A-37303027<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9039</td>
- <td>A-37302628<a href="#asterisk">*</a><br>
- QC-CR#760282</td>
+ <td>A-37302628<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9040</td>
- <td>A-37303625<a href="#asterisk">*</a><br>
- QC-CR#761216</td>
+ <td>A-37303625<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9041</td>
- <td>A-37303518<a href="#asterisk">*</a><br>
- QC-CR#762126</td>
+ <td>A-37303518<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9042</td>
- <td>A-37301248<a href="#asterisk">*</a><br>
- QC-CR#762214</td>
+ <td>A-37301248<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9043</td>
- <td>A-37305954<a href="#asterisk">*</a><br>
- QC-CR#762954</td>
+ <td>A-37305954<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9044</td>
- <td>A-37303520<a href="#asterisk">*</a><br>
- QC-CR#764858</td>
+ <td>A-37303520<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9045</td>
- <td>A-37302136<a href="#asterisk">*</a><br>
- QC-CR#766189</td>
+ <td>A-37302136<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9046</td>
- <td>A-37301486<a href="#asterisk">*</a><br>
- QC-CR#767335</td>
+ <td>A-37301486<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9047</td>
- <td>A-37304367<a href="#asterisk">*</a><br>
- QC-CR#779285</td>
+ <td>A-37304367<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9048</td>
- <td>A-37305707<a href="#asterisk">*</a><br>
- QC-CR#795960</td>
+ <td>A-37305707<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9049</td>
- <td>A-37301488<a href="#asterisk">*</a><br>
- QC-CR#421589, QC-CR#817165</td>
+ <td>A-37301488<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9050</td>
- <td>A-37302137<a href="#asterisk">*</a><br>
- QC-CR#830102</td>
+ <td>A-37302137<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9051</td>
- <td>A-37300737<a href="#asterisk">*</a><br>
- QC-CR#837317</td>
+ <td>A-37300737<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9052</td>
- <td>A-37304217<a href="#asterisk">*</a><br>
- QC-CR#840483</td>
+ <td>A-37304217<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9053</td>
- <td>A-37301249<a href="#asterisk">*</a><br>
- QC-CR#843808</td>
+ <td>A-37301249<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9054</td>
- <td>A-37303177<a href="#asterisk">*</a><br>
- QC-CR#856077</td>
+ <td>A-37303177<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9055</td>
- <td>A-37472412<a href="#asterisk">*</a><br>
- QC-CR#806464</td>
+ <td>A-37472412<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Core</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9060</td>
- <td>A-37472807<a href="#asterisk">*</a><br>
- QC-CR#817343</td>
+ <td>A-37472807<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9061</td>
- <td>A-37470436<a href="#asterisk">*</a><br>
- QC-CR#824195</td>
+ <td>A-37470436<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9062</td>
- <td>A-37472808<a href="#asterisk">*</a><br>
- QC-CR#802039</td>
+ <td>A-37472808<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9067</td>
- <td>A-37474000<a href="#asterisk">*</a><br>
- QC-CR#848926</td>
+ <td>A-37474000<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9068</td>
- <td>A-37470144<a href="#asterisk">*</a><br>
- QC-CR#851114</td>
+ <td>A-37470144<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9069</td>
- <td>A-37470777<a href="#asterisk">*</a><br>
- QC-CR#854496</td>
+ <td>A-37470777<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9070</td>
- <td>A-37474001<a href="#asterisk">*</a><br>
- QC-CR#877102</td>
+ <td>A-37474001<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9071</td>
- <td>A-37471819<a href="#asterisk">*</a><br>
- QC-CR#877276</td>
+ <td>A-37471819<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9072</td>
- <td>A-37474002<a href="#asterisk">*</a><br>
- QC-CR#877361</td>
+ <td>A-37474002<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2015-9073</td>
- <td>A-37473407<a href="#asterisk">*</a><br>
- QC-CR#878073</td>
+ <td>A-37473407<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10343</td>
- <td>A-32580186<a href="#asterisk">*</a><br>
- QC-CR#972213</td>
+ <td>A-32580186<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10344</td>
- <td>A-32583954<a href="#asterisk">*</a><br>
- QC-CR#1022360</td>
+ <td>A-32583954<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Modem</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10346</td>
- <td>A-37473408<a href="#asterisk">*</a><br>
- QC-CR#896584</td>
+ <td>A-37473408<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Core</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10347</td>
- <td>A-37471089<a href="#asterisk">*</a><br>
- QC-CR#899671</td>
+ <td>A-37471089<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Core</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10382</td>
- <td>A-28823584<a href="#asterisk">*</a><br>
- QC-CR#944014</td>
+ <td>A-28823584<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10383</td>
- <td>A-28822389<a href="#asterisk">*</a><br>
- QC-CR#960624</td>
+ <td>A-28822389<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10388</td>
- <td>A-32580294<a href="#asterisk">*</a><br>
- QC-CR#992749</td>
+ <td>A-32580294<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-10391</td>
- <td>A-32583804<a href="#asterisk">*</a><br>
- QC-CR#970283</td>
+ <td>A-32583804<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>WConnect</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-5871</td>
- <td>A-37473055<a href="#asterisk">*</a><br>
- QC-CR#883013</td>
+ <td>A-37473055<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
<tr>
<td>CVE-2016-5872</td>
- <td>A-37472809<a href="#asterisk">*</a><br>
- QC-CR#886220</td>
+ <td>A-37472809<a href="#asterisk">*</a></td>
<td>N/A</td>
<td>High</td>
- <td>Secure systems group</td>
+ <td>Closed-source component</td>
</tr>
</table>
<h2 id="google-device-updates">Google device updates</h2>
@@ -1783,7 +1728,11 @@ site</a>.</p>
<td>July 11, 2017</td>
<td>Bulletin revised to update acknowledgements.</td>
</tr>
-</table>
+ <tr>
+ <td>1.3</td>
+ <td>August 17, 2017</td>
+ <td>Bulletin revised to update reference numbers.</td>
+ </tr>
</table>
</body>
</html>
diff --git a/en/security/bulletin/2017-08-01.html b/en/security/bulletin/2017-08-01.html
index 2c4139d2..00acb55c 100644
--- a/en/security/bulletin/2017-08-01.html
+++ b/en/security/bulletin/2017-08-01.html
@@ -20,7 +20,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<p><em>Published August 7, 2017 | Updated August 8, 2017</em></p>
+<p><em>Published August 7, 2017 | Updated August 14, 2017</em></p>
<p>The Android Security Bulletin contains details of security vulnerabilities
affecting Android devices. Security patch levels of August 05, 2017 or later
@@ -343,6 +343,13 @@ privileged process.</p>
<td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
</tr>
<tr>
+ <td>CVE-2017-0687</td>
+ <td><a href="https://android.googlesource.com/platform/external/libavc/+/17b46beeae7421f76d894f14696ba4db9023287c">A-35583675</a></td>
+ <td>DoS</td>
+ <td>High</td>
+ <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+ </tr>
+ <tr>
<td>CVE-2017-0737</td>
<td><a href="https://android.googlesource.com/platform/frameworks/av/+/77e075ddd6d8cae33832add5225ee8f8c77908f0">A-37563942</a></td>
<td>EoP</td>
@@ -962,6 +969,11 @@ site</a>.</p>
<td>August 8, 2017</td>
<td>Bulletin revised to include AOSP links and acknowledgements.</td>
</tr>
+ <tr>
+ <td>1.2</td>
+ <td>August 14, 2017</td>
+ <td>Bulletin revised to add CVE-2017-0687.</td>
+ </tr>
</table>
</body>
</html>
diff --git a/en/security/images/access-to-keymaster.png b/en/security/images/access-to-keymaster.png
index 5f27a312..8269c30b 100644
--- a/en/security/images/access-to-keymaster.png
+++ b/en/security/images/access-to-keymaster.png
Binary files differ
diff --git a/en/security/keystore/attestation.html b/en/security/keystore/attestation.html
new file mode 100644
index 00000000..7b03c250
--- /dev/null
+++ b/en/security/keystore/attestation.html
@@ -0,0 +1,603 @@
+<html devsite>
+ <head>
+ <title>Key Attestation</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
+
+ //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>
+Keystore provides a more secure place to create, store, and use cryptographic
+keys in a controlled way. When hardware-backed key storage is available and
+used, key material is more secure against extraction from the device, and
+keymaster1 enforces restrictions in a hard-to-subvert way.
+</p>
+<p>
+This is only true, however, if the keystore keys are known to be in
+hardware-backed storage. There is presently no way for apps or remote servers to
+reliably verify if this is the case. The keystore daemon loads the available
+keymaster HAL and believes whatever the HAL says with respect to hardware
+backing of keys.
+</p>
+<p>
+Key attestation aims to provide a way to strongly determine if an asymmetric key
+pair is hardware-backed, what the properties of the key are, and what
+constraints are applied to its usage.
+</p>
+<h2 id="java-api">Java API</h2>
+<p class="note">
+Note: This section is informational only. Keymaster2 implementers neither
+implement nor use the Java API. This is provided to help implementers understand
+how the feature is used by applications. System components may use it
+differently, which is why it's crucial this section not be treated as normative.
+</p>
+
+<section class="expandable">
+ <h4 class="showalways">How application developers use attestation</h4>
+<ul>
+<li>Creates a key generation request, specifying a key alias and key generation
+parameters for an EC or RSA key pair.</li>
+<li>Sets the "attestation challenge" for the request, with
+<code>KeyPairGenerator.setAttestationChallenge(byte[])</code>. This both
+provides challenge data (which may be empty), and indicates that an attestation
+is requested.</li>
+<li>Generates the key pair.</li>
+<li>Requests the certificate chain from <code>AndroidKeyStore</code>. The first
+certificate in the chain is the attestation; the other certificates provide the
+chain of trust back to and including the root attestation key.</li>
+</ul>
+<p>
+This example generates a key pair and requests an attestation.
+</p>
+
+<pre class="prettyprint">// Create KeyPairGenerator and set generation parameters for an ECDSA key pair
+// using the NIST P-256 curve. "Key1" is the key alias.
+KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+ keyPairGenerator.initialize(
+ new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN)
+ .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+ .setDigests(KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA384,
+ KeyProperties.DIGEST_SHA512)
+ // Only permit the private key to be used if the user
+ // authenticated within the last five minutes.
+ .setUserAuthenticationRequired(true)
+ .setUserAuthenticationValidityDurationSeconds(5 * 60)
+ // Request an attestation with challenge "hello world".
+ .setAttestationChallenge("hello world".toBytes());
+ .build());
+// Generate the key pair. This will result in calls to both generate_key() and
+// attest_key() at the keymaster2 HAL.
+KeyPair keyPair = keyPairGenerator.generateKeyPair();
+// Get the certificate chain
+KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+keyStore.load(null);
+Certificate[] certs = keyStore.getCertificateChain("Key1");
+// certs[0] is the attestation certificate. certs[1] signs certs[0], etc.,
+// up to certs[certs.length - 1].
+</pre>
+</section>
+
+<h2 id="hal-changes">HAL changes</h2>
+<p>
+To support key attestation, Android 7.1 introduced a set of tags, type, and
+method to the HAL.
+</p>
+<p>
+<strong>Tags</strong>
+</p>
+<ul>
+<li><code>KM_TAG_ATTESTATION_CHALLENGE</code></li>
+<li><code>KM_TAG_INCLUDE_UNIQUE_ID</code></li>
+<li><code>KM_TAG_RESET_SINCE_ID_ROTATION</code> </li>
+</ul>
+<p>
+<strong>Type</strong>
+</p>
+
+<pre class="prettyprint">typedef struct {
+ keymaster_blob_t* entries;
+ size_t entry_count;
+} keymaster_cert_chain_t;
+</pre>
+
+<p>
+<strong><code>Attest_key</code> method</strong></p>
+
+<pre class="prettyprint">keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
+ const keymaster_key_blob_t* key_to_attest,
+ const keymaster_key_param_set_t* attest_params,
+ keymaster_cert_chain_t* cert_chain);
+</pre>
+
+<ul>
+<li><code>dev</code> is the keymaster device structure.</li>
+<li><code>key_to_attest</code> is the key blob returned from
+<code>generate_key</code> for which the attestation will be created.</li>
+<li><code>attest_params</code> is a list of any parameters necessary for
+attestation. This includes <code>KM_TAG_ATTESTATION_CHALLENGE</code> and
+possibly <code>KM_TAG_RESET_SINCE_ID_ROTATION</code>, as well as
+<code>KM_TAG_APPLICATION_ID</code> and <code>KM_TAG_APPLICATION_DATA</code>. The
+latter two are necessary to decrypt the key blob if they were specified during
+key generation.</li>
+<li><code>cert_chain</code> is the output parameter, which returns an array of
+certificates. Entry 0 is the attestation certificate, meaning it
+certifies the key from <code>key_to_attest</code> and contains the
+attestation extension.</li>
+</ul>
+
+<p>
+The <code>attest_key</code> method is considered a public key operation on the
+attested key, because it can be called at any time and doesn't need to meet
+authorization constraints. For example, if the attested key needs user
+authentication for use, an attestation can be generated without user
+authentication.
+</p>
+<h2 id="attestation-certificate">Attestation certificate</h2>
+<p>
+The attestation certificate is a standard X.509 certificate, with an optional
+attestation extension that contains a description of the attested key. The
+certificate is signed with a factory-provisioned <a
+href="#attestation-keys-and-certificates">attestation key</a> that uses the same
+algorithm as the key being attested (RSA for RSA, EC for EC).
+</p>
+<p>
+The attestation certificate contains the fields in the table below and can't
+contain any additional fields. Some fields specify a fixed field value. CTS
+tests validate that the certificate content is exactly as defined.
+</p>
+<h3 id="certificate-sequence">Certificate SEQUENCE</h3>
+<table>
+ <tr>
+ <th>Field name (see
+ <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>)
+ </th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.1">tbsCertificate</a></td>
+ <td><a href="#tbscertificate-sequence">TBSCertificate SEQUENCE</a></td>
+ </tr>
+ <tr>
+ <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.2">signatureAlgorithm</a></td>
+ <td>AlgorithmIdentifier of algorithm used to sign key:<br />
+ ECDSA for EC keys, RSA for RSA keys.</td>
+ </tr>
+ <tr>
+ <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.3">signatureValue</a></td>
+ <td>BIT STRING, signature computed on ASN.1 DER-encoded tbsCertificate.</td>
+ </tr>
+</table>
+
+<h3 id="tbscertificate-sequence">TBSCertificate SEQUENCE</h3>
+
+<table>
+ <tr>
+ <th>Field name (see
+ <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>)</th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td><code>version</code></td>
+ <td>INTEGER 2 (means v3 certificate)</td>
+ </tr>
+ <tr>
+ <td><code>serialNumber</code></td>
+ <td>INTEGER 1 (fixed value: same on <em>all</em> certs)</td>
+ </tr>
+ <tr>
+ <td><code>signature</code></td>
+ <td>AlgorithmIdentifier of algorithm used to sign key: ECDSA for EC keys,
+ RSA for RSA keys.</td>
+ </tr>
+ <tr>
+ <td><code>issuer</code></td>
+ <td>Same as the subject field of the batch attestation key.</td>
+ </tr>
+ <tr>
+ <td><code>validity</code></td>
+ <td>SEQUENCE of two dates, containing the values of
+ <code>KM_TAG_ACTIVE_DATETIME</code> and
+ <code>KM_TAG_USAGE_EXPIRE_DATETIME</code>. Those values are in milliseconds
+ since Jan 1, 1970. See <a href="https://tools.ietf.org/html/rfc5280">RFC
+ 5280</a> for correct date representations in certificates.<br />
+ If <code>KM_TAG_ACTIVE_DATETIME</code> is not present, use the value of
+ <code>KM_TAG_CREATION_DATETIME</code>. If
+ <code>KM_TAG_USAGE_EXPIRE_DATETIME</code> is not present, use the expiration
+ date of the batch attestation key certificate.</td>
+ </tr>
+ <tr>
+ <td><code>subject</code></td>
+ <td>CN = "Android Keystore Key" (fixed value: same on <em>all</em> certs)</td>
+ </tr>
+ <tr>
+ <td><code>subjectPublicKeyInfo</code></td>
+ <td>SubjectPublicKeyInfo containing attested public key.</td>
+ </tr>
+ <tr>
+ <td><code>extensions/Key Usage</code></td>
+ <td>digitalSignature: set if key has purpose <code>KM_PURPOSE_SIGN</code> or
+ <code>KM_PURPOSE_VERIFY</code>. All other bits unset.</td>
+ </tr>
+ <tr>
+ <td><code>extensions/CRL Distribution Points</code></td>
+ <td>Value TBD</td>
+ </tr>
+ <tr>
+ <td><code>extensions/"attestation"</code></td>
+ <td>The OID is 1.3.6.1.4.1.11129.2.1.17; the content is defined in the
+ Attestation Extension section below. As with all
+ X.509 certificate extensions, the content is represented as an OCTET_STRING
+ containing a DER encoding of the attestation SEQUENCE.</td>
+ </tr>
+</table>
+
+<h2 id="attestation-extension">Attestation extension</h2>
+<p>
+The attestation extension contains a complete description of the keymaster
+authorizations associated with the key, in a structure that directly corresponds
+to the authorization lists as used in Android and the keymaster HAL. Each tag in
+an authorization list is represented by an ASN.1 SEQUENCE entry, explicitly
+tagged with the keymaster tag number, but with the type descriptor (four high
+order bits) masked out. For example, <code>KM_TAG_PURPOSE</code> is defined in
+keymaster_defs.h as <code>KM_ENUM_REP</code> | 1. For the attestation extension,
+the <code>KM_ENUM_REP</code> value is removed, leaving tag 1.
+</p>
+<p>
+Values are translated in a straightforward way to ASN.1 types, per this table:
+</p>
+<table>
+ <tr>
+ <th>Keymaster type</th>
+ <th>ASN.1 type</th>
+ </tr>
+ <tr>
+ <td><code>KM_ENUM</code></td>
+ <td>INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_ENUM_REP</code></td>
+ <td>SET of INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_UINT</code></td>
+ <td>INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_UINT_REP</code></td>
+ <td>SET of INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_ULONG</code></td>
+ <td>INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_ULONG_REP</code></td>
+ <td>SET of INTEGER</td>
+ </tr>
+ <tr>
+ <td><code>KM_DATE</code></td>
+ <td>INTEGER (milliseconds since Jan 1, 1970 00:00:00 GMT)</td>
+ </tr>
+ <tr>
+ <td><code>KM_BOOL</code></td>
+ <td>NULL (in keymaster, tag present means true, absent means false.<br />
+ The same semantics apply to the ASN.1 encoding)</td>
+ </tr>
+ <tr>
+ <td><code>KM_BIGNUM</code></td>
+ <td>Not presently used, so no mapping is defined</td>
+ </tr>
+ <tr>
+ <td><code>KM_BYTES</code></td>
+ <td>OCTET_STRING</td>
+ </tr>
+</table>
+<p class="note">
+<strong>Note:</strong> Some tags are omitted from the schema and should not be
+included in attestations. For example, the values of <code>KM_TAG_USER_ID</code>
+and <code>KM_TAG_SECURE_USER_ID</code> have no meaning off-device, and
+<code>KM_TAG_MIN_MAC_LENGTH</code> and <code>KM_TAG_CALLER_NONCE</code> are
+useless with asymmetric keys.
+</p>
+
+<h3 id="schema">Schema</h3>
+<p>
+The attestation extension content is described by the following ASN.1 schema:
+</p>
+
+<pre class="prettyprint">
+KeyDescription ::= SEQUENCE {
+ attestationVersion INTEGER,
+ attestationSecurityLevel SecurityLevel,
+ keymasterVersion INTEGER,
+ keymasterSecurityLevel SecurityLevel,
+ attestationChallenge OCTET_STRING,
+ uniqueId OCTET_STRING,
+ softwareEnforced AuthorizationList,
+ teeEnforced AuthorizationList,
+}
+
+SecurityLevel ::= ENUMERATED {
+ Software (0),
+ TrustedEnvironment (1),
+}
+AuthorizationList ::= SEQUENCE {
+ purpose [1] EXPLICIT SET OF INTEGER OPTIONAL,
+ algorithm [2] EXPLICIT INTEGER OPTIONAL,
+ keySize [3] EXPLICIT INTEGER OPTIONAL.
+ digest [5] EXPLICIT SET OF INTEGER OPTIONAL,
+ padding [6] EXPLICIT SET OF INTEGER OPTIONAL,
+ ecCurve [10] EXPLICIT INTEGER OPTIONAL,
+ rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL,
+ activeDateTime [400] EXPLICIT INTEGER OPTIONAL
+ originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL
+ usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL
+ noAuthRequired [503] EXPLICIT NULL OPTIONAL,
+ userAuthType [504] EXPLICIT INTEGER OPTIONAL,
+ authTimeout [505] EXPLICIT INTEGER OPTIONAL,
+ allowWhileOnBody [506] EXPLICIT NULL OPTIONAL,
+ allApplications [600] EXPLICIT NULL OPTIONAL,
+ applicationId [601] EXPLICIT OCTET_STRING OPTIONAL,
+ creationDateTime [701] EXPLICIT INTEGER OPTIONAL,
+ origin [702] EXPLICIT INTEGER OPTIONAL,
+ rollbackResistant [703] EXPLICIT NULL OPTIONAL,
+ rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL,
+ osVersion [705] EXPLICIT INTEGER OPTIONAL,
+ osPatchLevel [706] EXPLICIT INTEGER OPTIONAL,
+}
+RootOfTrust ::= SEQUENCE {
+ verifiedBootKey OCTET_STRING,
+ deviceLocked BOOLEAN,
+ verifiedBootState VerifiedBootState,
+}
+
+VerifiedBootState ::= ENUMERATED {
+ Verified (0),
+ SelfSigned (1),
+ Unverified (2),
+ Failed (3),
+}</pre>
+
+
+<h3 id="keydescription-fields">KeyDescription fields</h3>
+<p>
+The keymasterVersion and attestationChallenge fields are identified
+positionally, rather than by tag, so the tags in the encoded form only specify
+field type. The remaining fields are implicitly tagged as specified in the
+schema.
+</p>
+<table>
+ <tr>
+ <th>Field name</th>
+ <th>Type</th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td><code>attestationVersion</code></td>
+ <td>INTEGER</td>
+ <td>1</td>
+ </tr>
+ <tr>
+ <td><code>attestationSecurity</code></td>
+ <td>SecurityLevel</td>
+ <td>The security level of this attestation. It is possible to get software
+attestations of hardware-backed keys. Such attestations cannot be trusted if the
+Android system is compromised.</td>
+ </tr>
+ <tr>
+ <td><code>keymasterVersion</code></td>
+ <td>INTEGER</td>
+ <td>Version of keymaster device, 0, 1, or 2.</td>
+ </tr>
+ <tr>
+ <td><code>keymasterSecurity</code></td>
+ <td>SecurityLevel</td>
+ <td>The security level of the keymaster implementation.</td>
+ </tr>
+ <tr>
+ <td><code>attestationChallenge</code></td>
+ <td>OCTET_STRING</td>
+ <td>Value of <code>KM_TAG_ATTESTATION_CHALLENGE</code>, specified to
+attestation request.</td>
+ </tr>
+ <tr>
+ <td><code>uniqueId</code></td>
+ <td>OCTET_STRING</td>
+ <td>Optional unique ID, present if key has
+<code>KM_TAG_INCLUDE_UNIQUE_ID</code></td>
+ </tr>
+ <tr>
+ <td><code>softwareEnforced</code></td>
+ <td>AuthorizationList</td>
+ <td>Optional, keymaster authorizations that are not enforced by the TEE, if
+any.</td>
+ </tr>
+ <tr>
+ <td><code>teeEnforced</code></td>
+ <td>AuthorizationList</td>
+ <td>Optional, Keymaster authorizations that are enforced by the TEE, if any.</td>
+ </tr>
+</table>
+
+<h3 id="authorizationlist-fields">AuthorizationList fields</h3>
+<p>
+AuthorizationList fields are all optional and are identified by keymaster tag
+value, with the type bits masked out. Explicit tagging is used so the fields
+also contain a tag indicating their ASN.1 type, for easier parsing.
+</p>
+<p>
+See keymaster_defs.h for details on each field's values. Keymaster tag names
+were transformed into field names by omitting the KM_TAG prefix and changing the
+remainder to camel case, so <code>KM_TAG_KEY_SIZE</code> became
+<code>keySize</code>.
+</p>
+<p class="note">
+<strong>Note</strong>: Many tags from keymaster_defs.h are not included in the
+schema. Some tags are not applicable to asymmetric keys, some have no meaning
+off-device, etc.
+</p>
+
+<h3 id="rootoftrust-fields">RootOfTrust fields</h3>
+<p>
+The RootOfTrust Fields are identified positionally.
+</p>
+<table>
+ <tr>
+ <th>Field name</th>
+ <th>Type</th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td><code>verifiedBootKey</code></td>
+ <td>OCTET_STRING</td>
+ <td>A secure hash of the key used to verify the system image. SHA-256
+recommended.</td>
+ </tr>
+ <tr>
+ <td><code>deviceLocked</code></td>
+ <td>BOOLEAN</td>
+ <td>True if the bootloader is locked, which means that only signed images can
+be flashed, and that verified boot checking is done.</td>
+ </tr>
+ <tr>
+ <td><code>verifiedBootState</code></td>
+ <td>VerifiedBootState</td>
+ <td>State of verified boot.</td>
+ </tr>
+ <tr>
+ <td><code>osVersion</code></td>
+ <td>INTEGER</td>
+ <td>The current version of the OS, as an integer in the format MMmmss, where
+MM is a two-digit major version number, mm is a two-digit minor version number,
+and ss is a two-digit sub-minor version number. For example, version 6.0.1 would
+be represented as 060001</td>
+ </tr>
+ <tr>
+ <td><code>patchMonthYear</code></td>
+ <td>INTEGER</td>
+ <td>The month and year of the last patch, as an integer in the format YYYYMM,
+where YYYY is a four-digit year and MM is a two-digit month. For example, April
+2016 would be represented as 201604.</td>
+ </tr>
+</table>
+<h3 id="verifiedbootstate-values">VerifiedBootState values</h3>
+<p>
+The values of <code>verifiedBootState</code> have the following meanings:
+</p>
+<table>
+ <tr>
+ <th>Value</th>
+ <th>Meaning</th>
+ </tr>
+ <tr>
+ <td><code>Verified</code></td>
+ <td>Indicates a full chain of trust extending from the bootloader to verified
+partitions, including the bootloader, boot partition, and all verified
+partitions.<br />
+In this state, the verifiedBootKey value is the hash of the embedded certificate,
+meaning the unchangeable certificate burned into ROM.</td>
+ </tr>
+ <tr>
+ <td><code>SelfSigned</code></td>
+ <td>Indicates the boot partition has been verified using the embedded
+certificate, and the signature is valid. The bootloader displays a warning and
+the fingerprint of the public key before allowing the boot process to continue.
+<br />
+In this state, the verifiedBootKey value is the hash of the self-signing
+certificate.</td>
+ </tr>
+ <tr>
+ <td><code>Unverified</code></td>
+ <td>Indicates a device may be freely modified. Device integrity is left to
+the user to verify out-of-band. The bootloader displays a warning to the user
+before allowing the boot process to continue.<br />
+In this state the verifiedBootKey value is empty.</td>
+ </tr>
+ <tr>
+ <td><code>Failed</code></td>
+ <td>Indicates the device has failed verification. No attestation certificate
+actually contains this value, because in this state the bootloader halts. It's
+included here for completeness.</td>
+ </tr>
+</table>
+
+<h3 id="securitylevel-values">SecurityLevel values</h3>
+<p>
+The values of securityLevel have the following meanings:
+</p>
+<table>
+ <tr>
+ <th>Value</th>
+ <th>Meaning</th>
+ </tr>
+ <tr>
+ <td><code>Software</code></td>
+ <td>The code that creates or manages the relevant element (attestation or
+key) is implemented in the Android system and could be altered if that system is
+compromised.</td>
+ </tr>
+ <tr>
+ <td><code>TrustedEnvironment</code></td>
+ <td>The code that creates or manages the relevant element (attestation or
+key) is implemented in a Trusted Execution Environment (TEE). It could be
+altered if the TEE is compromised, but the TEE is highly resistant to remote
+compromise and moderately resistant to compromise by direct hardware attack.</td>
+ </tr>
+</table>
+<h2 id="unique-id">Unique ID</h2>
+<p>
+The Unique ID is a 128-bit value that identifies the device, but only for a
+limited period of time. The value is computed with:
+</p>
+
+<pre class="prettyprint">
+HMAC_SHA256(T || C || R, HBK)
+</pre>
+
+<p>
+Where:
+</p>
+
+<ul>
+<li><code>T</code> is the "temporal counter value", computed by dividing the
+value of <code>KM_TAG_CREATION_DATETIME</code> by 2592000000, dropping any
+remainder. <code>T</code> changes every 30 days (2592000000 = 30 * 24 * 60 * 60
+* 1000).</li>
+<li><code>C</code> is the value of <code>KM_TAG_APPLICATION_ID</code></li>
+<li><code>R</code> is 1 if <code>KM_TAG_RESET_SINCE_ID_ROTATION</code> is
+present in the attest_params parameter to the attest_key call, or 0 if the tag
+is not present.</li>
+<li><code>HBK</code> is a unique hardware-bound secret known to the Trusted
+Execution Environment and never revealed by it. The secret contains at least 128
+bits of entropy and is unique to the individual device (probabilistic uniqueness
+is acceptable given the 128 bits of entropy). HBK should be derived from fused
+key material via HMAC or AES_CMAC.</li>
+</ul>
+<p>
+Truncate the HMAC_SHA256 output to 128 bits.
+</p>
+
+<h2 id="attestation-keys-and-certificates">Attestation keys and
+certificates</h2>
+<p>
+Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are
+securely provisioned into the device.
+</p>
+</body>
+</html>
diff --git a/en/security/keystore/features.html b/en/security/keystore/features.html
index 238f0d79..05da1744 100644
--- a/en/security/keystore/features.html
+++ b/en/security/keystore/features.html
@@ -23,8 +23,8 @@
-<p>This page contains information about the features of <a href="index.html">Keystore</a>
-in Android 6.0.</p>
+<p>This page contains information about the cryptographic features of
+<a href="index.html">Keystore</a> in Android 6.0 and above.</p>
<h2 id=cryptographic_primitives>Cryptographic primitives</h2>
@@ -33,7 +33,7 @@ in Android 6.0.</p>
<ul>
<li>Key generation
<li>Import and export of asymmetric keys (no key wrapping)
- <li>Import of raw symmetric keys (again, no wrapping)
+ <li>Import of raw symmetric keys (no key wrapping)
<li>Asymmetric encryption and decryption with appropriate padding modes
<li>Asymmetric signing and verification with digesting and appropriate padding
modes
@@ -44,36 +44,34 @@ mode
<p>Protocol elements, such as purpose, mode and padding, as well
as <a href="#key_access_control">access control constraints</a>,
-must be specified when keys are generated or imported and are permanently
+are specified when keys are generated or imported and are permanently
bound to the key, ensuring the key cannot be used in any other way.</p>
<p>In addition to the list above, there is one more service that Keymaster
-implementations must provide but which is not exposed as an API: Random number
+implementations provide, but which is not exposed as an API: Random number
generation. This is used internally for generation of keys, Initialization
Vectors (IVs), random padding and other elements of secure protocols that
require randomness.</p>
-<h2 id=required_primitives>Required primitives</h2>
+<h2 id="primitives">Necessary primitives</h2>
-<p>All implementations must provide:</p>
+<p>All Keymaster implementations provide:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/RSA_(cryptosystem)">RSA</a>
<ul>
- <li>2048, 3072 and 4096-bit key support are required
+ <li>2048, 3072, and 4096-bit key support
<li>Support for public exponent F4 (2^16+1)
- <li>Required padding modes for RSA signing are:
+ <li>Padding modes for RSA signing:
<ul>
- <li>No padding (deprecated, will be removed in the future)
<li>RSASSA-PSS (<code>KM_PAD_RSA_PSS</code>)
<li>RSASSA-PKCS1-v1_5 (<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code>)
</ul>
- <li>Required digest modes for RSA signing are:
+ <li>Digest modes for RSA signing:
<ul>
- <li>No digest (deprecated, will be removed in the future)
<li>SHA-256
</ul>
- <li>Required padding modes for RSA encryption/decryption are:
+ <li>Padding modes for RSA encryption/decryption:
<ul>
<li>Unpadded
<li>RSAES-OAEP (<code>KM_PAD_RSA_OAEP</code>)
@@ -82,31 +80,32 @@ require randomness.</p>
</ul>
<li><a href="http://en.wikipedia.org/wiki/Elliptic_Curve_DSA">ECDSA</a>
<ul>
- <li>224, 256, 384 and 521-bit key support are required, using the NIST P-224,
-P-256, P-384 and P-521 curves, respectively
- <li>Required digest modes for ECDSA are:
+ <li>224, 256, 384, and 521-bit key support are supported, using the NIST P-224,
+P-256, P-384, and P-521 curves, respectively
+ <li>Digest modes for ECDSA:
<ul>
- <li>No digest (deprecated, will be removed in the future)
- <li>SHA-256
+ <li>No digest (deprecated, will be removed in the future)</li>
+ <li>SHA-256</li>
</ul>
</ul>
<li><a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES</a>
<ul>
- <li>128 and 256-bit keys are required
+ <li>128 and 256-bit keys are supported
<li><a href="http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29">CBC</a>,
- CTR, ECB and and GCM. The GCM implementation must not allow the use of tags
+ CTR, ECB, and GCM. The GCM implementation does not allow the use of tags
smaller than 96 bits or nonce lengths other than 96 bits.
- <li>Padding modes <code>KM_PAD_NONE</code> and <code>KM_PAD_PKCS7</code> must
- be supported for CBC and ECB modes. With no padding, CBC or ECB mode
-encryption must fail if the input isn't a multiple of the block size.
+ <li>Padding modes <code>KM_PAD_NONE</code> and <code>KM_PAD_PKCS7</code> is
+ supported for CBC and ECB modes. With no padding, CBC or ECB mode
+ encryption fails if the input isn't a multiple of the block size.
</ul>
<li><a href="http://en.wikipedia.org/wiki/Hash-based_message_authentication_code">HMAC</a>
- <a href="http://en.wikipedia.org/wiki/SHA-2">SHA-256</a>, with any key size up to at least 32 bytes.
+ <a href="http://en.wikipedia.org/wiki/SHA-2">SHA-256</a>, with any key size up
+ to at least 32 bytes.
</ul>
</ul>
<p>SHA1 and the other members of the SHA2 family (SHA-224, SHA384 and SHA512) are
-strongly recommended, but not required. Keystore will provide them in software
+strongly recommended for Keymaster implementations. Keystore provides them in software
if the hardware Keymaster implementation doesn't provide them.</p>
<p>Some primitives are also recommended for interoperability with other systems:</p>
@@ -126,65 +125,75 @@ enforce access controls.</p>
<p>Access controls are defined as an "authorization list" of tag/value pairs.
Authorization tags are 32-bit integers and the values are a variety of types.
Some tags may be repeated to specify multiple values. Whether a tag may be
-repeated is specified in the documentation for the tag. When a key is created,
+repeated is specified in the <a href="/security/keystore/tags">documentation
+for the tag</a>. When a key is created,
the caller specifies an authorization list. The Keymaster implementation
-underlying Keystore will modify the list to specify some additional information,
+underlying Keystore modifies the list to specify some additional information,
such as whether the key has rollback protection, and return a "final"
authorization list, encoded into the returned key blob. Any attempt to use the
-key for any cryptographic operation must fail if the final authorization list is
+key for any cryptographic operation fails if the final authorization list is
modified.</p>
-<p>The set of possible tags is defined in the enumeration <code>keymaster_authorization_tag_t</code> and
-the set must be permanently fixed (though it can be extended).
+<p>The set of possible tags is defined in the enumeration
+<code>keymaster_authorization_tag_t</code> and
+is permanently fixed (though it can be extended).
Names are prefixed with <code>KM_TAG_</code>. The top
four bits of tag IDs are used to indicate the type.</p>
<p>Possible types include:</p>
-<p><strong><code>KM_ENUM</code>:</strong> Many tags' values are defined in enumerations. For example, the possible
-values of <code>KM_TAG_PURPOSE</code> are defined in enum <code>keymaster_purpose_t</code>.</p>
+<p><strong><code>KM_ENUM</code>:</strong> Many tags' values are defined in
+enumerations. For example, the possible values of <code>KM_TAG_PURPOSE</code>
+are defined in enum <code>keymaster_purpose_t</code>.</p>
-<p><strong><code>KM_ENUM_REP</code></strong>: Same as <code>KM_ENUM</code>, except that the tag may
-be repeated in an authorization list. Repetition
-indicates multiple authorized values. For example, an encryption key will
-likely have <code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_DECRYPT</code>.</p>
+<p><strong><code>KM_ENUM_REP</code></strong>: Same as <code>KM_ENUM</code>,
+except that the tag may be repeated in an authorization list. Repetition
+indicates multiple authorized values. For example, an encryption key
+likely has <code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_DECRYPT</code>.</p>
-<p><strong><code>KM_UINT</code>:</strong> 32-bit unsigned integers. Example: <code>KM_TAG_KEY_SIZE</code></p>
+<p><strong><code>KM_UINT</code>:</strong> 32-bit unsigned integers. Example:
+<code>KM_TAG_KEY_SIZE</code></p>
-<p><strong><code>KM_UINT_REP</code></strong>: Same as <code>KM_UINT</code>, except that the tag may be
-repeated in an authorization list. Repetition indicates multiple authorized values.</p>
+<p><strong><code>KM_UINT_REP</code></strong>: Same as <code>KM_UINT</code>,
+except that the tag may be repeated in an authorization list. Repetition
+indicates multiple authorized values.</p>
-<p><strong><code>KM_ULONG</code></strong>: 64-bit unsigned integers. Example: <code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
+<p><strong><code>KM_ULONG</code></strong>: 64-bit unsigned integers. Example:
+<code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
-<p><strong><code>KM_ULONG_REP</code></strong>: Same as <code>KM_ULONG</code>, except that the tag may be
-repeated in an authorization list. Repetition
+<p><strong><code>KM_ULONG_REP</code></strong>: Same as <code>KM_ULONG</code>,
+except that the tag may be repeated in an authorization list. Repetition
indicates multiple authorized values.</p>
-<p><strong><code>KM_DATE</code></strong>: Date/time values, expressed as milliseconds since January 1, 1970.
+<p><strong><code>KM_DATE</code></strong>: Date/time values, expressed as
+milliseconds since January 1, 1970.
Example: <code>KM_TAG_PRIVKEY_EXPIRE_DATETIME</code></p>
-<p><strong><code>KM_BOOL</code></strong>: True or false. A tag of type <code>KM_BOOL</code> is assumed
-to be "false" if the tag is not present and "true" if present. Example: <code>KM_TAG_ROLLBACK_RESISTANT</code></p>
+<p><strong><code>KM_BOOL</code></strong>: True or false. A tag of type
+<code>KM_BOOL</code> is assumed to be "false" if the tag is not present and
+"true" if present. Example: <code>KM_TAG_ROLLBACK_RESISTANT</code></p>
-<p><strong><code>KM_BIGNUM</code></strong>: Arbitrary-length integers, expressed as a byte array
-in big-endian order. Example: <code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
+<p><strong><code>KM_BIGNUM</code></strong>: Arbitrary-length integers,
+expressed as a byte array in big-endian order. Example:
+<code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
-<p><strong><code>KM_BYTES</code></strong>: A sequence of bytes. Example: <code>KM_TAG_ROOT_OF_TRUST</code></p>
+<p><strong><code>KM_BYTES</code></strong>: A sequence of bytes. Example:
+<code>KM_TAG_ROOT_OF_TRUST</code></p>
<h3 id=hardware_vs_software_enforcement>Hardware vs. software enforcement</h3>
-<p>Not all secure hardware will implement the same features. To support a
-variety of approaches, Keymaster 1.0 distinguishes between secure and non-secure
-world access control enforcement, which we call hardware and software
+<p>Not all secure hardware implementations contain the same features. To support
+a variety of approaches, Keymaster distinguishes between secure and non-secure
+world access control enforcement, or hardware and software
enforcement, respectively.</p>
-<p>Implementations are required to:</p>
+<p>All implementations:</p>
<ul>
<li>Enforce exact matching (not enforcement) of all authorizations.
- Authorization lists in key blobs must exactly match the authorizations
- returned during key generation, including ordering. Any mismatch must cause an
+ Authorization lists in key blobs exactly match the authorizations
+ returned during key generation, including ordering. Any mismatch causes an
error diagnostic.
<li>Declare the authorizations whose semantic values are enforced.
@@ -215,20 +224,27 @@ expiration, then a request for key characteristics will find
list, and attempts to use the key after expiration will fail even if the
keystore is somehow subverted or bypassed.</p>
+<p>For more information about determining whether keys are hardware-backed,
+see <a href="/security/keystore/attestation">Key attestation</a>.
+
<h3 id=cryptographic_message_construction_authorizations>Cryptographic message construction authorizations</h3>
<p>The following tags are used to define the cryptographic characteristics of
-operations using the associated key: <code>KM_TAG_ALGORITHM</code>, <code>KM_TAG_KEY_SIZE</code>,
-<code>KM_TAG_BLOCK_MODE</code>, <code>KM_TAG_PADDING</code>, <code>KM_TAG_CALLER_NONCE</code>, and <code>KM_TAG_DIGEST</code></p>
+operations using the associated key: <code>KM_TAG_ALGORITHM</code>,
+<code>KM_TAG_KEY_SIZE</code>, <code>KM_TAG_BLOCK_MODE</code>,
+<code>KM_TAG_PADDING</code>, <code>KM_TAG_CALLER_NONCE</code>,
+and <code>KM_TAG_DIGEST</code></p>
-<p><code>KM_TAG_PADDING</code>, <code>KM_TAG_DIGEST</code>, and <code>KM_PAD_BLOCK_MODE</code>
-are repeatable, meaning that multiple values may be associated with a single
-key, and the value to be used will be specified at operation time.</p>
+<p><code>KM_TAG_PADDING</code>, <code>KM_TAG_DIGEST</code>,
+and <code>KM_PAD_BLOCK_MODE</code> are repeatable, meaning that multiple values
+may be associated with a single key, and the value to be used is specified at
+operation time.</p>
<h3 id=purpose>Purpose</h3>
<p>Keys have an associated set of purposes, expressed as one or more authorization
-entries with tag <code>KM_TAG_PURPOSE</code>, which defines how they can be used. The purposes are:</p>
+entries with tag <code>KM_TAG_PURPOSE</code>, which defines how they can be used.
+The purposes are:</p>
<ul>
<li><code>KM_PURPOSE_ENCRYPT</code>
@@ -264,41 +280,41 @@ hardware will have the value <code>KM_ORIGIN_IMPORTED</code>.</p>
<h3 id=user_authentication>User authentication</h3>
<p>Secure Keymaster implementations do not implement user authentication, but
-depend on other trusted apps which do. For the interface that must be
-implemented by these apps, see the Gatekeeper page.</p>
+depend on other trusted apps which do. For the interface that these apps
+implement, see the <a href="/security/authentication/gatekeeper">Gatekeeper page</a>.</p>
<p>User authentication requirements are specified via two sets of tags. The first
set indicate which user can use the key:</p>
<ul>
<li><code>KM_TAG_ALL_USERS</code> indicates the key is usable by all users. If
- present, <code>KM_TAG_USER_ID</code> and <code>KM_TAG_USER_SECURE_ID</code> must not be present.
- <li><code>KM_TAG_USER_ID</code> has a numeric value specifying the ID of the authorized user.
- Note that this
-is the Android user ID (for multi-user), not the application UID, and it is
-enforced by non-secure software only. If present, <code>KM_TAG_ALL_USERS</code> must not be present.
- <li><code>KM_TAG_USER_SECURE_ID</code> has a 64-bit numeric value specifying the secure user ID
- that must be provided
-in a secure authentication token to unlock use of the key. If repeated, the key
-may be used if any of the values is provided in a secure authentication token.
+ present, <code>KM_TAG_USER_ID</code> and <code>KM_TAG_USER_SECURE_ID</code> is
+ not present.</li>
+ <li><code>KM_TAG_USER_ID</code> has a numeric value specifying the ID of the
+ authorized user. Note that this is the Android user ID (for multi-user), not
+ the application UID, and it is enforced by non-secure software only. If
+ present, <code>KM_TAG_ALL_USERS</code> is not present.</li>
+ <li><code>KM_TAG_USER_SECURE_ID</code> has a 64-bit numeric value specifying
+ the secure user ID that is provided in a secure authentication token to
+ unlock use of the key. If repeated, the key may be used if any of the values
+ is provided in a secure authentication token.</li>
</ul>
-<p>The second set indicate whether and when the user must be authenticated. If
-neither of these tags is present, but <code>KM_TAG_USER_SECURE_ID</code> is, authentication is
-required for every use of the key.</p>
+<p>The second set indicates whether and when the user needs to be authenticated.
+If neither of these tags is present, but <code>KM_TAG_USER_SECURE_ID</code> is,
+authentication is required for every use of the key.</p>
<ul>
- <li><code>KM_NO_AUTHENTICATION_REQUIRED</code> indicates no user authentication is required, though
- the key still may only be
-used by apps running as the user(s) specified by <code>KM_TAG_USER_ID</code>.
- <li><code>KM_TAG_AUTH_TIMEOUT</code> is a numeric value specifying, in seconds, how fresh the user
- authentication
-must be to authorize key usage. This applies only to private/secret key
-operations. Public key operations don't require authentication. Timeouts do not
-cross reboots; after a reboot, all keys are "never authenticated." The timeout
-may be set to a large value to indicate that authentication is required once
-per boot (2^32 seconds is ~136 years; presumably Android devices are rebooted
-more often than that).
+ <li><code>KM_NO_AUTHENTICATION_REQUIRED</code> indicates no user
+ authentication is required, though the key still may only be used by apps
+ running as the user(s) specified by <code>KM_TAG_USER_ID</code>.</li>
+ <li><code>KM_TAG_AUTH_TIMEOUT</code> is a numeric value specifying, in
+ seconds, how fresh the user authentication needs to be to authorize key usage.
+ This applies only to private/secret key operations. Public key operations
+ don't require authentication. Timeouts do not cross reboots; after a reboot,
+ all keys are "never authenticated." The timeout may be set to a large value to
+ indicate that authentication is required once per boot (2^32 seconds is ~136
+ years; presumably Android devices are rebooted more often than that).</li>
</ul>
<h3 id=client_binding>Client binding</h3>
@@ -309,14 +325,14 @@ application, is done via an optional client ID and some optional client data
respectively). Keystore treats these values as opaque blobs, only ensuring that
the same blobs presented during key generation/import are presented for every
use and are byte-for-byte identical. The client binding data is not returned by
-Keymaster. The caller must know it in order to use the key.</p>
+Keymaster. The caller has to know it in order to use the key.</p>
<p>This feature is not exposed to applications.
<h3 id=expiration>Expiration</h3>
<p>Keystore supports restricting key usage by date. Key start of validity and
-key expirations can be associated with a key and Keymaster will refuse to
+key expirations can be associated with a key and Keymaster refuses to
perform key operations if the current date/time is outside of the valid
range. The key validity range is specified with the tags
<code>KM_TAG_ACTIVE_DATETIME</code>,
@@ -327,9 +343,10 @@ range. The key validity range is specified with the tags
ciphertext/signature/etc. Note that this distinction is not exposed to
applications.</p>
-<p>The <code>KM_TAG_ACTIVE_DATETIME</code>, <code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code>,
-and <code>KM_TAG_USAGE_EXPIRE_DATETIME</code> tags are optional. If the tags are absent, it is
-assumed that the key in
+<p>The <code>KM_TAG_ACTIVE_DATETIME</code>,
+<code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code>,
+and <code>KM_TAG_USAGE_EXPIRE_DATETIME</code> tags are optional. If the tags
+are absent, it is assumed that the key in
question can always be used to decrypt/verify messages.</p>
<p>Because wall-clock time is provided by the non-secure world, it's unlikely that
@@ -342,13 +359,13 @@ trusted remote timeserver.</p>
<p>Keystore requires keys to be bound to a root of trust, which is a bitstring
provided to the Keymaster secure hardware during startup, preferably by the
-bootloader. This bitstring must be cryptographically bound to every key managed
+bootloader. This bitstring is cryptographically bound to every key managed
by Keymaster.</p>
<p>The root of trust consists of the public key used to verify the signature on
the boot image and the lock state of the device. If the public key is changed to
allow a different system image to be used or if the lock state is changed, then
-none of the Keymaster-protected keys created by the previous system will be
+none of the Keymaster-protected keys created by the previous system are
usable, unless the previous root of trust is restored and a system that is
signed by that key is booted. The goal is to increase the value of the
software-enforced key access controls by making it impossible for an
@@ -359,7 +376,7 @@ attacker-installed operating system to use Keymaster keys.</p>
<p>Some Keymaster secure hardware may choose to store key material internally
and return handles rather than encrypted key material. Or there may be other
cases in which keys cannot be used until some other non-secure or secure world
-system component is available. The Keymaster 1.0 HAL allows the caller to
+system component is available. The Keymaster HAL allows the caller to
request that a key be "standalone," via the <code>KM_TAG_STANDALONE</code> tag,
meaning that no resources other than the blob and the running Keymaster system
are required. The tags associated with a key may be inspected to see whether a
@@ -376,37 +393,37 @@ key is standalone. At present, only two values are defined:</p>
<p>When it's created, the maximum usage velocity can be specified
with <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code>.
-TrustZone implementations will refuse to perform cryptographic operations
+TrustZone implementations refuse to perform cryptographic operations
with that key if an operation was performed less
than <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> seconds earlier.</p>
<p>The simple approach to implementing velocity limits is a table of key IDs and
-last-use timestamps. This table will likely be of limited size, but must
-accommodate at least 16 entries. In the event that the table is full and no
-entries may be updated or discarded, secure hardware implementations must "fail
+last-use timestamps. This table will likely be of limited size, but
+accommodates at least 16 entries. In the event that the table is full and no
+entries may be updated or discarded, secure hardware implementations "fail
safe," preferring to refuse all velocity-limited key operations until one of the
entries expires. It is acceptable for all entries to expire upon reboot.</p>
<p>Keys can also be limited to <em>n</em> uses per boot with
-<code>KM_TAG_MAX_USES_PER_BOOT</code>. This also requires a tracking table,
-which must accommodate at least four keys, and must also fail safe. Note that
-applications will be unable to create per-boot limited keys. This feature will
-not be exposed through Keystore and will be reserved for system operations.</p>
+<code>KM_TAG_MAX_USES_PER_BOOT</code>. This also requires a tracking table,
+which accommodates at least four keys and also fails safe. Note that
+applications will be unable to create per-boot limited keys. This feature
+is not exposed through Keystore and is reserved for system operations.</p>
<p>This feature is not exposed to applications.</p>
<h3 id=random_number_generator_re-seeding>Random number generator re-seeding</h3>
-<p>Because secure hardware must generate random numbers for key material and
+<p>Because secure hardware generates random numbers for key material and
Initialization Vectors (IVs), and because hardware random number generators may
not always be fully trustworthy, the Keymaster HAL provides an interface to
allow the client to provide additional entropy which will be mixed into the
random numbers generated.</p>
-<p>A hardware random-number generator must be used as the primary seed source,
-and the seed data provided through the external API must not be the sole source
+<p>Use a hardware random-number generator as the primary seed source.
+The seed data provided through the external API can't be the sole source
of randomness used for number generation. Further, the mixing operation used
-must ensure that the random output is unpredictable if any one of the seed
+needs to ensure that the random output is unpredictable if any one of the seed
sources is unpredictable.</p>
<p>This feature is not exposed to applications but is used by the framework,
diff --git a/en/security/keystore/implementer-ref.html b/en/security/keystore/implementer-ref.html
index c0b2ad93..9043b30a 100644
--- a/en/security/keystore/implementer-ref.html
+++ b/en/security/keystore/implementer-ref.html
@@ -1,10 +1,10 @@
<html devsite>
<head>
- <title>Implementer's Reference</title>
+ <title>Keymaster Functions</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
- <body>
+<body>
<!--
Copyright 2017 The Android Open Source Project
@@ -20,567 +20,44 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<p>This page provides details to assist implementers of Keymaster HALs.
+It covers each function in the API and which Keymaster version that
+function is available in. It describes the default implementation.
+For tags, see the
+<a href="/security/keystore/tags">Keymaster Tags</a> page.</p>
-
-
-<p>This page provides details to assist implementers of <a href="index.html">Keymaster</a> HALs. It
-covers each tag and each function in the HAL.</p>
-
-<h2 id=authorization_tags>Authorization tags</h2>
-
-<p>Except as noted in the tag descriptions, all of the tags below are used during
-key generation to specify key characteristics.</p>
-
-<h3 id=km_tag_purpose>KM_TAG_PURPOSE</h3>
-
-<p>Specifies the set of purposes for which the key may be used.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_PURPOSE_ENCRYPT = 0,
- KM_PURPOSE_DECRYPT = 1,
- KM_PURPOSE_SIGN = 2,
- KM_PURPOSE_VERIFY = 3,
-} keymaster_purpose_t;
-</pre>
-
-<p>This tag is repeatable; keys may be generated with multiple values, although an
-operation has a single purpose. When the <a href="#begin">begin</a> function is called to
-start an operation, the purpose of the operation is
-specified. If the purpose specified to the operation is not authorized by the
-key, the operation must fail with <code>KM_ERROR_INCOMPATIBLE_PURPOSE</code>.</p>
-
-<h3 id=km_tag_algorithm>KM_TAG_ALGORITHM</h3>
-
-<p>Specifies the cryptographic algorithm with which the key is used.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_ALGORITHM_RSA = 1,
- KM_ALGORITHM_EC = 3,
- KM_ALGORITHM_AES = 32,
- KM_ALGORITHM_HMAC = 128,
-} keymaster_algorithm_t;
-</pre>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_key_size>KM_TAG_KEY_SIZE</h3>
-
-<p>Specifies the size, in bits, of the key, measuring in the normal way for the
-key's algorithm. For example, for RSA keys, <code>KM_TAG_KEY_SIZE</code> specifies
-the size of the public modulus. For AES keys it specifies the length
-of the secret key material.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_block_mode>KM_TAG_BLOCK_MODE</h3>
-
-<p>Specifies the block cipher mode(s) with which the key may be used. This tag is
-only relevant to AES keys.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_MODE_ECB = 1,
- KM_MODE_CBC = 2,
- KM_MODE_CTR = 3,
- KM_MODE_GCM = 32,
-} keymaster_block_mode_t;
-</pre>
-
-<p>This tag is repeatable, and for AES key operations a mode must be specified in
-the <code>additional_params</code> argument of <a href="#begin">begin</a>. If the specified
-mode is not in the modes associated with the key, the
-operation must fail with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
-
-<h3 id=km_tag_digest>KM_TAG_DIGEST</h3>
-
-<p>Specifies the digest algorithms which may be used with the key to perform
-signing and verification operations. This tag is relevant to RSA, ECDSA and
-HMAC keys.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_DIGEST_NONE = 0,
- KM_DIGEST_MD5 = 1,
- KM_DIGEST_SHA1 = 2,
- KM_DIGEST_SHA_2_224 = 3,
- KM_DIGEST_SHA_2_256 = 4,
- KM_DIGEST_SHA_2_384 = 5,
- KM_DIGEST_SHA_2_512 = 6,
-}
-keymaster_digest_t;
-</pre>
-
-<p>This tag is repeatable. For signing and verification operations a digest must
-be specified in the <code>additional_params</code> argument of <a href="#begin">begin</a>.
-If the specified digest is not in the digests associated with the key, the
-operation must fail with <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.</p>
-
-<h3 id=km_tag_padding>KM_TAG_PADDING</h3>
-
-<p>Specifies the padding modes which may be used with the key. This tag is
-relevant to RSA and AES keys.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_PAD_NONE = 1,
- KM_PAD_RSA_OAEP = 2,
- KM_PAD_RSA_PSS = 3,
- KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4,
- KM_PAD_RSA_PKCS1_1_5_SIGN = 5,
- KM_PAD_PKCS7 = 64,
-} keymaster_padding_t;
-</pre>
-
-<p><code>KM_PAD_RSA_OAEP</code> and <code>KM_PAD_RSA_PKCS1_1_5_ENCRYPT</code> are used
-only for RSA encryption/decryption keys and specify RSA PKCS#1v2 OAEP
-padding and RSA PKCS#1 v1.5 randomized padding, respectively. <code>KM_PAD_RSA_PSS</code> and
-<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> are used only for RSA signing/verification keys and
-specify RSA PKCS#1v2 PSS
-padding and RSA PKCS#1 v1.5 deterministic padding, respectively. Note also that
-the RSA PSS padding mode is incompatible with <a href="#km_tag_digest">KM_DIGEST_NONE</a>.</p>
-
-<p><code>KM_PAD_NONE</code> may be used with either RSA or AES keys. For AES keys,
-if <code>KM_PAD_NONE</code> is used with block mode ECB or CBC and the data to be encrypted
-or decrypted
-is not a multiple of the AES block size in length, the call to finish must fail
-with <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</p>
-
-<p><code>KM_PAD_PKCS7</code> may only be used with AES keys, and only with ECB and CBC modes.</p>
-
-<p>This tag is repeatable. A padding mode must be specified in the call to
-<a href="#begin">begin</a>. If the specified mode is not authorized for the key,
-the operation must fail
-with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
-
-<h3 id=km_tag_caller_nonce>KM_TAG_CALLER_NONCE</h3>
-
-<p>Specifies that the caller is allowed to provide a nonce for nonce-requiring
-operations.</p>
-
-<p>This tag is boolean, so the possible values are true (if the tag is present)
-and false (if the tag is not present).</p>
-
-<p>This tag is used only for AES keys, and is only relevant for CBC, CTR and GCM
-block modes. If the tag is not present, implementations should reject any
-operation which provides <a href="#km_tag_nonce">KM_TAG_NONCE</a> to <a href="#begin">begin</a>
-with <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_min_mac_length>KM_TAG_MIN_MAC_LENGTH</h3>
-
-<p>Required for HMAC keys and AES keys that support GCM mode, this tag specifies
-the minimum length of MAC that can be requested or verified with this key.</p>
-
-<p>This value is the minimum MAC length, in bits. It must be a multiple of 8. For
-HMAC keys, the value must be at least 64. For GCM keys it must be at least 96
-and must not exceed 128.</p>
-
-<h3 id=km_tag_rsa_public_exponent>KM_TAG_RSA_PUBLIC_EXPONENT</h3>
-
-<p>Specifies the value of the public exponent for an RSA key pair. This tag is
-relevant only to RSA keys, and required for all RSA keys.</p>
-
-<p>The value is a 64-bit unsigned integer that must satisfy the requirements of an
-RSA public exponent. Because it is specified by the caller and therefore cannot
-be chosen by the implementation, it must be a prime number. Trustlets are
-required to support the value 2^16+1. It is recommended that other reasonable
-values be supported, in particular the value 3. If no exponent is specified or
-if the specified exponent is not supported, key generation must fail
-with <code>KM_ERROR_INVALID_ARGUMENT</code>.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_blob_usage_requirements>KM_TAG_BLOB_USAGE_REQUIREMENTS</h3>
-
-<p>Specifies the system environment conditions which must hold for the generated
-key to be used.</p>
-
-<p>Possible values are defined by the following enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_BLOB_STANDALONE = 0,
- KM_BLOB_REQUIRES_FILE_SYSTEM = 1,
-} keymaster_key_blob_usage_requirements_t;
-</pre>
-
-<p>This tag may be specified during key generation to require that the key be
-usable in the specified condition, and must be returned with the key
-characteristics (from <a href="#generate_key">generate_key</a> and
-<a href="#get_key_characteristics">get_key_characteristics</a>). If
-the caller specifies <code>KM_TAG_BLOB_USAGE_REQUIREMENTS</code> with
-value <code>KM_BLOB_STANDALONE</code> the trustlet must return a key blob
-which can be used without file system
-support. This is critical for devices with encrypted disks, where the file
-system may not be available until after a Keymaster key is used to decrypt the
-disk.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_bootloader_only>KM_TAG_BOOTLOADER_ONLY</h3>
-
-<p>Specifies that the key may only be used by the bootloader.</p>
-
-<p>This tag is boolean, so the possible values are true (if the tag is present)
-and false (if the tag is not present).</p>
-
-<p>Any attempt to use a key with <code>KM_TAG_BOOTLOADER_ONLY</code> from the
-Android system must fail with <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_active_datetime>KM_TAG_ACTIVE_DATETIME</h3>
-
-<p>Specifies the date and time at which the key becomes active. Prior to this
-time, any attempt to use the key must fail with <code>KM_ERROR_KEY_NOT_YET_VALID</code>.</p>
-
-<p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_origination_expire_datetime>KM_TAG_ORIGINATION_EXPIRE_DATETIME</h3>
-
-<p>Specifies the date and time at which the key expires for signing and encryption
-purposes. After this time, any attempt to use a key
-with <a href="#km_tag_purpose">KM_PURPOSE_SIGN</a> or
-<a href="#km_tag_purpose">KM_PURPOSE_ENCRYPT</a> provided
-to <a href="#begin">begin</a> must fail with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
-
-<p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_usage_expire_datetime>KM_TAG_USAGE_EXPIRE_DATETIME</h3>
-
-<p>Specifies the date and time at which the key expires for verification and
-decryption purposes. After this time, any attempt to use a key with
-<a href="#km_tag_purpose">KM_PURPOSE_VERIFY</a> or <a href="#km_tag_purpose">KM_PURPOSE DECRYPT</a>
-provided to <a href="#begin">begin</a> must fail with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
-
-<p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_min_seconds_between_ops>KM_TAG_MIN_SECONDS_BETWEEN_OPS</h3>
-
-<p>Specifies the minimum amount of time that must elapse between allowed
-operations using a key. This can be used to rate-limit uses of keys in contexts
-where unlimited use may enable brute force attacks.</p>
-
-<p>The value is a 32-bit integer representing seconds between allowed operations.</p>
-
-<p>When a key with this tag is used in an operation, a timer should be started
-during the <a href="#finish">finish</a> or <a href="#abort">abort</a> call. Any
-call to <a href="#begin">begin</a> that is received before the timer indicates
-that the interval specified by <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> has
-elapsed must fail with <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>. This
-requirement implies that a trustlet must keep a table of timers for keys
-with this tag. Because Keymaster memory is often limited, it is acceptable for
-this table to have a fixed maximum size and for Keymaster to fail operations
-which attempt to use keys with this tag when the table is full. At least 32
-in-use keys must be accommodated, and table slots must be aggressively reused
-when key minimum-usage intervals expire. If an operation fails because the
-table is full, Keymaster should return <code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_max_uses_per_boot>KM_TAG_MAX_USES_PER_BOOT</h3>
-
-<p>Specifies the maximum number of times that a key may be used between system
-reboots. This is another mechanism to rate-limit key use.</p>
-
-<p>The value is a 32-bit integer representing uses per boot.</p>
-
-<p>When a key with this tag is used in an operation, a key-associated counter
-should be incremented during the <a href="#begin">begin</a> call. After the key counter
-has exceeded this value, all subsequent attempts
-to use the key must fail with <code>KM_ERROR_MAX_OPS_EXCEEDED</code>, until the device is
-restarted. This requirement implies that a trustlet must
-keep a table of use counters for keys with this tag. Because Keymaster memory
-is often limited, it is acceptable for this table to have a fixed maximum size
-and for Keymaster to fail operations that attempt to use keys with this tag
-when the table is full. At least 16 keys must be accommodated. If an operation
-fails because the table is full, Keymaster should return <code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_user_secure_id>KM_TAG_USER_SECURE_ID</h3>
-
-<p>Specifies that a key may only be used under a particular secure user
-authentication state. This tag is mutually exclusive
-with <a href="#km_tag_no_auth_required">KM_TAG_NO_AUTH_REQUIRED</a>.</p>
-
-<p>The value is a 64-bit integer specifying the authentication policy state value
-which must be present in an authentication token (provided to <a href="#begin">begin</a> with
-the <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a>) to authorize use of the key. Any
-call to <a href="#begin">begin</a> with a key with this tag that does not provide an
-authentication token, or provides an
-authentication token without a matching policy state value, must fail.</p>
-
-<p>This tag is repeatable. If any of the provided values matches any policy state
-value in the authentication token, the key is authorized for use. Otherwise the operation
-must fail with <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
-
-<h3 id=km_tag_no_auth_required>KM_TAG_NO_AUTH_REQUIRED</h3>
-
-<p>Specifies that no authentication is required to use this key. This tag is
-mutually exclusive with <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>.</p>
-
-<p>This tag is boolean, so the possible values are true (if the tag is present)
-and false (if the tag is not present).</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_user_auth_type>KM_TAG_USER_AUTH_TYPE</h3>
-
-<p>Specifies the types of user authenticators that may be used to authorize this
-key. When Keymaster is requested to perform an operation with a key with this
-tag, it must receive an authentication token, and the token's
-<code>authenticator_type</code> field must match the value in the tag. To be
-precise, it must be true that <code>(ntoh(token.authenticator_type) &
-auth_type_tag_value) != 0</code>, where <code>ntoh</code> is a function that converts
-network-ordered integers to host-ordered integers and
-<code>auth_type_tag_value</code> is the value of this tag.</p>
-
-<p>The value is a 32-bit integer bitmask of values from the enumeration:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- HW_AUTH_NONE = 0,
- HW_AUTH_PASSWORD = 1 &lt;&lt; 0,
- HW_AUTH_FINGERPRINT = 1 &lt;&lt; 1,
- // Additional entries should be powers of 2.
- HW_AUTH_ANY = UINT32_MAX,
-} hw_authenticator_type_t;
-</pre>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_auth_timeout>KM_TAG_AUTH_TIMEOUT</h3>
-
-<p>Specifies the time in seconds for which the key is authorized for use, after
-authentication. If <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> is present and this tag
-is not, then the key requires authentication for every
-usage (see <a href="#begin">begin</a> for the details of the authentication-per-operation flow).</p>
-
-<p>The value is a 32-bit integer specifying the time in seconds after a successful
-authentication of the user specified by <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> with
-the authentication method specified
-by <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> that the key can be used.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_all_applications>KM_TAG_ALL_APPLICATIONS</h3>
-
-<p>Reserved for future use.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_application_id>KM_TAG_APPLICATION_ID</h3>
-
-<p>When provided to <a href="#generate_key">generate_key</a> or <a href="#import_key">import_key</a>,
-this tag specifies data that must be provided during all uses of the key. In
-particular, calls to <a href="#export_key">export_key</a> and
-<a href="#get_key_characteristics">get_key_characteristics</a> must
-provide the same value in the <code>client_id</code> parameter, and
-calls to <a href="#begin">begin</a> must provide this tag and the
-same associated data as part of the <code>in_params</code> set. If the correct
-data is not provided the function must return <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
-
-<p>The content of this tag must be bound to the key <i>cryptographically</i>,
-meaning it must not be possible for an adversary who has access to all of the
-secure world secrets but does not have access to the tag content to decrypt the
-key (without brute-forcing the tag content).</p>
-
-<p>The value is a blob, an arbitrary-length array of bytes.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_application_data>KM_TAG_APPLICATION_DATA</h3>
-
-<p>When provided to <a href="#generate_key">generate_key</a> or <a href="#import_key">import_key</a>,
-this tag specifies data that must be provided during all uses of the key. In
-particular, calls to <a href="#export_key">export_key</a> and
-<a href="#get_key_characteristics">get_key_characteristics</a> must
-provide the same value to the <code>client_id</code> parameter, and calls
-to <a href="#begin">begin</a> must provide this tag and the same associated
-data as part of the <code>in_params</code> set. If the correct data is not
-provided, the function must return <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
-
-<p>The content of this tag must be bound to the key <i>cryptographically</i>,
-meaning it must not be possible for an adversary who has access to all of the
-secure world secrets but does not have access to the tag content to decrypt the
-key (without brute-forcing the tag content, which applications can prevent by
-specifying sufficiently high-entropy content).</p>
-
-<p>The value is a blob, an arbitrary-length array of bytes.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_creation_datetime>KM_TAG_CREATION_DATETIME</h3>
-
-<p>Specifies the date and time the key was created, in milliseconds since January
-1, 1970. This tag is optional and informational only.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_origin>KM_TAG_ORIGIN</h3>
-
-<p>Specifies where the key was created, if known. This tag may not be specified
-during key generation or import, and must be added to the key characteristics
-by the trustlet.</p>
-
-<p>The possible values are defined in <code>keymaster_origin_t</code>:</p>
-
-<pre class="devsite-click-to-copy">
-typedef enum {
- KM_ORIGIN_GENERATED = 0,
- KM_ORIGIN_IMPORTED = 2,
- KM_ORIGIN_UNKNOWN = 3,
-} keymaster_key_origin_t
-</pre>
-
-<p>The full meaning of the value depends not only on the value but on whether it's
-found in the hardware-enforced or software-enforced characteristics list.</p>
-
-<p><code>KM_ORIGIN_GENERATED</code> indicates that Keymaster generated the key.
-If in the hardware-enforced list,
-the key was generated in secure hardware and is permanently hardware-bound. If
-in the software-enforced list, the key was generated in SoftKeymaster and is
-not hardware-bound.</p>
-
-<p><code>KM_ORIGIN_IMPORTED</code> indicates that the key was generated outside
-of Keymaster and imported into
-Keymaster. If in the hardware-enforced list, it is permanently hardware-bound,
-although copies outside of secure hardware may exist. If in the
-software-enforces list, the key was imported into SoftKeymaster and is not
-hardware-bound.</p>
-
-<p><code>KM_ORIGIN_UNKNOWN</code> should only appear in the hardware-enforced list.
-It indicates that the key is
-hardware-bound, but it is not known whether the key was originally generated in
-secure hardware or was imported. This only occurs when keymaster0 hardware is
-being used to emulate keymaster1 services.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_rollback_resistant>KM_TAG_ROLLBACK_RESISTANT</h3>
-
-<p>Indicates that the key is rollback-resistant, meaning that when deleted
-by <a href="#delete_key">delete_key</a> or <a href="#delete_all_keys">delete_all_keys</a>,
-the key is guaranteed to be permanently deleted and unusable. It's possible
-that keys without this tag could be deleted and then restored from backup.</p>
-
-<p>This tag is boolean, so the possible values are true (if the tag is present)
-and false (if the tag is not present).</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_root_of_trust>KM_TAG_ROOT_OF_TRUST</h3>
-
-<p>Specifies the "root of trust," the key used by verified boot to validate the
-operating system booted (if any). This tag is never provided to or returned
-from Keymaster in the key characteristics.</p>
-
-<h3 id=km_tag_associated_data>KM_TAG_ASSOCIATED_DATA</h3>
-
-<p>Provides "associated data" for AES-GCM encryption or decryption. This tag is
-provided to <a href="#update">update</a> and specifies data that is not
-encrypted/decrypted but is used in computing
-the GCM tag.</p>
-
-<p>The value is a blob, an arbitrary-length array of bytes.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_nonce>KM_TAG_NONCE</h3>
-
-<p>Provides or returns a nonce or Initialization Vector (IV) for AES GCM, CBC or
-CTR encryption or decryption. This tag is provided to <a href="#begin">begin</a>
-during encryption and decryption operations. It may only be provided to <a href="#begin">begin</a>
-if the key has <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a>. If not provided,
-an appropriate nonce or IV will be randomly generated by
-Keymaster and returned from begin.</p>
-
-<p>The value is a blob, an arbitrary-length array of bytes. Allowed lengths depend
-on the mode: GCM nonces are 12 bytes in length; CBC and CTR IVs are 16 bytes in
-length.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_auth_token>KM_TAG_AUTH_TOKEN</h3>
-
-<p>Provides an authentication token (see the Authentication page) to
-<a href="#begin">begin</a>, <a href="#update">update</a> or <a href="#finish">finish</a>,
-to prove user authentication for a key operation that requires
-it (key has <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>).</p>
-
-<p>The value is a blob which contains a <code>hw_auth_token_t</code> structure.</p>
-
-<p>This tag is not repeatable.</p>
-
-<h3 id=km_tag_mac_length>KM_TAG_MAC_LENGTH</h3>
-
-<p>Provides the requested length of a MAC or GCM authentication tag, in bits.</p>
-
-<p>The value is the MAC length in bits. It must be a multiple of 8 and must be at
-least as large as the value of <a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
-associated with the key.</p>
-
-<h2 id=functions>Functions</h2>
-
-<h3 id=deprecated_functions>Deprecated functions</h3>
-
-<p>The following functions are in the <code>keymaster1_device_t</code> definition but
-should not be implemented. The function pointers should be set
-to <code>NULL</code>:</p>
-
-<ul>
- <li><code>generate_keypair</code>
- <li><code>import_keypair</code>
- <li><code>get_keypair_public</code>
- <li><code>delete_keypair</code>
- <li><code>delete_all</code>
- <li><code>sign_data</code>
- <li><code>verify_data</code>
-</ul>
-
-<h3 id=general_implementation_guidelines>General implementation guidelines</h3>
+<h2 id="general_implementation_guidelines">General implementation guidelines</h2>
<p>The following guidelines apply to all functions in the API.</p>
-<h4 id=input_pointer_parameters>Input pointer parameters</h4>
+<h3 id="input_pointer_parameters">Input pointer parameters</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Input pointer parameters that are not used for a given call may be <code>NULL</code>.
The caller is not required to provide placeholders. For example, some key
types and modes may not use any values from the <code>in_params</code> argument
to <a href="#begin">begin</a>, so the caller may set <code>in_params</code>
-to <code>NULL</code> or provide an empty parameter set. It is also acceptable for the caller to
+to <code>NULL</code> or provide an empty parameter set. Callers can also
provide unused parameters, and Keymaster methods should not issue errors.</p>
<p>If a required input parameter is NULL, Keymaster methods should return
<code>KM_ERROR_UNEXPECTED_NULL_POINTER</code>.</p>
-<h4 id=output_pointer_parameters>Output pointer parameters</h4>
+
+<h3 id="output_pointer_parameters">Output pointer parameters</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Similar to input pointer parameters, unused output pointer parameters
may be <code>NULL</code>. If a method needs to return data in an output
-parameter found to be <code>NULL</code>, it should return <code>KM_ERROR_OUTPUT_PARAMETER_NULL</code>.</p>
+parameter found to be <code>NULL</code>, it should return
+<code>KM_ERROR_OUTPUT_PARAMETER_NULL</code>.</p>
+
-<h4 id=api_misuse>API misuse</h4>
+<h3 id="api_misuse">API misuse</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>There are many ways that callers can make requests that don't make sense or are
foolish but not technically wrong. Keymaster1 implementations are not required
@@ -593,232 +70,263 @@ invalid required parameters, and similar errors must be diagnosed.</p>
<p>It is the responsibility of apps, the framework, and Android keystore to ensure
that the calls to Keymaster modules are sensible and useful.</p>
-<h3 id=get_supported_algorithms>get_supported_algorithms</h3>
+<h2 id="functions">Functions</h2>
+
+<h3 id="get_supported_algorithms">get_supported_algorithms</h3>
+
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of algorithms supported by the Keymaster hardware
-implementation. A software implementation must return an empty list; a hybrid
-implementation must return a list containing only the algorithms that are
+implementation. A software implementation returns an empty list; a hybrid
+implementation returns a list containing only the algorithms that are
supported by hardware.</p>
-<p>Keymaster1 implementations must support RSA, EC, AES and HMAC.</p>
+<p>Keymaster 1 implementations support RSA, EC, AES and HMAC.</p>
-<h3 id=get_supported_block_modes>get_supported_block_modes</h3>
+
+<h3 id="get_supported_block_modes">get_supported_block_modes</h3>
+
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of AES block modes supported by the Keymaster hardware
implementation for a specified algorithm and purpose.</p>
-<p>For RSA, EC and HMAC, which are not block ciphers, the method must return an
+<p>For RSA, EC and HMAC, which are not block ciphers, the method returns an
empty list for all valid purposes. Invalid purposes should cause the method to
return <code>KM_ERROR_INVALID_PURPOSE</code>.</p>
-<p>Keymaster1 implementations must support ECB, CBC, CTR and GCM for AES
+<p>Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES
encryption and decryption.</p>
-<h3 id=get_supported_padding_modes>get_supported_padding_modes</h3>
+
+<h3 id="get_supported_padding_modes">get_supported_padding_modes</h3>
+
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of padding modes supported by the Keymaster hardware
implementation for a specified algorithm and purpose.</p>
-<p>HMAC and EC have no notion of padding so the method must return an empty list
-for all valid purposes. Invalid purposes should cause the method to return <code>KM_ERROR_INVALID_PURPOSE</code>.</p>
+<p>HMAC and EC have no notion of padding so the method returns an empty list
+for all valid purposes. Invalid purposes should cause the method to return
+<code>KM_ERROR_INVALID_PURPOSE</code>.</p>
-<p>For RSA, keymaster1 implementations must support:</p>
+<p>For RSA, Keymaster 1 implementations support:</p>
<ul>
<li>Unpadded encryption, decryption, signing and verification. For unpadded
encryption and signing, if the message is shorter than the public modulus,
implementations must left-pad it with zeros. For unpadded decryption and
-verification, the input length must match the public modulus size.
- <li>PKCS#1 v1.5 encryption and signing padding modes
- <li>PSS with a minimum salt length of 20
- <li>OAEP
+verification, the input length must match the public modulus size.</li>
+ <li>PKCS#1 v1.5 encryption and signing padding modes</li>
+ <li>PSS with a minimum salt length of 20</li>
+ <li>OAEP</li>
</ul>
-<p>For AES in ECB and CBC modes, keymaster1 implementations must support no
-padding and PKCS#7-padding. CTR and GCM modes must support only no padding.</p>
+<p>For AES in ECB and CBC modes, Keymaster 1 implementations support no
+padding and PKCS#7-padding. CTR and GCM modes support only no padding.</p>
+
+
+<h3 id="get_supported_digests">get_supported_digests</h3>
-<h3 id=get_supported_digests>get_supported_digests</h3>
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of digest modes supported by the Keymaster hardware
implementation for a specified algorithm and purpose.</p>
-<p>No AES modes support or require digesting, so the method must return an empty
+<p>No AES modes support or require digesting, so the method returns an empty
list for valid purposes.</p>
-<p>Keymaster1 implementations are allowed to implement a subset of the defined
-digests, but must provide SHA-256. It is strongly recommended that keymaster1
-implementations provide MD5, SHA1, SHA-224, SHA-256, SHA384 and SHA512 (the
-full set of defined digests).</p>
+<p>Keymaster 1 implementations can implement a subset of the defined
+digests. Implementations provide SHA-256 and can provide MD5, SHA1, SHA-224,
+SHA-256, SHA384 and SHA512 (the full set of defined digests).</p>
-<h3 id=get_supported_import_formats>get_supported_import_formats</h3>
+<h3 id="get_supported_import_formats">get_supported_import_formats</h3>
+
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of import formats supported by the Keymaster hardware
implementation of a specified algorithm.</p>
-<p>Keymaster1 implementations must support the PKCS#8 format (without password
-protection) for importing RSA and EC key pairs, and must support RAW import of
+<p>Keymaster 1 implementations support the PKCS#8 format (without password
+protection) for importing RSA and EC key pairs, and support RAW import of
AES and HMAC key material.</p>
-<h3 id=get_supported_export_formats>get_supported_export_formats</h3>
+<h3 id="get_supported_export_formats">get_supported_export_formats</h3>
+
+<p><strong>Version</strong>: 1</p>
<p>Returns the list of export formats supported by the Keymaster hardware
implementation of a specified algorithm.</p>
-<p>Keymaster1 implementations must support the X.509 format for exporting RSA and
-EC public keys. Export of private keys or asymmetric keys must not be
-supported.</p>
+<p>Keymaster1 implementations support the X.509 format for exporting RSA and
+EC public keys. Export of private keys or asymmetric keys is not supported.</p>
-<h3 id=add_rng_entropy>add_rng_entropy</h3>
+<h3 id="add_rng_entropy">add_rng_entropy</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Adds caller-provided entropy to the pool used by the Keymaster1 implementation
for generating random numbers, for keys, IVs, etc.</p>
-<p>Keymaster1 implementations must <strong>securely</strong> mix the provided
-entropy into their pool, which must also contain
-internally-generated entropy from a hardware random number generator. Mixing
-must have the property that an attacker with complete control of either
-the <code>add_rng_entropy</code>-provided bits or the hardware-generated bits, but not both, cannot predict
-bits generated from the entropy pool with probability greater than ½.</p>
+<p>Keymaster1 implementations <strong>securely</strong> mix the provided
+entropy into their pool, which also contains
+internally-generated entropy from a hardware random number generator.
+With this structure, an attacker with complete control of either the
+<code>add_rng_entropy</code>-provided bits or the hardware-generated bits,
+but not both, would not have an advangage in predicting the bits generated
+from the entropy pool.</p>
+
+<p>Keymaster implementations that attempt to estimate the entropy in their
+internal pool assume that data provided by
+<code>add_rng_entropy</code> contains no entropy. Keymaster implementations may
+return <code>KM_ERROR_INVALID_INPUT_LENGTH</code> if they're given more than 2
+KiB of data in a single call.</p>
-<p>Keymaster1 implementations that attempt to estimate the entropy in their
-internal pool must assume that data provided by <code>add_rng_entropy</code> contains no entropy.</p>
+<h3 id="generate_key">generate_key</h3>
-<h3 id=generate_key>generate_key</h3>
+<p><strong>Version</strong>: 1, 2</p>
<p>Generates a new cryptographic key, specifying associated authorizations, which
-will be permanently bound to the key. Keymaster1 implementations must make it
+are permanently bound to the key. Keymaster implementations make it
impossible to use a key in any way inconsistent with the authorizations
specified at generation time. With respect to authorizations that the secure
hardware cannot enforce, the secure hardware's obligation is limited to
ensuring that the unenforceable authorizations associated with the key cannot
be modified, so that every call to <a href="#get_key_characteristics">get_key_characteristics</a>
-will return the original value. In addition, the characteristics returned by <code>generate_key</code>
-must allocate authorizations correctly between the hardware-enforced and
-software-enforced lists. See <a href="#get_key_characteristics">get_key_characteristics</a>
+returns the original value. In addition, the characteristics returned by <code>generate_key</code>
+allocates authorizations correctly between the hardware-enforced and
+software-enforced lists. See <a href="#get_key_characteristics">get_key_characteristics</a>
for more details.</p>
-<p>The parameters that must be provided to <code>generate_key</code> depend on the type of key
-being generated. This section will summarize the
-required and allowed tags for each type of key. <a href="#km_tag_algorithm">KM_TAG_ALGORITHM</a>
-is always required, to specify the type.</p>
+<p>The parameters provided to <code>generate_key</code> depend on the type of key
+being generated. This section summarizes the necessary and optional tags for each
+type of key. <a href="/security/keystore/tags#algorithm">KM_TAG_ALGORITHM</a>
+is always necessary, to specify the type.</p>
-<h4 id=rsa_keys>RSA keys</h4>
+<h4 id="rsa_keys">RSA keys</h4>
-<p>The following parameters are required when generating an RSA key.</p>
+<p>The following parameters are necessary to generate an RSA key.</p>
<ul>
- <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> specifies the size of the public
- modulus, in bits. If omitted, the method must
-return <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>. Values that must be supported are
-1024, 2048, 3072 and 4096. It is
-recommended to support all key sizes that are a multiple of 8.
- <li><a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a> specifies
- the RSA public exponent value. If omitted, the method must
- return <code>KM_ERROR_INVALID_ARGUMENT</code>.
- Implementations must support the values 3 and 65537. It is recommended to
-support all prime values up to 2^64.
+ <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
+ specifies the size of the public modulus, in bits. If omitted,
+ the method returns <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>.
+ Supported values are 1024, 2048, 3072 and 4096. Recommended values
+ are all key sizes that are a multiple of 8.</li>
+ <li><a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
+ specifies the RSA public exponent value. If omitted, the method
+ returns <code>KM_ERROR_INVALID_ARGUMENT</code>.
+ Supported values are 3 and 65537. Recommended values are
+ all prime values up to 2^64.</li>
</ul>
-<p>The following parameters are not required to generate an RSA key, but creating
-an RSA key without them will produce a key that is unusable.
-The <code>generate_key</code> function should not return an error if these parameters are omitted.</p>
+<p>The following parameters are not necessary to generate an RSA key, but creating
+an RSA key without them produces a key that is unusable. However, the
+<code>generate_key</code> function doesn't return an error if these parameters are omitted.</p>
<ul>
- <li><a href="#km_tag_purpose">KM_TAG_PURPOSE</a> specifies allowed purposes.
- All purposes must be supported for RSA keys, in
-any combination.
- <li><a href="#km_tag_digest">KM_TAG_DIGEST</a> specifies digest algorithms that
- may be used with the new key. Implementations
-that do not support all digest algorithms must accept key generation requests
-that include unsupported digests. The unsupported digests should be placed in
-the "software-enforced" list in the returned key characteristics. This is
-because the key will be usable with those other digests, but digesting will be
-performed in software. Then hardware will be called to perform the operation
-with <code>KM_DIGEST_NONE</code>.
- <li><a href="#km_tag_padding">KM_TAG_PADDING</a> specifies the padding modes
+ <li><a href="/security/keystore/tags#purpose">KM_TAG_PURPOSE</a> specifies allowed purposes.
+ All purposes need to be supported for RSA keys, in
+ any combination.</li>
+ <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> specifies
+ digest algorithms that may be used with the new key. Implementations
+ that do not support all digest algorithms need to accept key generation requests
+ that include unsupported digests. The unsupported digests should be placed in
+ the "software-enforced" list in the returned key characteristics. This is
+ because the key is usable with those other digests, but digesting is
+ performed in software. Then hardware is called to perform the operation
+ with <code>KM_DIGEST_NONE</code>.</li>
+ <li><a href="/security/keystore/tags#padding">KM_TAG_PADDING</a> specifies the padding modes
that may be used with the new key. Implementations
-that do not support all digest algorithms must place <code>KM_PAD_RSA_PSS</code>
-and <code>KM_PAD_RSA_OAEP</code> in the software-enforced list of the key
-characteristics if any unsupported
-digest algorithms are specified.
+ that do not support all digest algorithms need to place <code>KM_PAD_RSA_PSS</code>
+ and <code>KM_PAD_RSA_OAEP</code> in the software-enforced list of the key
+ characteristics if any unsupported digest algorithms are specified.</li>
</ul>
-<h4 id=ecdsa_keys>ECDSA keys</h4>
+<h4 id="ecdsa_keys">ECDSA keys</h4>
-<p>Only <a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> is required to generate an
-ECDSA key. It is used to select the EC group.
-Implementations must support values 224, 256, 384 and 521, which indicate the
+<p>Only <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a> is
+necessary to generate an ECDSA key. It is used to select the EC group.
+Supported values are 224, 256, 384 and 521, which indicate the
NIST p-224, p-256, p-384 and p521 curves, respectively.</p>
-<p><a href="#km_tag_digest">KM_TAG_DIGEST</a> is also needed for a useful ECDSA key,
-but is not required for generation.</p>
+<p><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
+ is also necessary for a useful ECDSA key,
+ but is not required for generation.</p>
-<h4 id=aes_keys>AES keys</h4>
+<h4 id="aes_keys">AES keys</h4>
-<p>Only <a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> is required when
-generating an AES key. If omitted, the method must return <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>.
-Values that must be supported are 128 and 256. It is recommended to support
-192-bit AES keys.</p>
+<p>Only <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
+ is necessary to generate an AES key. If omitted, the method returns
+ <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>. Supported values are
+ 128 and 256, with optional support for 192-bit AES keys.</p>
<p>The following parameters are particularly relevant for AES keys, but not
-required to generate one:</p>
+necessary to generate one:</p>
<ul>
- <li><code>KM_TAG_BLOCK_MODE</code> specifies the block modes with which the new key may be used.
- <li><code>KM_TAG_PADDING</code> specifies the padding modes that may be used. This is only relevant for ECB
-and CBC modes.
+ <li><code>KM_TAG_BLOCK_MODE</code> specifies the block modes with which the new key may be used.</li>
+ <li><code>KM_TAG_PADDING</code> specifies the padding modes that may be used. This is only
+ relevant for ECB and CBC modes.</li>
</ul>
-<p>If the GCM block mode is specified, then <a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
-must be provided. If omitted, the method must return
-<code>KM_ERROR_MISSING_MIN_MAC_LENGTH</code>. The value of the tag must be a multiple of 8 and must
-be at least 96 and no more than 128.</p>
+<p>If the GCM block mode is specified, then provide the
+<a href="/security/keystore/tags#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>.
+If omitted, the method returns <code>KM_ERROR_MISSING_MIN_MAC_LENGTH</code>.
+The tag's value is a multiple of 8 and between 96 and 128.</p>
-<h4 id=hmac_keys>HMAC keys</h4>
+<h4 id="hmac_keys">HMAC keys</h4>
<p>The following parameters are required for HMAC key generation:</p>
<ul>
- <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> specifies the key size in bits. Values
- smaller than 64 and values that are not
-multiples of 8 must not be supported. All multiples of 8, from 64 to 512, must
-be supported. Larger values may be supported.
- <li><a href="#km_tag_min_mac_length">KM_TAG_MIN_MAC_LENGTH</a> specifies the minimum length of
- MACs that can be generated or verified with
-this key. The value must be a multiple of 8 and must be at least 64.
- <li><a href="#km_tag_digest">KM_TAG_DIGEST</a> specifies the digest algorithm for the key. Exactly
- one digest must be
-specified, otherwise return <code>KM_ERROR_UNSUPPORTED_DIGEST</code>. If the digest is not supported
-by the trustlet, return <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.
+ <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
+ specifies the key size in bits. Values smaller than 64
+ and values that are not multiples of 8 are not supported. All
+ multiples of 8, from 64 to 512, are supported. Larger values may be supported.</li>
+ <li><a href="/security/keystore/tags#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
+ specifies the minimum length of
+ MACs that can be generated or verified with this key. The value is a multiple of
+ 8 and at least 64.</li>
+ <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
+ specifies the digest algorithm for the key. Exactly
+ one digest is specified, otherwise return <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.
+ If the digest is not supported by the trustlet, return
+ <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.</li>
</ul>
-<h4 id=key_characteristics>Key characteristics</h4>
+<h4 id="key_characteristics">Key characteristics</h4>
-<p>If the characteristics argument is non-NULL, <code>generate_key</code> must return the newly-generated
+<p>If the characteristics argument is non-NULL,
+<code>generate_key</code> returns the newly-generated
key's characteristics divided appropriately
-into hardware-enforced and software-enforced lists. See <a href="#get_key_characteristics">get_key_characteristics</a>
+into hardware-enforced and software-enforced lists.
+See <a href="#get_key_characteristics">get_key_characteristics</a>
for a description of which characteristics go in which list. The returned
-characteristics must include all of the parameters specified to key generation,
-except <a href="#km_tag_application_id">KM_TAG_APPLICATION_ID</a> and
-<a href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a>.
-If these tags were included in the key parameters, they must be removed from
-the returned characteristics; it must not be possible to find their values by
-examining the returned key blob. However, they must be cryptographically bound
+characteristics include all of the parameters specified to key generation,
+except <a href="/security/keystore/tags#application_id">KM_TAG_APPLICATION_ID</a> and
+<a href="/security/keystore/tags#application_data">KM_TAG_APPLICATION_DATA</a>.
+If these tags were included in the key parameters, they are removed from
+the returned characteristics so that it is not be possible to find their values by
+examining the returned key blob. However, they are cryptographically bound
to the key blob, so that if the correct values are not provided when the key is
-used, usage will fail. Similarly, <a href="#km_tag_root_of_trust">KM_TAG_ROOT_OF_TRUST</a> must
-be cryptographically bound to the key, but it may not be specified during
-key creation or import and must never be returned.</p>
+used, usage fails. Similarly,
+<a href="/security/keystore/tags#root_of_trust">KM_TAG_ROOT_OF_TRUST</a> is
+cryptographically bound to the key, but it may not be specified during
+key creation or import and is never returned.</p>
-<p>In addition to the provided tags, the trustlet must also
-add <a href="#km_tag_origin">KM_TAG_ORIGIN</a>, with the value <code>KM_ORIGIN_GENERATED</code>,
-and if the key is rollback resistant, <a href="#km_tag_rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>.</p>
+<p>In addition to the provided tags, the trustlet also
+adds <a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a>,
+with the value <code>KM_ORIGIN_GENERATED</code>,
+and if the key is rollback resistant,
+<a href="/security/keystore/tags#rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>.</p>
-<h4 id=rollback_resistance>Rollback resistance </h4>
+<h4 id="rollback_resistance">Rollback resistance</h4>
<p>Rollback resistance means that once a key is deleted with
<a href="#delete_key">delete_key</a> or <a href="#delete_all_keys">delete_all_keys</a>,
it is guaranteed by secure hardware never to be usable again. Implementations
-without rollback resistance will typically return generated or imported key
+without rollback resistance typically return generated or imported key
material to the caller as a key blob, an encrypted and authenticated form. When
keystore deletes the key blob, the key is gone, but an attacker who has
previously managed to retrieve the key material can potentially restore it to
@@ -830,12 +338,14 @@ metadata in a trusted location that cannot be manipulated by an attacker. On
mobile devices, the mechanism used for this is usually Replay Protected Memory
Blocks (RPMB). Because the number of keys that may be created is essentially
unbounded and the trusted storage used for rollback resistance may be limited
-in size, it is required that this method succeed even if rollback resistance
+in size, this method needs to succeed even if rollback resistance
cannot be provided for the new key. In that case,
-<a href="#km_tag_rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a> should not be
-added to the key characteristics.</p>
+<a href="/security/keystore/tags#rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>
+should not be added to the key characteristics.</p>
+
+<h3 id="get_key_characteristics">get_key_characteristics</h3>
-<h3 id=get_key_characteristics>get_key_characteristics</h3>
+<p><strong>Version</strong>: 1, 2</p>
<p>Returns parameters and authorizations associated with the provided key, divided
into two sets: hardware-enforced and software-enforced. The description here
@@ -843,11 +353,11 @@ applies equally to the key characteristics lists returned
by <a href="#generate_key">generate_key</a> and <a href="#import_key">import_key</a>.</p>
<p>If <code>KM_TAG_APPLICATION_ID</code> was provided during key generation
-or import, the same value must provided to
+or import, the same value is provided to
this method in the <code>client_id</code> argument. Otherwise, the
-method must return <code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly,
-if <code>KM_TAG_APPLICATION_DATA </code>was provided during generation
-or import, the same value must be provided to
+method returns <code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly,
+if <code>KM_TAG_APPLICATION_DATA</code> was provided during generation
+or import, the same value is provided to
this method in the <code>app_data</code> argument.</p>
<p>The characteristics returned by this method completely describe the type and
@@ -855,176 +365,204 @@ usage of the specified key.</p>
<p>The general rule for deciding whether a given tag belongs in the
hardware-enforced or software-enforced list is that if the meaning of the tag
-is fully assured by secure hardware, it is hardware-enforced. Otherwise, it's
+is fully assured by secure hardware, it is hardware enforced. Otherwise, it's
software enforced. Below is a list of specific tags whose correct allocation
may be unclear:</p>
<ul>
- <li><a href="#km_tag_algorithm">KM_TAG_ALGORITHM</a>, <a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a>,
- and <a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a> are
- intrinsic properties of the key. For any key that is secured by hardware,
-these will be in the hardware-enforced list, because the statement that, for
-example, "This RSA key material is only used as an RSA key" is enforced by
-hardware because the hardware will use it in no other way and software has no
-access to the key material and cannot use it at all.
- <li><a href="#km_tag_digest">KM_TAG_DIGEST</a> values that are supported by the
- secure hardware are to be placed in the
-hardware-supported list. Unsupported digests go in the software-supported list.
- <li><a href="#km_tag_padding">KM_TAG_PADDING</a> values generally go in the
- hardware-supported list, but if there is a
-possibility that a specific padding mode may have to be performed by software,
-they go in the software-enforced list. Such a possibility arises for RSA keys
-that permit PSS or OAEP padding with digest algorithms that are not supported
-by the secure hardware.
- <li><a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> and
- <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> are hardware-enforced
- only if user authentication is hardware enforced. For
-that to be true, the Keymaster trustlet and the relevant authentication
-trustlet must both be secure and must share a secret HMAC key used to sign and
-validate authentication tokens. See the Authentication page for details.
- <li><a href="#km_tag_active_datetime">KM_TAG_ACTIVE_DATETIME</a>,
- <a href="#km_tag_origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a>,
- and <a href="#km_tag_usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> tags
+ <li><a href="/security/keystore/tags#algorithm">KM_TAG_ALGORITHM</a>,
+ <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>,
+ and <a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
+ are intrinsic properties of the key. For any key that is secured by hardware,
+ these tags will be in the hardware-enforced list.</li>
+ <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> values
+ that are supported by the secure hardware are placed in the
+ hardware-supported list. Unsupported digests go in the software-supported list.</li>
+ <li><a href="/security/keystore/tags#padding">KM_TAG_PADDING</a> values
+ generally go in the hardware-supported list, unlessthere is a
+ possibility that a specific padding mode may have to be performed by software.
+ In that case, they go in the software-enforced list. Such a possibility
+ arises for RSA keys that permit PSS or OAEP padding with digest algorithms
+ that are not supported by the secure hardware.</li>
+ <li><a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
+ and <a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>
+ are hardware-enforced only if user authentication is hardware enforced. To
+ accomplish this, the Keymaster trustlet and the relevant authentication
+ trustlet both have to be secure and share a secret HMAC key used to sign and
+ validate authentication tokens. See the
+ <a href="/security/authentication/">Authentication</a> page for details.</li>
+ <li><a href="/security/keystore/tags#active_datetime">KM_TAG_ACTIVE_DATETIME</a>,
+ <a href="/security/keystore/tags#origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a>,
+ and <a href="/security/keystore/tags#usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> tags
require access to a verifiably correct wall clock. Most secure hardware
-will only have access to time information provided by the non-secure OS, which
-means the tags are software-enforced.
- <li><a href="#km_tag_origin">KM_TAG_ORIGIN</a> is always in the hardware list for
- hardware-bound keys. Its presence in that
-list is the way higher layers determine that a key is hardware-backed.
+ only has access to time information provided by the non-secure OS, which
+ means the tags are software enforced.</li>
+ <li><a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a> is
+ always in the hardware list for hardware-bound keys. Its presence in that
+ list is the way higher layers determine that a key is hardware-backed.</li>
</ul>
-<h3 id=import_key>import_key</h3>
+<h3 id="import_key">import_key</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Imports key material into Keymaster hardware. Key definition parameters and
output characteristics are handled the same as for <code>generate_key</code>,
with the following exceptions:</p>
<ul>
- <li><a href="#km_tag_key_size">KM_TAG_KEY_SIZE</a> and
- <a href="#km_tag_rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a> (for RSA keys only)
- are not required in the input parameters. If not provided,
-the trustlet must deduce the values from the provided key material and add
-appropriate tags and values to the key characteristics. If the parameters are
-provided, the trustlet must validate them against the key material. In the
-event of a mismatch, the method must return <code>KM_ERROR_IMPORT_PARAMETER_MISMATCH</code>.
- <li>The returned <a href="#km_tag_origin">KM_TAG_ORIGIN</a> must have the
- value <code>KM_ORIGIN_IMPORTED</code>.
+ <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a> and
+ <a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
+ (for RSA keys only) are not necessary in the input parameters. If not provided,
+ the trustlet deduces the values from the provided key material and adds
+ appropriate tags and values to the key characteristics. If the parameters are
+ provided, the trustlet validates them against the key material. In the
+ event of a mismatch, the method returns <code>KM_ERROR_IMPORT_PARAMETER_MISMATCH</code>.</li>
+ <li>The returned <a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a> has the
+ same value as <code>KM_ORIGIN_IMPORTED</code>.</li>
</ul>
-<h3 id=export_key>export_key</h3>
+<h3 id="export_key">export_key</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Exports a public key from a Keymaster RSA or EC key pair.</p>
<p>If <code>KM_TAG_APPLICATION_ID</code> was provided during key generation or import,
-the same value must provided to
-this method in the <code>client_id</code> argument. Otherwise, the method must return
-<code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly, if <code>KM_TAG_APPLICATION_DATA</code>
-was provided during generation or import, the same value must be provided to
+the same value is provided to this method in the
+<code>client_id</code> argument. Otherwise, the method returns
+<code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly, if
+<code>KM_TAG_APPLICATION_DATA</code>
+was provided during generation or import, the same value is provided to
this method in the <code>app_data</code> argument.</p>
-<h3 id=delete_key>delete_key</h3>
+<h3 id="delete_key">delete_key</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
-<p>Deletes the provided key. This method is optional, and will likely be
-implemented only by Keymaster modules that provide rollback resistance.</p>
+<p>Deletes the provided key. This method is optional, and is only
+implemented by Keymaster modules that provide rollback resistance.</p>
-<h3 id=delete_all_keys>delete_all_keys</h3>
+<h3 id="delete_all_keys">delete_all_keys</h3>
-<p>Deletes all keys. This method is optional, and will likely be implemented only
+<p><strong>Version</strong>: 1, 2</p>
+
+<p>Deletes all keys. This method is optional, and is only implemented
by Keymaster modules that provide rollback resistance.</p>
-<h3 id=begin>begin</h3>
+<h3 id="begin">begin</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Begins a cryptographic operation, using the specified key, for the specified
purpose, with the specified parameters (as appropriate), and returns an
-operation handle which is used with <a href="#update">update</a> and <a
+operation handle that is used with <a href="#update">update</a> and <a
href="#finish">finish</a> to complete the operation. The operation handle is
also used as the "challenge" token in authenticated operations, and for such
-operations must be included in the <code>challenge</code> field of the
+operations is included in the <code>challenge</code> field of the
authentication token.</p>
-<p>A Keymaster implementation must support at least 16 concurrent
-operations. Keystore will use up to 15, leaving one for vold to use for password
+<p>A Keymaster implementation supports at least 16 concurrent
+operations. Keystore uses up to 15, leaving one for vold to use for password
encryption. When Keystore has 15 operations in progress (<code>begin</code> has
been called, but <code>finish</code> or <code>abort</code> have not yet been
-called) and it receives a request to begin a 16th, it will call
+called) and it receives a request to begin a 16th, it calls
<code>abort</code> on the least-recently used operation to reduce the number of
active operations to 14 before calling <code>begin</code> to start the
newly-requested operation.
-<p>If <a href="#km_tag_application_id">KM_TAG_APPLICATION_ID</a> or <a
-href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a> were specified
-during key generation or import, calls to <code>begin</code> must include those
+<p>If <a href="/security/keystore/tags#application_id">KM_TAG_APPLICATION_ID</a>
+or <a href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a> were specified
+during key generation or import, calls to <code>begin</code> include those
tags with the originally-specified values in the <code>in_params</code> argument
to this method.</p>
-<h4 id=authorization_enforcement>Authorization enforcement</h4>
+<h4 id="authorization_enforcement">Authorization enforcement</h4>
-<p>During this method, the following key authorizations must be enforced by the
+<p>During this method, the following key authorizations are enforced by the
trustlet if the implementation placed them in the "hardware-enforced"
characteristics and if the operation is not a public key operation. Public key
operations, meaning <code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_VERIFY</code>,
-with RSA or EC keys, must be allowed to succeed even if authorization
+with RSA or EC keys, are allowed to succeed even if authorization
requirements are not met.</p>
<ul>
- <li><a href="#km_tag_purpose">KM_TAG_PURPOSE</a> requires that the purpose specified
- for this method match one of the purposes
-in the key authorizations, unless the requested operation is a public key
-operation, meaning that the key is RSA or EC and the purpose is <code>KM_PURPOSE_ENCRYPT</code>
-or <code>KM_PURPOSE_VERIFY</code>. Note that <code>KM_PURPOSE_ENCRYPT</code> is not valid for EC keys.
-Begin should return <code>KM_ERROR_UNSUPPORTED_PURPOSE</code> in that case.
- <li><a href="#km_tag_active_datetime">KM_TAG_ACTIVE_DATETIME</a> requires comparison with a trusted
- UTC time source. If the current date and
-time is prior to the tag value, the method must return <code>KM_ERROR_KEY_NOT_YET_VALID</code>.
- <li><a href="#km_tag_origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a> requires
- comparison with a trusted UTC time source. If the current date and
-time is later than the tag value and the purpose is <code>KM_PURPOSE_ENCRYPT</code> or <code>KM_PURPOSE_SIGN</code>,
-the method must return <code>KM_ERROR_KEY_EXPIRED</code>.
- <li><a href="#km_tag_usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> requires comparison with a
- trusted UTC time source. If the current date and
-time is later than the tag value and the purpose is <code>KM_PURPOSE_DECRYPT</code> or <code>KM_PURPOSE_VERIFY</code>,
-the method must return <code>KM_ERROR_KEY_EXPIRED</code>.
- <li><a href="#km_tag_min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</a> requires comparison with a
- trusted relative timer indicating the last use of
-the key. If the last use time plus the tag value is less than the current time,
-the method must return <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>. See the tag description for
-important implementation requirements.
- <li><a href="#km_tag_max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</a> requires comparison against a
- secure counter that tracks the uses of the key
-since boot time. If the count of previous uses exceeds the tag value, the
-method must return <code>KM_ERROR_KEY_MAX_OPS_EXCEEDED</code>.
- <li><a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a> is enforced by this method only
- if the key also has <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a>. If the key has both,
- then this method must have received a <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a> in
- <code>in_params</code> and that token must be valid, meaning that the HMAC field validates correctly.
-In addition, at least one of the <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_ID</a>
-values from the key must match at least one of the secure ID values in the
-token. Finally, the key must also have a <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a> and
-it must match the auth type in the token. If any of these requirements is
-not met, the method must return <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.
- <li><a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> allows the caller to specify a nonce
- or initialization vector (IV). If the key
-does not have this tag but the caller provided <a href="#km_tag_nonce">KM_TAG_NONCE</a> to this method,
-<code>KM_ERROR_CALLER_NONCE_PROHIBITED</code> must be returned.
- <li><a href="#km_tag_bootloader_only">KM_TAG_BOOTLOADER_ONLY</a> specifies that the key may only be
- used by the bootloader. If this method is
-called with a bootloader-only key after the bootloader has finished executing,
-it must return <code>KM_ERROR_INVALID_KEY_BLOB</code>.
+ <li><a href="/security/keystore/tags#purpose">KM_TAG_PURPOSE</a>: The purpose
+ specified in the <code>begin()</code> call has to match one of the purposes
+ in the key authorizations, unless the requested operation is a public key
+ operation. If the specified purpose does not match and the operation is not
+ a public key operation, <code>begin</code> will return
+ <code>KM_ERROR_UNSUPPORTED_PURPOSE</code>. Public key operations are
+ asymmetric encryption or verification operations.</li>
+ <li><a href="/security/keystore/tags#active_datetime">KM_TAG_ACTIVE_DATETIME</a>
+ can only be enforced if a trusted UTC time source is available. If the
+ current date and time is prior to the tag value, the method returns
+ <code>KM_ERROR_KEY_NOT_YET_VALID</code>.</li>
+ <li><a href="/security/keystore/tags#origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a>
+ can only be enforced if a trusted UTC time source is available. If the
+ current date and time is later than the tag value and the purpose is
+ <code>KM_PURPOSE_ENCRYPT</code> or <code>KM_PURPOSE_SIGN</code>, the method
+ returns <code>KM_ERROR_KEY_EXPIRED</code>.</li>
+ <li><a href="/security/keystore/tags#usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a>
+ can only be enforced if a trusted UTC time source is available. If the
+ current date and time is later than the tag value and the purpose is
+ <code>KM_PURPOSE_DECRYPT</code> or <code>KM_PURPOSE_VERIFY</code>, the method
+ returns <code>KM_ERROR_KEY_EXPIRED</code>.</li>
+ <li><a href="/security/keystore/tags#min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</a>
+ is compared with a trusted relative timer indicating the last use of
+ the key. If the last use time plus the tag value is less than the current time,
+ the method returns <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>. See the
+ <a href="/security/keystore/tags#min_seconds_between_ops">tag description</a>
+ for important implementation details.</li>
+ <li><a href="/security/keystore/tags#max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</a>
+ is compared against a secure counter that tracks the uses of the key
+ since boot time. If the count of previous uses exceeds the tag value, the
+ method returns <code>KM_ERROR_KEY_MAX_OPS_EXCEEDED</code>.</li>
+ <li><a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
+ is enforced by this method only if the key also has
+ <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a>.
+ If the key has both, then this method must receive a valid
+ <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a> in
+ <code>in_params</code>. For the auth token to be valid, all of the following
+ has to be true:
+ <ul>
+ <li>The HMAC field validates correctly.</li>
+ <li>At least one of the
+ <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
+ values from the key matches at least one of the secure ID values in the
+ token.</li>
+ <li>The key has a
+ <a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>
+ that matches the auth type in the token.</li>
+ </ul>
+ <p>If any of these conditions aren't met, the method returns
+ <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p></li>
+ <li><a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
+ allows the caller to specify a nonce or initialization vector (IV). If the key
+ doesn't have this tag, but the caller provided
+ <a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a> to this method,
+ <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code> is returned.</li>
+ <li><a href="/security/keystore/tags#bootloader_only">KM_TAG_BOOTLOADER_ONLY</a>
+ specifies that only the bootloader may use the key. If this method is
+ called with a bootloader-only key after the bootloader has finished executing,
+ it returns <code>KM_ERROR_INVALID_KEY_BLOB</code>.</li>
</ul>
-<h4 id=rsa_keys>RSA keys</h4>
+<h4 id="begin-rsa_keys">RSA keys</h4>
-<p>All RSA key operations must specify exactly one padding mode in <code>in_params</code>. If
-unspecified or specified more than once, the method must return <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
+<p>All RSA key operations specify exactly one padding mode in <code>in_params</code>.
+If unspecified or specified more than once, the method returns
+<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
-<p>RSA signing and verification operations require a digest, as do RSA encryption
+<p>RSA signing and verification operations need a digest, as do RSA encryption
and decryption operations with OAEP padding mode. For those cases, the caller
-must specify exactly one digest in <code>in_params</code>. If unspecified or specified more than once,
-the method must return <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.</p>
+specifies exactly one digest in <code>in_params</code>. If unspecified or specified
+more than once, the method returns <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.</p>
-<p>Private key operations (<code>KM_PURPOSE_DECYPT</code> and <code>KM_PURPOSE_SIGN</code>) require
-authorization of digest and padding, which means that the specified
-values must be in the key authorizations. If not, the method must return <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>
+<p>Private key operations (<code>KM_PURPOSE_DECYPT</code> and <code>KM_PURPOSE_SIGN</code>)
+need authorization of digest and padding, which means that the key authorizations
+need to contain the specified values. If not, the method returns
+<code>KM_ERROR_INCOMPATIBLE_DIGEST</code>
or <code>KM_ERROR_INCOMPATIBLE_PADDING</code>, as appropriate. Public key operations
(<code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_VERIFY</code>) are permitted with
unauthorized digest or padding.</p>
@@ -1032,92 +570,104 @@ unauthorized digest or padding.</p>
<p>With the exception of <code>KM_PAD_NONE</code>, all RSA padding modes are applicable only to
certain purposes. Specifically, <code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> and <code>KM_PAD_RSA_PSS</code>
only support signing and verification, while <code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> and
-<code>KM_PAD_RSA_OAEP</code> only support encryption and decryption. The method must return
+<code>KM_PAD_RSA_OAEP</code> only support encryption and decryption. The method returns
<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code> if the specified mode does not support the specified purpose.</p>
<p>There are some important interactions between padding modes and digests:</p>
<ul>
- <li><code>KM_PAD_NONE</code> indicates that a "raw" RSA operation will be
- performed. If signing or verifying, <code>KM_DIGEST_NONE</code> must be
- specified for the digest. No digest is required for unpadded encryption or
- decryption.
-
+ <li><code>KM_PAD_NONE</code> indicates that a "raw" RSA operation is
+ performed. If signing or verifying, <code>KM_DIGEST_NONE</code> is
+ specified for the digest. No digest is necessary for unpadded encryption or
+ decryption.</li>
<li><code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> padding requires a digest. The
digest may be <code>KM_DIGEST_NONE</code>, in which case the Keymaster
implementation cannot build a proper PKCS#1 v1.5 signature structure, because
- it cannot add the DigestInfo structure. Instead, the implementation must
- construct <code>0x00 || 0x01 || PS || 0x00 || M</code>, where M is the
- provided message and PS is the padding string. The size of the RSA key must be
- at least 11 bytes larger than the message, otherwise the method must return
- <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.
-
- <li><code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> padding does not require a digest.
-
+ it cannot add the DigestInfo structure. Instead, the implementation
+ constructs <code>0x00 || 0x01 || PS || 0x00 || M</code>, where M is the
+ provided message and PS is the padding string. The size of the RSA key has to
+ be at least 11 bytes larger than the message, otherwise the method returns
+ <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</li>
+ <li><code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> padding does not require a digest.</li>
<li><code>KM_PAD_RSA_PSS</code> padding requires a digest, which may not be
- <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
- method must return <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. In addition, the
- size of the RSA key must be at least 22 bytes larger than the output size of
- the digest. Otherwise, the method must return
- <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.
-
+ <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
+ method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. In addition, the
+ size of the RSA key has to be at least 2 + D bytes larger than the output
+ size of the digest, where D is the size of the digest, in bytes. Otherwise
+ the method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. The salt size
+ is D.</li>
<li><code>KM_PAD_RSA_OAEP</code> padding requires a digest, which may not be
- <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
- method must return <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.
-
+ <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
+ method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.</li>
</ul>
-<h4 id=ec_keys>EC keys</h4>
-
-<p>EC key operations must specify exactly one padding mode in <code>in_params</code>.
-If unspecified or specified more than once,
-return <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
-
-<p>Private key operations (<code>KM_PURPOSE_SIGN</code>) require authorization of the
-digest, which means that the specified value must be in the key authorizations.
-If not, return <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.
-Public key operations (<code>KM_PURPOSE_VERIFY</code>) are permitted with unauthorized digest or padding.</p>
-
-<h4 id=aes_keys>AES keys</h4>
-
-<p>AES key operations must specify exactly one block mode and one padding mode in <code>in_params</code>.
-If either value is unspecified or specified more than once, return <code>KM_ERROR_UNSUPPORTED_BLOCK_MODE</code> or
-<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>. The specified modes must be authorized by the key.
-Otherwise, the method must
-return <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code> or <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_GCM</code>, <code>in_params</code> must specify <code>KM_TAG_MAC_LENGTH</code>, and the
-specified value must be a multiple of 8 and must not be greater than
-128, or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code> in the key authorizations. For MAC lengths greater than 128 or non-multiples of
-8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>. For values less than the key's minimum length, return <code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_GCM</code> or <code>KM_MODE_CTR</code>, the specified padding mode must
-be <code>KM_PAD_NONE</code>. For <code>KM_MODE_ECB</code> or <code>KM_MODE_CBC</code>, the mode may
-be <code>KM_PAD_NONE</code> or <code>KM_PAD_PKCS7</code>. If the padding mode doesn't meet these
-requirements, return <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_CBC</code>, <code>KM_MODE_CTR</code>, or <code>KM_MODE_GCM</code>, an initialization vector or nonce is needed.
-In most cases, callers should not
-provide an IV or nonce and the Keymaster implementation must generate a random
-IV or nonce and return it via <a href="#km_tag_nonce">KM_TAG_NONCE</a> in <code>out_params</code>. CBC
-and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
-authorizations contain <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a>, then the caller may
-provide an IV/nonce with <a href="#km_tag_nonce">KM_TAG_NONCE</a> in <code>in_params</code>. If a
-nonce is provided when <a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> is not authorized,
-return <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>. If a nonce is not provided when
-<a href="#km_tag_caller_nonce">KM_TAG_CALLER_NONCE</a> is authorized, generate a random IV/nonce.</p>
-
-<h4 id=hmac_keys>HMAC keys</h4>
-
-<p>HMAC key operations must specify <code>KM_TAG_MAC_LENGTH</code> in <code>in_params</code>.
-The specified value must be a multiple of 8 and must not be greater than the
-digest length, or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code> in the key authorizations.
-For MAC lengths greater than the digest length or
-non-multiples of 8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>. For values less than
-the key's minimum length, return <code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
-
-<h3 id=update>update</h3>
+<h4 id="ec_keys">EC keys</h4>
+
+<p>EC key operations specify exactly one padding mode in <code>in_params</code>.
+If unspecified or specified more than once, the method
+returns <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
+
+<p>Private key operations (<code>KM_PURPOSE_SIGN</code>) need authorization
+of digest and padding, which means that the key authorizations
+need to contain the specified values. If not, return
+<code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. Public key operations
+(<code>KM_PURPOSE_VERIFY</code>) are permitted with unauthorized digest or padding.</p>
+
+<h4 id="begin-aes_keys">AES keys</h4>
+
+<p>AES key operations specify exactly one block mode and one padding mode
+in <code>in_params</code>. If either value is unspecified or specified more
+than once, return <code>KM_ERROR_UNSUPPORTED_BLOCK_MODE</code> or
+<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>. The specified modes have to be
+authorized by the key, otherwise the method returns
+<code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code> or
+<code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
+
+<p>If the block mode is <code>KM_MODE_GCM</code>, <code>in_params</code>
+specifies <code>KM_TAG_MAC_LENGTH</code>, and the
+specified value is a multiple of 8 that is not greater than 128
+or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code> in the
+key authorizations. For MAC lengths greater than 128 or non-multiples of
+8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>. For values less
+than the key's minimum length, return <code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
+
+<p>If the block mode is <code>KM_MODE_GCM</code> or <code>KM_MODE_CTR</code>,
+the specified padding mode has to be <code>KM_PAD_NONE</code>.
+For <code>KM_MODE_ECB</code> or <code>KM_MODE_CBC</code>, the mode may be
+<code>KM_PAD_NONE</code> or <code>KM_PAD_PKCS7</code>. If the padding mode
+doesn't meet these conditions, return <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
+
+<p>If the block mode is <code>KM_MODE_CBC</code>, <code>KM_MODE_CTR</code>,
+or <code>KM_MODE_GCM</code>, an initialization vector or nonce is needed.
+In most cases, callers shouldn't provide an IV or nonce. In that case, the
+Keymaster implementation generates a random IV or nonce and returns it via
+<a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a> in <code>out_params</code>.
+CBC and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
+authorizations contain
+<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>,
+then the caller may provide an IV/nonce with
+<a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a>
+in <code>in_params</code>. If a nonce is provided when
+<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
+is not authorized, return <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>.
+If a nonce is not provided when
+<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
+is authorized, generate a random IV/nonce.</p>
+
+<h4 id="begin-hmac_keys">HMAC keys</h4>
+
+<p>HMAC key operations specify <code>KM_TAG_MAC_LENGTH</code> in <code>in_params</code>.
+The specified value must be a multiple of 8 that is not greater than the
+digest length or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code>
+in the key authorizations. For MAC lengths greater than the digest length or
+non-multiples of 8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>.
+For values less than the key's minimum length, return
+<code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
+
+<h3 id="update">update</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
<p>Provides data to process in an ongoing operation started with <a href="#begin">begin</a>.
The operation is specified by the <code>operation_handle</code> parameter.</p>
@@ -1125,164 +675,218 @@ The operation is specified by the <code>operation_handle</code> parameter.</p>
<p>To provide more flexibility for buffer handling, implementations of this method
have the option of consuming less data than was provided. The caller is
responsible for looping to feed the rest of the data in subsequent calls. The
-amount of input consumed must be returned in the <code>input_consumed</code> parameter.
-Implementations must always consume at least one byte, unless the
+amount of input consumed is returned in the <code>input_consumed</code> parameter.
+Implementations always consume at least one byte, unless the
operation cannot accept any more; if more than zero bytes are provided and zero
-bytes are consumed, callers will consider this an error and abort the
-operation.</p>
+bytes are consumed, callers consider this an error and abort the operation.</p>
<p>Implementations may also choose how much data to return, as a result of the
-update. This is only relevant for encryption and decryption operations, since
-signing and verification return no data until <a href="#finish">finish</a>. It is recommended
-to return data as early as possible, rather than buffer it.</p>
+update. This is only relevant for encryption and decryption operations, because
+signing and verification return no data until <a href="#finish">finish</a>.
+Return data as early as possible, rather than buffer it.</p>
-<h4 id=error_handling>Error handling</h4>
+<h4 id="error_handling">Error handling</h4>
-<p>If this method returns an error code other than <code>KM_ERROR_OK</code>, the operation is
-aborted and the operation handle must be invalidated. Any
-future use of the handle, with this method or <a href="#finish">finish</a> or <a href="#abort">abort</a>,
-must return <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
+<p>If this method returns an error code other than <code>KM_ERROR_OK</code>,
+the operation is aborted and the operation handle is invalidated. Any
+future use of the handle, with this method,
+<a href="#finish">finish</a>, or <a href="#abort">abort</a>,
+returns <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
-<h4 id=authorization_enforcement>Authorization enforcement</h4>
+<h4 id="update-authorization_enforcement">Authorization enforcement</h4>
-<p>Key authorization enforcement is performed primarily in <a href="#begin">begin</a>. The one exception
-is the case where the key has:</p>
+<p>Key authorization enforcement is performed primarily in <a href="#begin">begin</a>.
+The one exception is the case where the key has:</p>
<ul>
- <li>One or more <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and
- <li>Does not have a <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a>
+ <li>One or more <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and</li>
+ <li>Does not have a <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a></li>
</ul>
<p>In this case, the key requires an authorization per operation, and the update
-method must receive a <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a> in the <code>in_params</code> argument.
-The token must be valid (HMAC must verify) and it must contain a
-matching secure user ID, must match the key's <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a>, and must
-contain the operation handle of the current operation in the
-challenge field. If these requirements aren't met, return <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
-
-<p>The caller must provide the authentication token to every call to <a href="#update">update</a> and
+method receives a <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a>
+in the <code>in_params</code> argument. HMAC verifies that the token is valid and contains
+a matching secure user ID, matches the key's
+<a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>,
+and contains the operation handle of the current operation in the
+challenge field. If these conditions aren't met, return
+<code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
+
+<p>The caller provides the authentication token to every call to <a href="#update">update</a> and
<a href="#finish">finish</a>. The implementation need only validate the token once if it prefers.</p>
-<h4 id=rsa_keys>RSA keys</h4>
+<h4 id="update-rsa_keys">RSA keys</h4>
-<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>, this method must accept
-the entire block to be signed or verified in a single
-update. It may not consume only a portion of the block. It still must accept
-the data in multiple updates if the caller chooses to provide it that way,
-however. If the caller provides more data to sign than can be used (length of
+<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>,
+this method accepts the entire block to be signed or verified in a single
+update. It may not consume only a portion of the block. However, if the caller
+chooses to provide the data in multiple updates, this method accepts it.
+If the caller provides more data to sign than can be used (length of
data exceeds RSA key size), return <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</p>
-<h4 id=ecdsa_keys>ECDSA keys</h4>
+<h4 id="update-ecdsa_keys">ECDSA keys</h4>
-<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>, this method must accept the
-entire block to be signed or verified in a single
+<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>,
+this method accepts the entire block to be signed or verified in a single
update. This method may not consume only a portion of the block.</p>
-<p>However, this method still must accept the data in multiple updates if the
-caller chooses to provide it that way. If the caller provides more data to sign
-than can be used, the data should be silently truncated. (This differs from the
+<p>However, if the caller chooses to provide the data in multiple updates,
+this method accepts it. If the caller provides more data to sign
+than can be used, the data is silently truncated. (This differs from the
handling of excess data provided in similar RSA operations. The reason for this
is compatibility with legacy clients.)</p>
-<h4 id=aes_keys>AES keys</h4>
+<h4 id="update-aes_keys">AES keys</h4>
<p>AES GCM mode supports "associated authentication data," provided via the
-<a href="#km_tag_associated_data">KM_TAG_ASSOCIATED_DATA</a> tag in the <code>in_params</code> argument.
+<a href="/security/keystore/tags#associated_data">KM_TAG_ASSOCIATED_DATA</a>
+tag in the <code>in_params</code> argument.
The associated data may be provided in repeated calls (important if
-the data is too large to send in a single block) but must always precede data
+the data is too large to send in a single block) but always precedes data
to be encrypted or decrypted. An update call may receive both associated data
and data to encrypt/decrypt, but subsequent updates may not include associated
data. If the caller provides associated data to an update call after a call
that includes data to encrypt/decrypt, return <code>KM_ERROR_INVALID_TAG</code>.</p>
-<p>For GCM encryption, the tag is appended to the ciphertext by <a href="#finish">finish</a>.
-During decryption, the last <code>KM_TAG_MAC_LENGTH</code> bytes of the data provided to the last
-update call is the tag. Since a given
-invocation of <a href="#update">update</a> cannot know if it's the last invocation, it must process all but the tag
-length and buffer the possible tag data for processing during <a href="#finish">finish</a>.</p>
+<p>For GCM encryption, the tag is appended to the ciphertext by
+<a href="#finish">finish</a>. During decryption, the last
+<code>KM_TAG_MAC_LENGTH</code> bytes of the data provided to the last
+update call is the tag. Since a given invocation of
+<a href="#update">update</a> cannot know if it's the last invocation,
+it processes all but the tag length and buffer the possible tag data
+during <a href="#finish">finish</a>.</p>
+
+<h3 id="finish">finish</h3>
-<h3 id=finish>finish</h3>
+<p><strong>Version</strong>: 1, 2</p>
-<p>Finished an ongoing operation started with <a href="#begin">begin</a>, processing all of the
-as-yet-unprocessed data provided by <a href="#update">update</a>(s).</p>
+<p>Finishes an ongoing operation started with <a href="#begin">begin</a>,
+processing all of the as-yet-unprocessed data provided by
+<a href="#update">update</a>(s).</p>
-<p>This method is the last one called in an operation, so all processed data must
-be returned.</p>
+<p>This method is the last one called in an operation, so all
+processed data is returned.</p>
<p>Whether it completes successfully or returns an error, this method finalizes
the operation and therefore invalidates the provided operation handle. Any
future use of the handle, with this method or <a href="#update">update</a> or
-<a href="#abort">abort</a>, must return <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
+<a href="#abort">abort</a>, returns <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
<p>Signing operations return the signature as the output. Verification operations
accept the signature in the <code>signature</code> parameter, and return no output.</p>
-<h4 id=authorization_enforcement>Authorization enforcement</h4>
+<h4 id="finish-authorization_enforcement">Authorization enforcement</h4>
-<p>Key authorization enforcement is performed primarily in <a href="#begin">begin</a>. The one exception is the case where the key has:</p>
+<p>Key authorization enforcement is performed primarily in
+<a href="#begin">begin</a>. The one exception is the case where the key has:</p>
<ul>
- <li>One or more <a href="#km_tag_user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and
- <li>Does not have a <a href="#km_tag_auth_timeout">KM_TAG_AUTH_TIMEOUT</a>
+ <li>One or more
+ <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and</li>
+ <li>Does not have a
+ <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a></li>
</ul>
<p>In this case, the key requires an authorization per operation, and the update
-method must receive a <a href="#km_tag_auth_token">KM_TAG_AUTH_TOKEN</a> in the <code>in_params</code> argument.
-The token must be valid (HMAC must verify) and it must contain a
-matching secure user ID, must match the key's <a href="#km_tag_mac_length">KM_TAG_USER_AUTH_TYPE</a>, and must
-contain the operation handle of the current operation in the
-challenge field. If these requirements aren't met, return <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
-
-<p>The caller must provide the authentication token to every call to <a href="#update">update</a> and <a href="#finish">finish</a>.
+method receives a <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a>
+in the <code>in_params</code> argument. HMAC verifies that the token
+is valid and contains a matching secure user ID, matches the key's
+<a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>, and
+contains the operation handle of the current operation in the
+challenge field. If these conditions aren't met, return
+<code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
+
+<p>The caller provides the authentication token to every call to
+<a href="#update">update</a> and <a href="#finish">finish</a>.
The implementation need only validate the token once if it prefers.</p>
-<h4 id=rsa_keys>RSA keys</h4>
+<h4 id="finish-rsa_keys">RSA keys</h4>
<p>Some additional requirements, depending on the padding mode:</p>
<ul>
- <li><strong>KM_PAD_NONE</strong>. For unpadded signing and encryption operations, if the provided data is
-shorter than the key, the data must be zero-padded on the left before
-signing/encryption. If the data is the same length as the key but numerically
-larger, return <code>KM_ERROR_INVALID_ARGUMENT</code>. For verification and decryption operations, the data must be exactly as long
-as the key. Otherwise, return <code>KM_ERROR_INVALID_INPUT_LENGTH.</code>
- <li><strong>KM_PAD_RSA_PSS</strong>. For PSS-padded signature operations, the PSS salt must be at least 20 bytes
-in length and randomly-generated. The salt may be longer; the reference
-implementation uses maximally-sized salt. The digest specified with <a href="#km_tag_digest">KM_TAG_DIGEST</a> in
-<code>input_params</code> on <a href="#begin">begin</a> is used as the PSS digest algorithm, and SHA1 is used as the MGF1 digest
-algorithm.
- <li><strong>KM_PAD_RSA_OAEP</strong>. The digest specified with <a href="#km_tag_digest">KM_TAG_DIGEST</a> in
- <code>input_params</code> on <a href="#begin">begin</a> is used as the OAEP digest algorithm, and SHA1 is used as the MGF1 digest
-algorithm.
+ <li><strong>KM_PAD_NONE</strong>. For unpadded signing and encryption operations,
+ if the provided data is shorter than the key, the data is be zero-padded on
+ the left before signing/encryption. If the data is the same length as the key,
+ but numerically larger, return <code>KM_ERROR_INVALID_ARGUMENT</code>. For
+ verification and decryption operations, the data must be exactly as long
+ as the key. Otherwise, return <code>KM_ERROR_INVALID_INPUT_LENGTH.</code></li>
+ <li><strong>KM_PAD_RSA_PSS</strong>. For PSS-padded signature operations,
+ the PSS salt is at least 20 bytes in length and randomly-generated.
+ The salt may be longer; the reference implementation uses maximally-sized salt.
+ The digest specified with <a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
+ in <code>input_params</code> on <a href="#begin">begin</a> is used as the PSS digest
+ algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
+ <li><strong>KM_PAD_RSA_OAEP</strong>. The digest specified with
+ <a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> in
+ <code>input_params</code> on <a href="#begin">begin</a> is used as the OAEP
+ digest algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
</ul>
-<h4 id=ecdsa_keys>ECDSA keys</h4>
+<h4 id="finish-ecdsa_keys">ECDSA keys</h4>
<p>If the data provided for unpadded signing or verification is too long, truncate
it.</p>
-<h4 id=aes_keys>AES keys</h4>
+<h4 id="finish-aes_keys">AES keys</h4>
-<p>Some additional requirements, depending on block mode:</p>
+<p>Some additional conditions, depending on block mode:</p>
<ul>
- <li><strong>KM_MODE_ECB</strong> or <strong>KM_MODE_CBC</strong>. If padding is <code>KM_PAD_NONE</code> and the
- data length is not a multiple of the AES block size, return <code>KM_ERROR_INVALID_INPUT_LENGTH</code>. If
- padding is <code>KM_PAD_PKCS7</code>, pad the data per the PKCS#7 specification. Note that PKCS#7 requires that if
-the data is a multiple of the block length, an additional padding block must be
-added.
- <li><strong>KM_MODE_GCM</strong>. During encryption, after processing all plaintext, compute the
- tag (<a href="#km_tag_mac_length">KM_TAG_MAC_LENGTH</a> bytes) and append it to the returned ciphertext.
- During decryption, process
-the last <a href="#km_tag_mac_length">KM_TAG_MAC_LENGTH</a> bytes as the tag. If tag verification fails,
-return <code>KM_ERROR_VERIFICATION_FAILED</code>.
+ <li><strong>KM_MODE_ECB</strong> or <strong>KM_MODE_CBC</strong>.
+ If padding is <code>KM_PAD_NONE</code> and the
+ data length is not a multiple of the AES block size, return
+ <code>KM_ERROR_INVALID_INPUT_LENGTH</code>. If padding is
+ <code>KM_PAD_PKCS7</code>, pad the data per the PKCS#7 specification.
+ Note that PKCS#7 recommends adding an additional padding block
+ if the data is a multiple of the block length.</li>
+ <li><strong>KM_MODE_GCM</strong>. During encryption, after processing
+ all plaintext, compute the tag
+ (<a href="/security/keystore/tags#mac_length">KM_TAG_MAC_LENGTH</a> bytes)
+ and append it to the returned ciphertext. During decryption, process
+ the last <a href="/security/keystore/tags#mac_length">KM_TAG_MAC_LENGTH</a>
+ bytes as the tag. If tag verification fails, return
+ <code>KM_ERROR_VERIFICATION_FAILED</code>.</li>
</ul>
-<h3 id=abort>abort</h3>
+<h3 id="abort">abort</h3>
+
+<p><strong>Version</strong>: 1, 2</p>
-<p>Aborts the in-progress operation. After the call to abort, return <code>KM_ERROR_INVALID_OPERATION_HANDLE</code> for
+<p>Aborts the in-progress operation. After the call to abort, return
+<code>KM_ERROR_INVALID_OPERATION_HANDLE</code> for
any subsequent use of the provided operation handle with <a href="#update">update</a>,
<a href="#finish">finish</a>, or <a href="#abort">abort</a>.</p>
+<h2 id="historical-functions">Historical functions</h2>
+
+<h3 id="km0">Keymaster 0</h3>
+<p>
+The following functions belong to the original Keymaster 0 definition. They
+were present in Keymaster 1 struct keymaster1_device_t. However, in Keymaster
+1.0 they were not implemented, and their function pointers were set to NULL.
+</p>
+<ul>
+<li><code>generate_keypair</code></li>
+<li><code>import_keypair</code></li>
+<li><code>get_keypair_public</code></li>
+<li><code>delete_keypair</code></li>
+<li><code>delete_all</code></li>
+<li><code>sign_data</code></li>
+<li><code>Verify_data</code></li>
+</ul>
+
+<h3 id="km1">Keymaster 1</h3>
+<p>The following functions belong to the Keymaster 1 definition, but were
+removed in Keymaster 2, along with the Keymaster 0 functions listed above.
+</p>
+<ul>
+ <li><code>get_supported_algorithms</code></li>
+ <li><code>get_supported_block_modes</code></li>
+ <li><code>get_supported_padding_modes</code></li>
+ <li><code>get_supported_digests</code></li>
+ <li><code> get_supported_import_formats</code></li>
+ <li><code>get_supported_export_formats</code></li>
+</ul>
</body>
</html>
diff --git a/en/security/keystore/index.html b/en/security/keystore/index.html
index 8ce4b7a4..0c9e7272 100644
--- a/en/security/keystore/index.html
+++ b/en/security/keystore/index.html
@@ -30,15 +30,6 @@ third-party apps. Developers seeking the Android-specific extensions should go
to <a
href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.html">android.security.keystore</a>.</p>
-<p>Keystore has been <a href="features.html">significantly enhanced</a> in
-Android 6.0 with the addition of symmetric cryptographic primitives, AES and
-HMAC, and the addition of an access control system for hardware-backed
-keys. Access controls are specified during key generation and enforced for the
-lifetime of the key. Keys can be restricted to be usable only after the user has
-authenticated, and only for specified purposes or with specified cryptographic
-parameters. For more information, please see the <a
-href="implementer-ref.html">Implementer's Reference</a>.</p>
-
<p>Before Android 6.0, Android already had a simple, hardware-backed crypto
services API, provided by versions 0.2 and 0.3 of the Keymaster Hardware
Abstraction Layer (HAL). Keystore provided digital signing and verification
@@ -47,10 +38,38 @@ already implemented on many devices, but there are many security goals that
cannot easily be achieved with only a signature API. Keystore in Android 6.0
extends the Keystore API to provide a broader range of capabilities.</p>
+<p>In Android 6.0, Keystore added <a href="/security/keystore/features.html">symmetric cryptographic
+primitives</a>, AES and HMAC, and an access control system for hardware-backed
+keys. Access controls are specified during key generation and enforced for the
+lifetime of the key. Keys can be restricted to be usable only after the user has
+authenticated, and only for specified purposes or with specified cryptographic
+parameters. For more information, see the <a href="/security/keystore/tags">Authorization
+Tags</a> and <a href="/security/keystore/implementer-ref">Functions</a> pages.</p>
+
+<p>
+In Android 7.0, Keymaster 2 added support for key attestation and version binding.
+<a href="/security/keystore/attestation">Key attestation</a>
+provides public key certificates that contain a detailed
+description of the key and its access controls, to make the key's existence in
+secure hardware and its configuration remotely verifiable.
+</p>
+<p>
+<a href="/security/keystore/version-binding">Version binding</a>
+binds keys to operating system and patch
+level version. This ensures that an attacker who discovers a weakness in an old
+version of system or TEE software cannot roll a device back to the vulnerable
+version and use keys created with the newer version. In addition, when a key
+with a given version and patch level is used on a device that has been upgraded
+to a newer version or patch level, the key is upgraded before it can be used,
+and the previous version of the key invalidated. As the device is upgraded, the
+keys "ratchet" forward along with the device, but any reversion of the device to
+a previous release causes the keys to be unusable.
+</p>
+
<h2 id=goals>Goals</h2>
-<p>The goal of the Android 6.0 Keystore API and the underlying Keymaster 1.0 HAL
-is to provide a basic but adequate set of cryptographic primitives to allow the
+<p>The Android 7.0 Keystore API and the underlying Keymaster HAL
+provides a basic but adequate set of cryptographic primitives to allow the
implementation of protocols using access-controlled, hardware-backed keys.</p>
<p>In addition to expanding the range of cryptographic primitives, Keystore in
@@ -66,11 +85,11 @@ clients, and a defined time range
<h2 id=architecture>Architecture</h2>
<p>The Keymaster HAL is an OEM-provided, dynamically-loadable library used by the
-Keystore service to provide hardware-backed cryptographic services. HAL
-implementations must not perform any sensitive operations in user space, or even
-in kernel space. Sensitive operations are delegated to a secure processor
-reached through some kernel interface. The resulting architecture looks
-like the following:</p>
+Keystore service to provide hardware-backed cryptographic services. To keep
+things secure, HAL implementations don't perform any sensitive operations in
+user space, or even in kernel space. Sensitive operations are delegated to a
+secure processor reached through some kernel interface.
+The resulting architecture looks like this:</p>
<div align="center">
<img src="/security/images/access-to-keymaster.png" alt="Access to Keymaster" id="figure1" />
@@ -91,14 +110,21 @@ wire format is implementation-defined.</p>
<h2 id=compatibility_with_previous_versions>Compatibility with previous versions</h2>
-<p>The Keymaster v1.0 HAL is completely incompatible with the
-previously-released HALs, e.g. Keymaster v0.2 and v0.3. To facilitate
-interoperability on pre-Marshmallow devices that launched with the older
-Keymaster HALs, Keystore provides an adapter that implements the 1.0 HAL with
-calls to the existing hardware library. The result cannot provide the full range
-of functionality in the 1.0 HAL. In particular, it will only support RSA and
-ECDSA algorithms, and all of the key authorization enforcement will be performed
-by the adapter, in the non-secure world.</p>
+<p>The Keymaster 1 HAL is completely incompatible with the
+previously-released HALs, e.g. Keymaster 0.2 and 0.3. To facilitate
+interoperability on devices running Android 5.0 and earlier that launched with
+the older Keymaster HALs, Keystore provides an adapter that implements the
+Keymaster 1 HAL with calls to the existing hardware library. The result cannot
+provide the full range of functionality in the Keymaster 1 HAL. In particular,
+it only supports RSA and ECDSA algorithms, and all of the key authorization
+enforcement is performed by the adapter, in the non-secure world.</p>
+
+<p>
+Keymaster 2 further simplified the HAL interface by removing the <code>get_supported_*</code>
+methods and allowing the <code>finish()</code> method to accept input. This reduces the
+number of round trips to the TEE in cases where the input is available all at
+once, and simplifies implementation of AEAD decryption.
+</p>
</body>
</html>
diff --git a/en/security/keystore/tags.html b/en/security/keystore/tags.html
new file mode 100644
index 00000000..73880c81
--- /dev/null
+++ b/en/security/keystore/tags.html
@@ -0,0 +1,732 @@
+<html devsite>
+ <head>
+ <title>Keymaster Authorization Tags</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>This page provides details to assist implementers of Keymaster HALs.
+It covers each tag in the HAL, which Keymaster version that tag is available
+in, and whether the tag is repeatable. Except as noted in the tag descriptions,
+all of the tags below are used during key generation to specify key
+characteristics. For functions, see the
+<a href="/security/keystore/implementer-ref">Keymaster Functions</a> page.</p>
+
+<h2 id="active_datetime">KM_TAG_ACTIVE_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the date and time at which the key becomes active. Prior to this
+time, any attempt to use the key fails with
+<code>KM_ERROR_KEY_NOT_YET_VALID</code>.</p>
+
+<p>The value is a 64-bit integer representing milliseconds since January 1,
+1970.</p>
+
+
+<h2 id="algorithm">KM_TAG_ALGORITHM</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the cryptographic algorithm with which the key is used.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_ALGORITHM_RSA = 1,
+ KM_ALGORITHM_EC = 3,
+ KM_ALGORITHM_AES = 32,
+ KM_ALGORITHM_HMAC = 128,
+} keymaster_algorithm_t;
+</pre>
+
+
+<h2 id="all_applications">KM_TAG_ALL_APPLICATIONS</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Reserved for future use.</p>
+
+
+<h2 id="allow_while_on_body">KM_TAG_ALLOW_WHILE_ON_BODY</h2>
+
+<p><strong>Version</strong>: 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>This tag is applicable only for Android Wear devices with on-body sensors. At
+this point, it's not expected that any TEE will be able to provide secure access
+to an on-body sensor, or that on-body sensors are very secure, so this is
+expected to be a purely software-enforced feature.</p>
+
+<h2 id="application_data">KM_TAG_APPLICATION_DATA</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>When provided to
+<a href="/security/keystore/implementer-ref#generate_key">generate_key</a>
+or <a href="/security/keystore/implementer-ref#import_key">import_key</a>,
+this tag specifies data that is necessary during all uses of the key. In
+particular, calls to
+<a href="/security/keystore/implementer-ref#export_key">export_key</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>
+need to provide the same value to the <code>client_id</code> parameter, and calls
+to <a href="/security/keystore/implementer-ref#begin">begin</a> need to provide
+this tag and the same associated data as part of the <code>in_params</code>
+set. If the correct data is not provided, the function returns
+<code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+
+<p>The content of this tag is bound to the key <em>cryptographically</em>,
+meaning it must not be possible for an adversary who has access to all of the
+secure world secrets but does not have access to the tag content to decrypt the
+key without brute-forcing the tag content, which applications can prevent by
+specifying sufficiently high-entropy content.</p>
+
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+
+<h2 id="application_id">KM_TAG_APPLICATION_ID</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>When provided to
+<a href="/security/keystore/implementer-ref#generate_key">generate_key</a>
+or <a href="/security/keystore/implementer-ref#import_key">import_key</a>,
+this tag specifies data that is necessary during all uses of the key. In
+particular, calls to
+<a href="/security/keystore/implementer-ref#export_key">export_key</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>
+need to provide the same value in the <code>client_id</code> parameter, and
+calls to <a href="/security/keystore/implementer-ref#begin">begin</a> need to
+provide this tag and the same associated data as part of the
+<code>in_params</code> set. If the correct data is not provided, the function
+returns <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+
+<p>The content of this tag is bound to the key <em>cryptographically</em>,
+meaning it an adversary who can access all of the secure world secrets—but
+does not have access to the tag content—can't decrypt the
+key (without brute-forcing the tag content).</p>
+
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+
+<h2 id="associated_data">KM_TAG_ASSOCIATED_DATA</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides "associated data" for AES-GCM encryption or decryption. This tag is
+provided to <a href="/security/keystore/implementer-ref#update">update</a> and
+specifies data that is not encrypted/decrypted, but is used in computing
+the GCM tag.</p>
+
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+
+<h2 id="auth_timeout">KM_TAG_AUTH_TIMEOUT</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the time in seconds for which the key is authorized for use, after
+authentication. If <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>
+is present and this tag is not, then the key needs authentication for every
+usage (see <a href="/security/keystore/implementer-ref#begin">begin</a> for the
+details of the authentication-per-operation flow).</p>
+
+<p>The value is a 32-bit integer specifying the time in seconds after a successful
+authentication of the user specified by
+<a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a> with
+the authentication method specified
+by <a href="#mac_length">KM_TAG_USER_AUTH_TYPE</a> that the key can be used.</p>
+
+
+<h2 id="auth_token">KM_TAG_AUTH_TOKEN</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides an authentication token (see the
+<a href="/security/keystore/features#user_authentication">Authentication</a>
+page) to <a href="/security/keystore/implementer-ref#begin">begin</a>,
+<a href="/security/keystore/implementer-ref#update">update</a> or
+<a href="/security/keystore/implementer-ref#finish">finish</a>,
+to prove user authentication for a key operation that requires
+it (key has <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>).</p>
+
+<p>The value is a blob which contains a <code>hw_auth_token_t</code> structure.</p>
+
+
+<h2 id="blob_usage_requirements">KM_TAG_BLOB_USAGE_REQUIREMENTS</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the necessary system environment conditions for the generated
+key to be used.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_BLOB_STANDALONE = 0,
+ KM_BLOB_REQUIRES_FILE_SYSTEM = 1,
+} keymaster_key_blob_usage_requirements_t;
+</pre>
+
+<p>This tag can be specified during key generation to require that the key is
+usable in the specified condition. It needs to be returned with the key
+characteristics from
+<a href="/security/keystore/implementer-ref#generate_key">generate_key</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>.
+If the caller specifies <code>KM_TAG_BLOB_USAGE_REQUIREMENTS</code> with
+value <code>KM_BLOB_STANDALONE</code> the trustlet returns a key blob
+that can be used without file system support. This is critical for devices
+with encrypted disks, where the file system may not be available until
+after a Keymaster key is used to decrypt the disk.</p>
+
+
+<h2 id="block_mode">KM_TAG_BLOCK_MODE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Specifies the block cipher mode(s) with which the key may be used.
+This tag is only relevant to AES keys.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_MODE_ECB = 1,
+ KM_MODE_CBC = 2,
+ KM_MODE_CTR = 3,
+ KM_MODE_GCM = 32,
+} keymaster_block_mode_t;
+</pre>
+
+<p>This tag is repeatable, and for AES key operations specify a mode in
+the <code>additional_params</code> argument of
+<a href="/security/keystore/implementer-ref#begin">begin</a>.
+If the specifiedmode is not in the modes associated with the key, the
+operation fails with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
+
+
+<h2 id="bootloader_only">KM_TAG_BOOTLOADER_ONLY</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies only the bootloader can use the key.</p>
+
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
+
+<p>Any attempt to use a key with <code>KM_TAG_BOOTLOADER_ONLY</code> from the
+Android system fails with <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+
+
+<h2 id="caller_nonce">KM_TAG_CALLER_NONCE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies that the caller can provide a nonce for nonce-requiring operations.</p>
+
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
+
+<p>This tag is used only for AES keys, and is only relevant for CBC, CTR and GCM
+block modes. If the tag is not present, implementations should reject any
+operation that provides <a href="#nonce">KM_TAG_NONCE</a> to
+<a href="/security/keystore/implementer-ref#begin">begin</a>
+with <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>.</p>
+
+
+<h2 id="creation_datetime">KM_TAG_CREATION_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the date and time the key was created, in milliseconds since January
+1, 1970. This tag is optional and informational only.</p>
+
+
+<h2 id="digest">KM_TAG_DIGEST</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Specifies the digest algorithms that may be used with the key to perform
+signing and verification operations. This tag is relevant to RSA, ECDSA and
+HMAC keys.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_DIGEST_NONE = 0,
+ KM_DIGEST_MD5 = 1,
+ KM_DIGEST_SHA1 = 2,
+ KM_DIGEST_SHA_2_224 = 3,
+ KM_DIGEST_SHA_2_256 = 4,
+ KM_DIGEST_SHA_2_384 = 5,
+ KM_DIGEST_SHA_2_512 = 6,
+}
+keymaster_digest_t;
+</pre>
+
+<p>This tag is repeatable. For signing and verification operations, specify
+a digest in the <code>additional_params</code> argument of
+<a href="/security/keystore/implementer-ref#begin">begin</a>.
+If the specified digest is not in the digests associated with the key, the
+operation fails with <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.</p>
+
+<h2 id="ec_curve">KM_TAG_EC_CURVE</h2>
+
+<p><strong>Version</strong>: 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>In Keymaster 1, the curve used for EC keys was guessed from the specified key
+size. To improve flexibility moving forward, Keymaster 2 introduced an explicit
+way to specify curves. EC key generation requests may have
+<code>KM_TAG_EC_CURVE</code>, <code>KM_TAG_KEY_SIZE</code>, or both.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+enum class EcCurve : uint32_t {
+ P_224 = 0,
+ P_256 = 1,
+ P_384 = 2,
+P_521 = 3,
+};
+</pre>
+
+<p>If a generation request only contains <code>KM_TAG_KEY_SIZE</code>,
+fall back to the Keymaster 1 logic, choosing the appropriate NIST curve.</p>
+
+<p>If the request only contains <code>KM_TAG_EC_CURVE</code>, use the
+specified curve. Curves are defined in <code>keymaster_ec_curve_t</code>.</p>
+
+<p>If the request contains both, use the curve specified by
+<code>KM_TAG_EC_CURVE</code>, and validate that the specified key size is
+appropriate for that curve. If not, return
+<code>KM_ERROR_INVALID_ARGUMENT</code>.</p>
+
+
+<h2 id="include_unique_id">KM_TAG_INCLUDE_UNIQUE_ID</h2>
+
+<p><strong>Version</strong>: 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>This tag is specified during key generation to indicate that an attestation
+certificate for the generated key should contain a Unique ID.</p>
+
+
+<h2 id="key_size">KM_TAG_KEY_SIZE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the size, in bits, of the key, measuring in the normal way for the
+key's algorithm. For example, for RSA keys, <code>KM_TAG_KEY_SIZE</code> specifies
+the size of the public modulus. For AES keys it specifies the length
+of the secret key material.</p>
+
+
+<h2 id="mac_length">KM_TAG_MAC_LENGTH</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the requested length of a MAC or GCM authentication tag, in bits.</p>
+
+<p>The value is the MAC length in bits. It is a multiple of 8 and at
+least as large as the value of <a href="#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
+associated with the key.</p>
+
+
+<h2 id="max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the maximum number of times that a key may be used between system
+reboots. This is another mechanism to rate-limit key use.</p>
+
+<p>The value is a 32-bit integer representing uses per boot.</p>
+
+<p>When a key with this tag is used in an operation, a key-associated counter
+should be incremented during the
+<a href="/security/keystore/implementer-ref#begin">begin</a> call. After the key
+counter has exceeded this value, all subsequent attempts to use the key fail
+with <code>KM_ERROR_MAX_OPS_EXCEEDED</code>, until the device is restarted. This
+implies that a trustlet keeps a table of use counters for keys with this tag.
+Because Keymaster memory is often limited, this table can have a fixed maximum
+size and Keymaster can fail operations that attempt to use keys with this tag
+when the table is full. The table needs to acommodate at least 16 keys. If an
+operation fails because the table is full, Keymaster returns
+<code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
+
+
+<h2 id="min_mac_length">KM_TAG_MIN_MAC_LENGTH</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>This tag specifies the minimum length of MAC that can be requested or
+ verified with this key for HMAC keys and AES keys that support GCM mode.</p>
+
+<p>This value is the minimum MAC length, in bits. It is a multiple of 8. For
+HMAC keys, the value is at least 64. For GCM keys, the value is at least 96
+and no more than 128.</p>
+
+
+<h2 id="min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the minimum amount of time that elapses between allowed
+operations using a key. This can be used to rate-limit uses of keys in contexts
+where unlimited use may enable brute force attacks.</p>
+
+<p>The value is a 32-bit integer representing seconds between allowed operations.</p>
+
+<p>When a key with this tag is used in an operation, start a timer
+during the <a href="/security/keystore/implementer-ref#finish">finish</a> or
+<a href="/security/keystore/implementer-ref#abort">abort</a> call. Any
+call to <a href="/security/keystore/implementer-ref#begin">begin</a> that is received
+before the timer indicates that the interval specified by
+<code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> has elapsed fails with
+<code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>.This
+implies that a trustlet keeps a table of use counters for keys with this tag.
+Because Keymaster memory is often limited, this table can have a fixed maximum size
+and Keymaster can fail operations that attempt to use keys with this tag
+when the table is full. The table needs to acommodate at least 32 in-use
+keys and aggressively reuse table slots when key minimum-usage intervals expire.
+If an operation fails because the table is full, Keymaster returns
+<code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
+
+
+<h2 id="no_auth_required">KM_TAG_NO_AUTH_REQUIRED</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies that no authentication is required to use this key. This tag is
+mutually exclusive with <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>.</p>
+
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
+
+
+<h2 id="nonce">KM_TAG_NONCE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides or returns a nonce or Initialization Vector (IV) for AES GCM, CBC, or
+CTR encryption or decryption. This tag is provided to
+<a href="/security/keystore/implementer-ref#begin">begin</a>
+during encryption and decryption operations. It is only provided to
+<a href="/security/keystore/implementer-ref#begin">begin</a>
+if the key has <a href="#caller_nonce">KM_TAG_CALLER_NONCE</a>. If not provided,
+an appropriate nonce or IV will be randomly generated by
+Keymaster and returned from begin.</p>
+
+<p>The value is a blob, an arbitrary-length array of bytes. Allowed lengths depend
+on the mode: GCM nonces are 12 bytes in length; CBC and CTR IVs are 16 bytes in
+length.</p>
+
+
+<h2 id="origin">KM_TAG_ORIGIN</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies where the key was created, if known. This tag may not be specified
+during key generation or import, and must be added to the key characteristics
+by the trustlet.</p>
+
+<p>The possible values are defined in <code>keymaster_origin_t</code>:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_ORIGIN_GENERATED = 0,
+ KM_ORIGIN_IMPORTED = 2,
+ KM_ORIGIN_UNKNOWN = 3,
+} keymaster_key_origin_t
+</pre>
+
+<p>The full meaning of the value depends not only on the value but on whether it's
+found in the hardware-enforced or software-enforced characteristics list.</p>
+
+<p><code>KM_ORIGIN_GENERATED</code> indicates that Keymaster generated the key.
+If in the hardware-enforced list,
+the key was generated in secure hardware and is permanently hardware-bound. If
+in the software-enforced list, the key was generated in SoftKeymaster and is
+not hardware-bound.</p>
+
+<p><code>KM_ORIGIN_IMPORTED</code> indicates that the key was generated outside
+of Keymaster and imported into
+Keymaster. If in the hardware-enforced list, it is permanently hardware-bound,
+although copies outside of secure hardware may exist. If in the
+software-enforces list, the key was imported into SoftKeymaster and is not
+hardware-bound.</p>
+
+<p><code>KM_ORIGIN_UNKNOWN</code> should only appear in the hardware-enforced list.
+It indicates that the key is
+hardware-bound, but it is not known whether the key was originally generated in
+secure hardware or was imported. This only occurs when keymaster0 hardware is
+being used to emulate keymaster1 services.</p>
+
+
+<h2 id="origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the date and time at which the key expires for signing and encryption
+purposes. After this time, any attempt to use a key
+with <a href="#purpose">KM_PURPOSE_SIGN</a> or
+<a href="#purpose">KM_PURPOSE_ENCRYPT</a> provided
+to <a href="/security/keystore/implementer-ref#begin">begin</a> fails
+with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
+
+<p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
+
+
+<h2 id="os_patchlevel">KM_TAG_OS_PATCHLEVEL</h2>
+
+<p><strong>Version</strong>: 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>This tag is never sent to the keymaster TA, but is added to the
+hardware-enforced authorization list by the TA.</p>
+
+<p>The value of the tag is an integer of the form YYYYMM, where YYYY is the
+four-digit year of the last update and MM is the two-digit month of the last
+update. For example, for a key generated on an Android device last updated in
+December 2015, the value would be 201512.</p>
+
+<p>Keys that have a patch level different than the current patch level are not
+usable. An attempt to use such a key causes
+<a href="/security/keystore/implementer-ref#begin">begin</a>,
+<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>,
+or <a href="/security/keystore/implementer-ref#export_key">export_key</a>
+to return <code>KM_ERROR_KEY_REQUIRES_UPGRADE</code>. See
+<a href="/security/keystore/version-binding">Version Binding</a> for more details.</p>
+
+
+<h2 id="os_version">KM_TAG_OS_VERSION</h2>
+
+<p><strong>Version</strong>: 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>This tag is never sent to the keymaster TA, but is added to the
+hardware-enforced authorization list by the TA.</p>
+
+<p>The value of the tag is an integer of the form MMmmss, where MM is the major
+version number, mm is the minor version number, and ss is the sub-minor version
+number. For example, for a key generated on Android version 4.0.3, the value
+would be 040003.</p>
+
+
+<h2 id="padding">KM_TAG_PADDING</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Specifies the padding modes that may be used with the key. This tag is
+relevant to RSA and AES keys.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_PAD_NONE = 1,
+ KM_PAD_RSA_OAEP = 2,
+ KM_PAD_RSA_PSS = 3,
+ KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4,
+ KM_PAD_RSA_PKCS1_1_5_SIGN = 5,
+ KM_PAD_PKCS7 = 64,
+} keymaster_padding_t;
+</pre>
+
+<p><code>KM_PAD_RSA_OAEP</code> and <code>KM_PAD_RSA_PKCS1_1_5_ENCRYPT</code> are used
+only for RSA encryption/decryption keys and specify RSA PKCS#1v2 OAEP
+padding and RSA PKCS#1 v1.5 randomized padding, respectively. <code>KM_PAD_RSA_PSS</code> and
+<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> are used only for RSA signing/verification keys and
+specify RSA PKCS#1v2 PSS
+padding and RSA PKCS#1 v1.5 deterministic padding, respectively. Note also that
+the RSA PSS padding mode is incompatible with <a href="#digest">KM_DIGEST_NONE</a>.</p>
+
+<p><code>KM_PAD_NONE</code> may be used with either RSA or AES keys. For AES keys,
+if <code>KM_PAD_NONE</code> is used with block mode ECB or CBC and the data to be encrypted
+or decrypted
+is not a multiple of the AES block size in length, the call to finish fails
+with <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</p>
+
+<p><code>KM_PAD_PKCS7</code> may only be used with AES keys, and only with ECB and CBC modes.</p>
+
+<p>This tag is repeatable. A padding mode must be specified in the call to
+<a href="/security/keystore/implementer-ref#begin">begin</a>.
+If the specified mode is not authorized for the key, the operation fails
+with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
+
+
+<h2 id="purpose">KM_TAG_PURPOSE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Specifies the set of purposes for which the key may be used.</p>
+
+<p>Possible values are defined by the following enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ KM_PURPOSE_ENCRYPT = 0,
+ KM_PURPOSE_DECRYPT = 1,
+ KM_PURPOSE_SIGN = 2,
+ KM_PURPOSE_VERIFY = 3,
+} keymaster_purpose_t;
+</pre>
+
+<p>This tag is repeatable; keys may be generated with multiple values, although an
+operation has a single purpose. When the
+<a href="/security/keystore/implementer-ref#begin">begin</a> function is called to
+start an operation, the purpose of the operation is
+specified. If the purpose specified to the operation is not authorized by the
+key, the operation fails with <code>KM_ERROR_INCOMPATIBLE_PURPOSE</code>.</p>
+
+<h2 id="rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Indicates that the key is rollback-resistant, meaning that when deleted
+by <a href="/security/keystore/implementer-ref#delete_key">delete_key</a> or
+<a href="/security/keystore/implementer-ref#delete_all_keys">delete_all_keys</a>,
+the key is guaranteed to be permanently deleted and unusable. It's possible
+that keys without this tag could be deleted and then restored from backup.</p>
+
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
+
+
+<h2 id="root_of_trust">KM_TAG_ROOT_OF_TRUST</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+
+<p>Specifies the <em>root of trust</em>, the key used by verified boot to
+validate the operating system booted (if any). This tag is never provided
+to or returned from Keymaster in the key characteristics.</p>
+
+<h2 id="rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the value of the public exponent for an RSA key pair. This tag is
+relevant only to RSA keys, and necessary for all RSA keys.</p>
+
+<p>The value is a 64-bit unsigned integer that satisfies the requirements of an
+RSA public exponent. Because it is specified by the caller and therefore cannot
+be chosen by the implementation, it is a prime number. Trustlets support the
+value 2^16+1 and may support other reasonable values, in particular the value 3.
+If no exponent is specified or if the specified exponent is not supported,
+key generation fails with <code>KM_ERROR_INVALID_ARGUMENT</code>.</p>
+
+
+<h2 id="usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the date and time at which the key expires for verification and
+decryption purposes. After this time, any attempt to use a key with
+<a href="#purpose">KM_PURPOSE_VERIFY</a> or <a href="#purpose">KM_PURPOSE DECRYPT</a>
+provided to <a href="/security/keystore/implementer-ref#begin">begin</a> fails
+with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
+
+<p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
+
+
+<h2 id="user_auth_type">KM_TAG_USER_AUTH_TYPE</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies the types of user authenticators that may be used to authorize this
+key. When Keymaster is requested to perform an operation with a key with this
+tag, it receives an authentication token, and the token's
+<code>authenticator_type</code> field needs to match the value in the tag. For example,
+<code>(ntoh(token.authenticator_type) & auth_type_tag_value) != 0</code>,
+where <code>ntoh</code> is a function that converts
+network-ordered integers to host-ordered integers and
+<code>auth_type_tag_value</code> is the value of this tag.</p>
+
+<p>The value is a 32-bit integer bitmask of values from the enumeration:</p>
+
+<pre class="devsite-click-to-copy">
+typedef enum {
+ HW_AUTH_NONE = 0,
+ HW_AUTH_PASSWORD = 1 &lt;&lt; 0,
+ HW_AUTH_FINGERPRINT = 1 &lt;&lt; 1,
+ // Additional entries should be powers of 2.
+ HW_AUTH_ANY = UINT32_MAX,
+} hw_authenticator_type_t;
+</pre>
+
+
+<h2 id="user_secure_id">KM_TAG_USER_SECURE_ID</h2>
+
+<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Specifies that a key may only be used under a particular secure user
+authentication state. This tag is mutually exclusive
+with <a href="#no_auth_required">KM_TAG_NO_AUTH_REQUIRED</a>.</p>
+
+<p>The value is a 64-bit integer specifying the authentication policy state value
+which needs to be present in an authentication token (provided to
+<a href="/security/keystore/implementer-ref#begin">begin</a> with
+the <a href="#auth_token">KM_TAG_AUTH_TOKEN</a>) to authorize use of the key. Any
+call to <a href="/security/keystore/implementer-ref#begin">begin</a>
+with a key with this tag that does not provide an
+authentication token, or provides an
+authentication token without a matching policy state value, fails.</p>
+
+<p>This tag is repeatable. If any of the provided values matches any policy state
+value in the authentication token, the key is authorized for use. Otherwise the operation
+fails with <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
+
+</body>
+</html>
diff --git a/en/security/keystore/version-binding.html b/en/security/keystore/version-binding.html
new file mode 100644
index 00000000..930e6486
--- /dev/null
+++ b/en/security/keystore/version-binding.html
@@ -0,0 +1,176 @@
+<html devsite>
+ <head>
+ <title>Version Binding</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
+
+ //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>
+In Keymaster1, all keymaster keys were cryptographically bound to the device
+<em>Root of Trust</em>, the <a href="/security/verifiedboot/">verified boot
+key</a>. In Keymaster2, all keys are
+also bound to the operating system and patch level of the system image.
+This ensures that an attacker who discovers a weakness in an old
+version of system or TEE software cannot roll a device back to the vulnerable
+version and use keys created with the newer version. In addition, when a key
+with a given version and patch level is used on a device that has been upgraded
+to a newer version or patch level, the key is upgraded before it can be used,
+and the previous version of the key invalidated. In this way, as the device is
+upgraded, the keys will "ratchet" forward along with the device, but any
+reversion of the device to a previous release will cause the keys to be
+unusable.
+</p>
+
+<h2 id="hal-changes">HAL changes</h2>
+<p>
+To support version binding and version attestation, Android 7.1 added the tags
+<code>KM_TAG_OS_VERSION</code> and <code>KM_TAG_OS_PATCHLEVEL</code> and the
+methods <code>configure</code> and <code>upgrade_key</code>. The version tags
+are automatically added by keymaster2 implementations to all newly-generated (or
+updated) keys. Further, any attempt to use a key that does not have an OS
+version or patch level matching the current system OS version or patch level,
+respectively, is rejected with <code>KM_ERROR_KEY_REQUIRES_UPGRADE</code>.
+</p>
+<p>
+<code>KM_TAG_OS_VERSION</code> is a <code>KM_UINT</code> that represents the
+major, minor, and sub-minor portions of an Android system version as MMmmss,
+where MM is the major version, mm is the minor version and ss is the sub-minor
+version. For example 6.1.2 would be represented as 060102.
+</p>
+<p>
+<code>KM_TAG_OS_PATCHLEVEL</code> is a <code>KM_UINT</code> that represents the
+year and month of the last update to the system as YYYYMM, where YYYY is the
+four-digit year and MM is the two-digit month. For example, March 2016 would be
+represented as 201603.
+</p>
+
+<h3 id="upgrade_key">Upgrade_key</h3>
+<p>
+To allow keys to be upgraded to the new OS version and patch level of the system
+image, Android 7.1 added the <code>upgrade_key</code> method to the HAL:
+</p>
+
+<pre
+class="prettyprint">keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
+ const keymaster_key_blob_t* key_to_upgrade,
+ const keymaster_key_param_set_t* upgrade_params,
+ keymaster_key_blob_t* upgraded_key);
+</pre>
+
+<ul>
+ <li><code>dev</code> is the device structure</li>
+ <li><code>key_to_upgrade</code> is the key which needs to be upgraded</li>
+ <li><code>upgrade_params</code> are parameters needed to upgrade the key. These
+ will include <code>KM_TAG_APPLICATION_ID</code> and
+ <code>KM_TAG_APPLICATION_DATA</code>, which are necessary to decrypt the key
+ blob, if they were provided during generation.</li>
+ <li><code>upgraded_key</code> is the output parameter, used to return the new
+ key blob.</li>
+</ul>
+
+<p>
+If <code>upgrade_key</code> is called with a key blob that cannot be parsed or
+is otherwise invalid, it returns <code>KM_ERROR_INVALID_KEY_BLOB</code>. If it
+is called with a key whose patch level is greater than the current system value,
+it returns <code>KM_ERROR_INVALID_ARGUMENT</code>. If it is called with a key
+whose OS version is greater than the current system value, and the system value
+is non-zero, it returns KM_ERROR_INVALID_ARGUMENT. OS version upgrades from
+non-zero to zero are allowed. In the event of errors communicating with the
+secure world, it returns an appropriate error value (e.g.
+<code>KM_SECURE_HW_ACCESS_DENIED</code>, <code>KM_SECURE_HW_BUSY</code>, etc.)
+Otherwise, it returns <code>KM_ERROR_OK</code> and returns a new key blob in
+<code>upgraded_key</code>.
+</p>
+<p>
+<code>key_to_upgrade</code> remains valid after the <code>upgrade_key</code>
+call, and could theoretically be used again if the device were downgraded. In
+practice, keystore generally calls <code>delete_key</code> on the
+<code>key_to_upgrade</code> blob shortly after the call to upgrade_key. If
+<code>key_to_upgrade</code> had tag <code>KM_TAG_ROLLBACK_RESISTANT</code>, then
+<code>upgraded_key</code> should have it as well (and should be rollback
+resistant).
+</p>
+
+<h2 id="secure-configuration">Secure configuration</h2>
+<p>
+To implement version binding, the keymaster TA needs a way to securely receive
+the current OS version and patch level (version information), and to ensure that
+the information it receives strongly matches the information about the running
+system.
+</p>
+<p>
+To support secure delivery of version information to the TA, an <code><a
+href="https://android.googlesource.com/platform/system/core/+/master/mkbootimg/bootimg.h#48">os_version
+field</a></code> has been added to the boot image header. The boot image build
+script automatically populates this field. OEMs and keymaster TA implementers
+need to work together to modify device bootloaders to extract the version
+information from the boot image and pass it to the TA before the non-secure
+system is booted. This ensures that attackers cannot interfere with provisioning
+of version information to the TA.
+</p>
+
+<p>
+It is also necessary to ensure that the system image has the same version
+information as the boot image. To that end, the configure method has been added
+to the keymaster HAL:
+</p>
+
+
+<pre
+class="prettyprint">keymaster_error_t (*configure)(const struct keymaster2_device* dev,
+ const keymaster_key_param_set_t* params);
+</pre>
+
+<p>
+The <code>params</code> argument contains <code>KM_TAG_OS_VERSION</code> and
+<code>KM_TAG_OS_PATCHLEVEL</code>. This method is called by keymaster2 clients
+after opening the HAL, but before calling any other methods. If any other method
+is called before configure, the TA returns
+<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>.
+</p>
+
+<p>
+The first time <code>configure</code> is called after the device boots, it
+should verify that the version information provided matches what was provided by
+the bootloader. If the version information does not match,
+<code>configure</code> returns <code>KM_ERROR_INVALID_ARGUMENT</code>, and all
+other keymaster methods continue returning
+<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>. If the information matches,
+<code>configure</code> returns <code>KM_ERROR_OK</code>, and other keymaster
+methods begin functioning normally.
+</p>
+
+<p>
+Subsequent calls to <code>configure</code> return the same value returned by the
+first call, and do not change the state of keymaster. Note that this process
+will REQUIRErequire that all OTAs update both system and boot images; they can't
+be updated separately in order to keep the version information in sync.
+</p>
+
+<p>
+Because <code>configure</code> will be called by the system whose contents it is
+intended to validate, there is a narrow window of opportunity for an attacker to
+compromise the system image and force it to provide version information that
+matches the boot image, but which is not the actual version of the system. The
+combination of boot image verification, dm-verity validation of the system image
+contents, and the fact that <code>configure</code> is called very early in the
+system boot should make this window of opportunity difficult to exploit.
+</p>
+</body>
+</html>
diff --git a/en/security/selinux/customize.html b/en/security/selinux/customize.html
index 294d4040..98eafa4c 100644
--- a/en/security/selinux/customize.html
+++ b/en/security/selinux/customize.html
@@ -21,11 +21,16 @@
limitations under the License.
-->
-
-
-<p>Once you've integrated this base level of functionality and thoroughly analyzed
-the results, you may add your own policy settings to cover your customizations
-to the Android operating system. Of course, these policies must still meet the <a href="/compatibility/index.html">Android Compatibility program</a> requirements and not remove the default SELinux settings.</p>
+<p>After you've integrated this base level of functionality and thoroughly
+analyzed the results, you may add your own policy settings to cover your
+customizations to the Android operating system. Of course, these policies must
+still meet the <a href="/compatibility/index.html">Android Compatibility
+program</a> requirements and not remove the default SELinux settings.</p>
+
+<aside class="note"><strong>Note:</strong> For details on customizing SELinux
+in Android 8.0, see
+<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
+8.0</a>.</aside>
<p>Manufacturers should not remove existing security settings. Otherwise, they
risk breaking the Android SELinux implementation and the applications it
diff --git a/en/security/selinux/device-policy.html b/en/security/selinux/device-policy.html
index eb31aeb7..9474e14c 100644
--- a/en/security/selinux/device-policy.html
+++ b/en/security/selinux/device-policy.html
@@ -21,21 +21,23 @@
limitations under the License.
-->
-
-
-
-
<p>The Android Open Source Project (AOSP) provides a solid base policy for the
applications and services that are common across all Android devices.
Contributors to AOSP regularly refine this policy. The core policy is expected
to make up about 90&ndash;95% of the final on-device policy with device-specific
-customizations making up the remaining 5&ndash;10%. This article focuses on these
-device-specific customizations, how to write device-specific policy, and some
-of the pitfalls to avoid along the way.</p>
+customizations making up the remaining 5&ndash;10%. This article focuses on
+these device-specific customizations, how to write device-specific policy, and
+some of the pitfalls to avoid along the way.</p>
+
+<aside class="note"><strong>Note:</strong> For details on writing SELinux policy
+in Android 8.0, see
+<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
+8.0</a>.</aside>
<h2 id=device_bringup>Device bringup</h2>
-<p>While writing device-specific policy, progress through the following steps in order.</p>
+<p>While writing device-specific policy, progress through the following steps in
+order.</p>
<h3 id=run_in_permissive_mode>Run in permissive mode</h3>
diff --git a/en/security/selinux/implement.html b/en/security/selinux/implement.html
index 11473906..5a855ce5 100644
--- a/en/security/selinux/implement.html
+++ b/en/security/selinux/implement.html
@@ -21,18 +21,21 @@
limitations under the License.
-->
-
-
<p>SELinux is set up to default-deny, which means that every single access for
-which it has a hook in the kernel must be explicitly allowed by policy. This
+which it has a hook in the kernel must be explicitly allowed by policy. This
means a policy file is comprised of a large amount of information regarding
-rules, types, classes, permissions, and more. A full consideration of SELinux
+rules, types, classes, permissions, and more. A full consideration of SELinux
is out of the scope of this document, but an understanding of how to write
policy rules is now essential when bringing up new Android devices. There is a
great deal of information available regarding SELinux already. See <a
href="/security/selinux#supporting_documentation">Supporting
documentation</a> for suggested resources.</p>
+<aside class="note"><strong>Note:</strong> For details on implementing SELinux
+in Android 8.0, see
+<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
+8.0</a>.</aside>
+
<h2 id=summary_of_steps>Summary of steps</h2>
<p>Here is a brief summary of the steps needed to implement SELinux on your
@@ -113,8 +116,7 @@ add (register) and find (lookup) a binder reference for the service. This
configuration is read by the servicemanager process during startup.
<li><em>seapp_contexts</em> - Located in the sepolicy subdirectory. This file
assigns labels to app processes and /data/data directories. This configuration
-is read by the zygote process on each app launch and by installd during
-startup.
+is read by the zygote process on each app launch and by installd during startup.
<li><em>mac_permissions.xml</em> - Located in the sepolicy subdirectory. This
file assigns a seinfo tag to apps based on their signature and optionally their
package name. The seinfo tag can then be used as a key in the seapp_contexts
diff --git a/en/security/selinux/index.html b/en/security/selinux/index.html
index 03b8dd68..f45d517d 100644
--- a/en/security/selinux/index.html
+++ b/en/security/selinux/index.html
@@ -22,9 +22,6 @@
-->
-
-<h2 id=introduction>Introduction</h2>
-
<p>The Android security model is based in part on the concept of application
sandboxes. Each application runs in its own sandbox. Prior to Android 4.3,
these sandboxes were defined by the creation of a unique Linux UID for each
@@ -32,6 +29,10 @@ application at time of installation. Starting with Android 4.3,
Security-Enhanced Linux (SELinux) is used to further define the boundaries of
the Android application sandbox.</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>
+
<p>As part of the Android <a href="/security/index.html">
security model</a>, Android uses SELinux to enforce mandatory access control
(MAC) over all processes, even processes running with root/superuser privileges
diff --git a/en/source/64-bit-builds.html b/en/source/64-bit-builds.html
index f0079a86..30b51d6f 100644
--- a/en/source/64-bit-builds.html
+++ b/en/source/64-bit-builds.html
@@ -25,7 +25,7 @@
<h2 id=overview>Overview</h2>
-<p>From the build system’s perspective, the most notable change is that now it
+<p>From the build system’s perspective, the most noticeable change is that now it
supports building binaries for two target CPU architectures (64-bit and 32-bit)
in the same build. That’s also known as <em>Multilib build</em>.</p>
diff --git a/en/source/build-numbers.html b/en/source/build-numbers.html
index ef099f77..26d30d9c 100644
--- a/en/source/build-numbers.html
+++ b/en/source/build-numbers.html
@@ -40,6 +40,11 @@ API levels and NDK releases provided for convenience:</p>
</thead>
<tbody>
<tr>
+<td>Oreo</td>
+<td>8.0</td>
+<td>API level 26</td>
+</tr>
+<tr>
<td>Nougat</td>
<td>7.1</td>
<td>API level 25</td>
@@ -161,8 +166,14 @@ API levels and NDK releases provided for convenience:</p>
</tr>
</tbody>
</table>
-<p>Starting with Cupcake, individual builds are identified with a short
-build code, e.g. FRF85B.</p>
+<p>Starting with Oreo, individual builds are identified with a new build ID format, in the form of PVBB.YYMMDD.bbb.</p>
+<p>The P part represents the first letter of the code name of the platform release, e.g. O is Oreo.</p>
+<p>The V part represents a supported vertical. By convention, 'P' represents the primary platform branch.</p>
+<p>The BB part represents a alpha numeric code which allows Google to identify the exact code branch that the build was made from.</p>
+<p>The YYMMDD part identifies the date when the release is branched from or synced with the development branch. It is not guaranteed to be the exact date at which a build was made, and it is common that minor variations added to an existing build re-use the same date code as that existing build.</p>
+<p>The bbb part identifies individual versions related to the same date code, sequentially starting with 001.</p>
+<p>Older Android releases from Cupcake to Nougat uses a different build ID scheme. These Android builds are identified with a short build code, e.g. FRF85B.
+</p>
<p>The first letter is the code name of the release family, e.g. F is
Froyo.</p>
<p>The second letter is a branch code that allows Google to identify
@@ -197,6 +208,30 @@ site:</p>
</thead>
<tbody>
<tr>
+ <td>OPR6.170623.013</td>
+ <td>android-8.0.0_r4</td>
+ <td>Oreo</td>
+ <td>Nexus 5X, Nexus 6P</td>
+ </tr>
+ <tr>
+ <td>OPR6.170623.012</td>
+ <td>android-8.0.0_r3</td>
+ <td>Oreo</td>
+ <td>Pixel XL, Pixel</td>
+ </tr>
+ <tr>
+ <td>OPR6.170623.011</td>
+ <td>android-8.0.0_r2</td>
+ <td>Oreo</td>
+ <td>Pixel XL, Pixel</td>
+ </tr>
+ <tr>
+ <td>OPR6.170623.010</td>
+ <td>android-8.0.0_r1</td>
+ <td>Oreo</td>
+ <td>Pixel C</td>
+ </tr>
+ <tr>
<td>NZH54D</td>
<td>android-7.1.2_r33</td>
<td>Nougat</td>
diff --git a/en/source/site-updates.html b/en/source/site-updates.html
index 969f4cc5..656301c5 100644
--- a/en/source/site-updates.html
+++ b/en/source/site-updates.html
@@ -27,6 +27,567 @@ href="https://android.googlesource.com/platform/docs/source.android.com/+log/mas
Open Source Project (AOSP) docs/source.android.com log</a> for the complete
list of changes to this site.
+<h2 id="August-2017">August 2017</h2>
+
+<p>Android 8.0 has been released! This section describes the major new features in the Android 8.0 platform.</p>
+
+<h3 id="architecture">Architecture</h3>
+
+<h4>Treble</h4>
+<p>
+Android 8.0 includes support for Treble, a major re-architect of the
+Android OS framework designed to make it easier, faster, and less costly
+for manufacturers to update devices to a new version of Android. Documentation
+includes details on the <a href="/devices/architecture/hidl/index.html">HAL interface definition
+language (HIDL)</a>, a new <a href="/devices/architecture/configstore/index.html">ConfigStore HAL</a>,
+<a href="/devices/architecture/dto/index.html">Device Tree Overlays</a>,
+the <a href="/devices/architecture/vndk/index.html">Vendor Native Development
+Kit (VNDK)</a>, <a href="/devices/architecture/vintf/index.html">Vendor
+ Interface Objects (VINTF)</a>, <a href="/devices/architecture/kernel/modular-kernels.html">
+Modular Kernel requirements</a>, and the <a href="/devices/tech/vts/index.html">
+Vendor Test Suite (VTS) and Infrastructure</a>.
+</p>
+
+<h4>Kernel enhancements to LLDB/C++ debugging</h4>
+<p>
+The Android 8.0 release includes kernel enhancements that help developers create
+better applications by improving their debugging experience. For more
+information, see <a
+href="/devices/architecture/kernel/lldb-debug.html">Implementing
+kernel enhancements to LLDB/C++ debugging</a>.
+</p>
+
+<h4>Kernel Hardening</h4>
+<p>
+Upstreamed kernel hardening features and tools to find bugs in kernel drivers.
+For more information, see <a
+href="/devices/architecture/kernel/hardening.html">Kernel Hardening</a>.
+</p>
+
+<h4>Optimizing SquashFS at the Kernel Level</h4>
+<p>
+SquashFS is a compressed read-only filesystem for Linux, suitable for use on the
+system partition. The optimizations in this document help improve the
+performance of SquashFS. For more information, see <a
+href="/devices/architecture/kernel/squashfs.html">Optimizing
+SquashFS at the Kernel Level</a>.
+</p>
+
+<h3 id="art-dalvik">ART and Dalvik</h3>
+<h4>Fuzz Testing</h4>
+<p>
+The Android Open Source Project (AOSP) offers a new fuzzing testing suite for
+testing the <a href="/devices/tech/dalvik/">Android
+runtime (ART)</a> infrastructure. The new toolset, JFuzz and an improved
+DexFuzz, are directly available in AOSP now with accompanying documentation.
+See:
+<a
+href="https://android.googlesource.com/platform/art/+/master/tools/jfuzz/README.md">https://android.googlesource.com/platform/art/+/master/tools/jfuzz/README.md</a>
+<a
+href="https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/README">https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/README</a>
+</p>
+<p>
+Nothing is required to implement or use the new tools. You may make changes
+to the tools if required, just like you can make changes to the
+runtime/compiler already.
+</p>
+
+<h4>VDEX files: Improve System Update Performance</h4>
+<p>
+VDEX files improve the performance and user experience of software updates. VDEX
+files store pre-validated DEX files with verifier dependencies so that during
+system updates ART does not need to extract and verify the DEX files again. No
+action is needed to implement this feature. It is enabled by default. To
+disable the feature, set the <code>ART_ENABLE_VDEX</code> environment variable
+to <code>false</code>.
+</p>
+
+<h4>ART performance improvements</h4>
+<p>
+The Android runtime (ART) has been improved significantly in the Android 8.0
+release. This document summarizes enhancements device manufacturers can expect
+in ART. For more information, see <a
+href="/devices/tech/dalvik/improvements.html">Improving
+ART Performance in Android 8.0</a>.
+</p>
+
+<h4>Android A/B OTA Updates</h4>
+<p>
+This update answers common questions device manufacturers have regarding Android
+A/B (seamless) system updates. For more information, see <a
+href="/devices/tech/ota/ab_updates#frequently-asked-questions.html">A/B
+(Seamless) System Updates Frequently asked questions</a>.
+</p>
+
+<h3 id="automotive">Automotive</h3>
+
+<h4>Bluetooth connection management</h4>
+<p>
+Android 8.0 provides Bluetooth connection management in in-vehicle infotainment
+systems for a more seamless Bluetooth user experience. For more information, see
+<a href="/devices/automotive/ivi_connectivity.html#bluetooth-connection-management">
+Bluetooth connection management</a>.
+</p>
+
+<h4>Bluetooth multi-device HFP</h4>
+<p>
+Bluetooth multi-device connectivity lets users connect multiple devices to telephony profiles in
+an Android Automotive IVI Bluetooth. For more information, see
+<a href="/devices/automotive/ivi_connectivity.html#bluetooth-multi-device-connectivity">
+IVI Connectivity</a>.
+</p>
+
+<h4>Vehicle Camera HAL</h4>
+<p>
+Describes the design of an exterior view system (EVS) stack and provides the HAL
+specification for supporting the acquisition and presentation of vehicle camera
+data. For more information, see <a
+href="/devices/automotive/camera-hal.html">Exterior
+View System (EVS) Vehicle Camera HAL.</a>
+</p>
+
+<h3 id="bluetooth">Bluetooth</h3>
+<p>
+See the updated <a
+href="/devices/bluetooth/index.html">Bluetooth
+overview</a>.
+</p>
+
+<h4>Verifying and Debugging Bluetooth</h4>
+<p>
+A new page about how to verify and debug the native Bluetooth stack. See this page at
+<a href="/devices/bluetooth/verifying_debugging.html">Verifying and Debugging</a>.
+</p>
+
+<!--
+<h4>Bluetooth support for audio codecs</h4>
+<p>
+The Android 8.0 release includes support for Bluetooth high-definition audio
+codecs. For more information, see <a
+href="/devices/bluetooth/audio-codecs.html">Bluetooth
+Support for Audio Codecs in Android 8.0</a>.
+</p>
+-->
+
+<h3 id="camera">Camera</h3>
+
+<h4>Critical camera features</h4>
+<p>
+The Android 8.0 release contains these key enhancements to the Camera service:
+shared surfaces, enable multiple surfaces sharing the same OutputConfiguration
+System API for custom camera modes, and onCaptureQueueEmpty. For more
+information, see <a
+href="/devices/camera/versioning.html">Camera Version
+Support</a>.
+</p>
+
+<h3 id="configuration">Configuration</h3>
+
+<h4>Ambient Capabilities</h4>
+<p>
+Capabilities allow Linux processes to drop most root-like privileges, while
+retaining the subset of privileges that they require to perform their function.
+Ambient capabilities allows system services to configure capabilities in their
+<code>.rc</code> files, bringing all their configuration into a single file. For
+more information, see <a
+href="/devices/tech/config/ambient.html">Implementing
+Ambient Capabilities</a>.
+</p>
+
+<h4>Privileged Permission Whitelist Requirement</h4>
+<p>
+Starting in Android 8.0, all privileged apps must be explicitly whitelisted in
+system configuration XML files in the <code>/etc/permissions</code> directory.
+If they are not, then the device will boot, but the device implementation will
+not pass CTS. For more information, see <a
+href="/devices/tech/config/perms-whitelist.html">Privileged
+Permission Whitelist Requirement</a>.
+</p>
+
+<h4>Implementing USB HAL</h4>
+<p>
+The Android 8.0 release moves handling of USB commands out of init scripts and
+into a native USB daemon for better configuration and code reliability. For more
+information, see <a
+href="/devices/tech/config/usb-hal.html">Implementing
+USB HAL</a>.
+</p>
+
+<h3 id="connectivity">Connectivity</h3>
+
+<h4>Customizing Device Behavior for Out-of-balance Users</h4>
+<p>
+Android devices with no data balance allow network traffic through, requiring
+carriers and telecoms to implement mitigation protocols. This feature implements
+a generic solution that allows carriers and telcos to indicate when a device has
+run out of balance. For more information, see <a
+href="/devices/tech/connect/oob-users.html">Customizing
+device behavior for out-of-balance users</a>.
+</p>
+
+<h3 id="debugging">Debugging</h3>
+
+<h4>Enabling sanitizers in the Android build system</h4>
+<p>
+Sanitizers are compiler-based instrumentation components to use during
+development and testing in order to identify bugs and make Android better.
+Android's current set of sanitizers can discover and diagnose memory misuse bugs
+and potentially dangerous undefined behavior. For more information, see <a
+href="/devices/tech/debug/sanitizers.html">Enabling
+Sanitizers in the Android Build System</a>.
+</p>
+
+<h4>Recover devices in reboot loops</h4>
+<p>
+Android 8.0 includes a feature that sends out a "rescue party" when it notices
+core system components stuck in crash loops. Rescue Party then escalates through
+a series of actions to recover the device. For more information, see <a
+href="/devices/tech/debug/rescue-party.html">Rescue
+Party</a>.
+</p>
+
+<h4>Storaged</h4>
+<p>
+Android 8.0 adds support for <code>storaged</code>, an Android native daemon that
+collects and publishes storage metrics on Android devices. For more information,
+see <a
+href="/devices/tech/debug/storaged.html">Implementing
+Storaged</a>.
+</p>
+
+<h3 id="display">Display</h3>
+
+<h4>Air Traffic Control for floating windows</h4>
+<p>
+Android 8.0 introduces Air Traffic Control for floating windows in order to
+simplify and unify how apps display on top of other apps. Everything necessary
+to use the feature is included in the Android Open Source Project (AOSP).
+</p>
+<p>
+Air Traffic Control allows developers to create a new (managed) floating
+layer/window type for apps to use to display windows on-top of other apps. The
+feature displays ongoing notifications for all apps using a floating layer that
+lets the user manage the alert window.
+</p>
+<p>
+The Android Compatibility Test Suite (CTS) confirms:
+</p> <ul>
+ <li>The current alert window types are: <code>TYPE_PHONE</code>, <code>TYPE_PRIORITY_PHONE</code>,
+<code>TYPE_SYSTEM_ALERT</code>, <code>TYPE_SYSTEM_OVERLAY</code>, or <code>TYPE_SYSTEM_ERROR</code>
+ <li>Apps targeting the O SDK won't be able to use the window types above to
+display windows above other apps. They will need to use a new window type
+TYPE_APPLICATION_OVERLAY.
+ <li>Apps targeting older SDKs can still use the current window types; however,
+the windows will be z-ordered below the new TYPE_APPLICATION_OVERLAY windows.
+ <li>The system can move or resize windows in the new layer to reduce clutter.
+ <li>Device manufacturers must keep the notification that lets users control
+what is displayed over other apps.</li> </ul>
+
+<h4>Launching activities on secondary displays</h4>
+<p>
+Virtual displays are available to everyone, and they don't require any special
+hardware. Any application can create an instance of virtual display; and in the
+Android 8.0 release, activities can be launched on that virtual display if the
+associated feature is enabled.
+</p>
+<p>
+To support multi-display features, you should either use one of the
+existing supported ways of connecting secondary devices or build new hardware.
+The supported ways of connecting displays on Nexus and Pixel devices are Google
+Cast and <a
+href="https://developer.android.com/reference/android/hardware/display/VirtualDisplay.html">virtual
+displays inside apps</a>. Support of other ways depends on kernel driver support
+for each particular case (like MHL or DisplayPort over USB-C) and fully
+implementing interface definitions that are related to displays in
+HardwareComposer HAL (IComposerCallback.hal and IComposerClient.hal).
+</p>
+<p>
+Each of the ways may require SoC or OEM support. For example, to enable
+DisplayPort over USB-C, both hardware (SOC) and software (drivers) support is
+required. You might need to implement drivers for your hardware to support
+connecting external displays.
+</p>
+<p>
+The default implementation will allow launching fullscreen stacks of activities
+on secondary displays. You can customize the stacks and System UI and
+behavior on secondary displays.
+</p>
+
+<h4>Support for generic tooltip</h4>
+<p>
+Android 8.0 allows developers to provide descriptive action names and other
+helpful information on mouse hover over buttons and other icons. Device
+manufacturers may style the tooltip popup. Its layout is defined in
+<code>android/frameworks/base/core/res/res/layout/tooltip.xml</code>.
+</a>
+</p>
+<p>
+OEMs may replace the layout or change its dimensions and style parameters. Use
+only text and keep the size reasonably small. The feature is implemented
+entirely inside the View class, and there are quite exhaustive CTS tests that
+check many aspects of Tooltip behavior.
+</p>
+<p>
+
+<h4>Support for extended aspect ratio</h4>
+<p>
+Android 8.0 includes a new manifest attribute, <a
+href="https://developer.android.com/reference/android/R.attr.html#maxAspectRatio">maxAspectRatio</a>,
+which lets an activity or app specify the maximum aspect ratio it supports.
+maxAspectRatio replaces the previous meta-data tag with a first-class API and
+allows devices to support an aspect ratio greater than 16:9.
+</p><ul>
+<li>If an activity or app is <a
+href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">resizable</a>,
+allow the activity to fill the screen.
+<li>If an activity or app is non-resizeable or the platform is force resizing
+the activity, allow the app window to display up to the maximum aspect ratio,
+according to the <a
+href="https://developer.android.com/reference/android/R.attr.html#maxAspectRatio">maxAspectRatio</a>
+value. <ul>
+ <li>For applications on devices running Android 8.0, the default value is the
+aspect ratio of the current device.
+ <li>For applications on devices running earlier versions of Android, the
+default value is 16:9.</li> </ul>
+</li> </ul>
+
+<h4>Implementing Adaptive Icons</h4>
+<p>
+Adaptive Icons maintain a consistent shape intra-device but vary from device to
+device with only one icon asset provided by the developer. Additionally, icons
+support two layers (foreground and background) that can be used for motion to
+provide visual delight to users. For more information, see <a
+href="/devices/tech/display/adaptive-icons.html">Implementing
+Adaptive Icons</a>.
+</p>
+
+<h4>Night Light</h4>
+<p>
+Night Light, introduced in Android 7.0.1, allows users to reduce the amount of
+blue light that their screen emits. Android 8.0 gives users more control over the
+intensity of this effect. For more information, see <a
+href="/devices/tech/display/night-light.html">Implementing
+Night Light</a>.
+</p>
+
+<h4>Picture-in-picture</h4>
+<p>
+Android 8.0 includes support for picture-in-picture (PIP) on Android handheld
+devices. PIP allows users to resize an app with an ongoing activity, such as a
+video, into a small window. For more information, see <a
+href="/devices/tech/display/pip.html">Picture-in-Picture
+on Android handsets</a>.
+</p>
+
+<h4>Better Split-Screen Interactions</h4>
+<p>
+Multi-window lets multiple apps simultaneously display on users' device screens.
+Android 8.0 improves the default mode, split-screen, by compressing the top pane
+and resizing the launcher if a user taps Home after entering split-screen. For
+more information, see <a
+href="/devices/tech/display/split-screen.html">Better
+Split-Screen Interactions</a>.
+</p>
+
+<h4>Add Widgets/Shortcuts</h4>
+<p>
+A new API in Android 8.0 allows application developers to add shortcuts and
+widgets from inside the app instead of relying on the widget tray. The older
+method of adding shortcuts by sending a broadcast has been deprecated for
+security reasons. For more information, see <a
+href="/devices/tech/display/widgets-shortcuts.html">Implementing
+Add Widgets/Shortcuts</a>.
+</p>
+
+<h3 id="downloading-building">Downloading and Building</h3>
+
+<h4>Android LLVM Toolchain improvements</h4>
+<p>
+OEMs who wish to use our latest toolchain/tools will need to ensure that any of
+their private code compiles successfully with the updated toolchains. This may
+require them to fix existing issues in their code with undefined behavior. (Of
+course, they are free to use whatever tools they prefer to compile their own
+code too.)
+</p>
+<p>
+They must ensure their code is free of undefined behavior (by using tools like
+UBSan), so they are less susceptible to problems caused by newer toolchains. All
+of the toolchains are always updated directly in AOSP. Everything will be
+available well before OC even ships, so OEMs should be following along
+already.
+</p>
+<p>
+See the <a href="https://llvm.org/">public Clang/LLVM</a> documentation for
+general instructions and the <a
+href="https://android.googlesource.com/platform/external/clang/+/dev/ReadmeAndroid.md">Android
+Clang/LLVM</a> documentation set within AOSP for Android-specific guidance.
+Finally, join the <a
+href="https://groups.google.com/forum/#!forum/android-llvm">android-llvm</a>
+public group to get help and take part in development.
+</p>
+
+<h3 id="drm">DRM</h3>
+
+<h4>DRM/KMS in Linux Kernel Version 4.9</h4>
+<p>
+The Digital Rights Management (DRM)/Kernel Mode Setting (KMS) framework used by
+Android is developed and maintained by Linux kernel developers in the Linux
+kernel. Android merges down from the Linux kernel. By merging down from our
+common kernel, device manufacturers gain the DRM/KMS framework automatically.
+</p>
+<p>
+DRM/KMS became viable in Linux kernel version 4.9, and Android <strong>strongly
+encourages</strong> OEM partners to use DRM/KMS starting with this kernel
+version. <a href="https://lwn.net/Articles/565422/">Atomic Display Framework
+(ADF)</a>, the display framework officially supported by Android today, will not
+be supported in 4.9 and higher versions of the common Android kernel; instead,
+Android will support DRM/KMS from this version. OEMs can continue to use ADF (or
+any other framework), but Android will not support them in the common Android
+kernel.
+</p>
+<p>
+To implement DRM/KMS, you will need to write your own drivers using
+DRM/KMS in addition to merging down the DRM/KMS framework from the android
+common kernel.
+</p>
+<!--
+<h3 id="keystore">Keystore</h3>
+
+<h4>Keymaster3 Implementer's guide</h4>
+<p>
+Android 8.0 updates Keymaster, the keystore HAL, by extending the capabilities of
+hardware-backed key storage on Android devices. This builds upon the Android N
+MR2 updates to Keymaster2. For more information, see <a
+href="/security/keystore/index.html">Keymaster 3 documentation</a>.
+</p>
+-->
+<h3 id="security-enhancements">Security Enhancements</h3>
+
+<h4>Insecure TLS Version Fallback removed from HttpsURLConnection</h4>
+<p>
+Insecure TLS/SSL protocol version fallback is a workaround for buggy
+implementations of TLS protocol downgrade negotiation in some servers. This is
+vulnerable to POODLE. When Chrome 45 dropped the insecure fallback in September
+2015, less than 0.01% of servers relied on it. To improve security, insecure TLS
+version fallback has been removed from <a
+href="https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html">HttpsURLConnection</a>
+in Android 8.0. For more details, see <a
+href="https://android-developers.googleblog.com/2017/04/android-o-to-drop-insecure-tls-version.html
+">this blog post</a>.
+</p>
+<p>
+To test this feature on devices with Android 8.0, run this CTS test case:
+</p>
+
+<pre class="devsite-click-to-copy devsite-terminal" data-terminal-prefix="# ">
+cts-tradefed run cts -m CtsLibcoreOkHttpTestCases</pre>
+
+<h3 id="performance">Performance</h3>
+
+<h4>Flash Wear Management</h4>
+<p>
+Describes eMMC behavior and new features to help OEMs lower the risk of a
+failing eMMC in the automotive environment. For more information, see <a
+href="/devices/tech/perf/flash-wear.html">Flash Wear
+Management in Android Automotive</a>.
+</p>
+
+<h4>Optimizing Boot Times</h4>
+<p>
+Guidance for improving boot times for specific Android devices. For more
+information, see <a
+href="/devices/tech/perf/boot-times.html">Optimizing
+boot times</a>.
+</p>
+
+<h4>Task Snapshots</h4>
+<p>
+Task Snapshots is infrastructure introduced in Android 8.0 that combines
+screenshots for Recents Thumbnails as well as Saved Surfaces from Window Manager
+to save memory. For more information, see <a
+href="/devices/tech/perf/task-snapshots.html">Task
+Snapshots</a>.
+</p>
+
+<h3 id="peripherals">Peripherals</h3>
+
+<h4>Default Print Services</h4>
+<p>
+A <a
+href="https://developer.android.com/reference/android/printservice/PrintService.html">print
+service</a> is an app that discovers and presents printers to a device's print
+framework. In earlier Android versions, users had to search for and install
+third-party print services to be able to print.
+</p>
+<p>
+Android 8.0 includes a default print service in <code><a
+href="https://android.googlesource.com/platform/packages/services/BuiltInPrintService/">platform/packages/services/BuiltInPrintService/</a></code>
+that lets users print on modern printers without installing any additional apps.
+This implementation supports printers that use the Internet Printing Protocol
+(IPP) to communicate with the printer and use PCLm, PWG-Raster, or PDF to send
+printable content. For older printers, users should install the app recommended
+by the <a
+href="https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r1/packages/PrintRecommendationService/">PrintRecommendationService</a>
+as seen in this <a href="https://youtu.be/M_JGeGLpOKs?t=16m20s">this I/O presentation</a>.
+
+<h3 id="reference">Reference Updates</h3>
+
+<p>
+The <a href="/reference/">Reference</a> section has been added to the top-level
+navigation. As part of the <a href="/devices/architecture/treble">Treble</a>
+release, a <a href="/reference/hidl/">HIDL reference</a> section was added.
+The <a href="/reference/tradefed/">Trade Federation</a> and the
+<a href="/reference/hal/">legacy HAL</a> reference documentation has been updated.
+</p>
+
+<h3 id="settings-menu">Settings menu</h3>
+
+<h4>Settings: Patterns and Components</h4>
+<p>
+In Android 8.0, the Settings menu gains several components and widgets that
+cover common uses. For more information, see <a
+href="/devices/tech/settings/patterns-components.html">Patterns
+and Components</a>.
+</p>
+
+<h4>Settings: Updated information architecture</h4>
+<p>
+Android 8.0 introduces a new information architecture for the Settings app. The
+goal of the new information architecture is to simplify the way settings are
+organized and make it easier for users to quickly find the settings needed to
+customize their Android devices. For more information, see Implementing <a
+href="/devices/tech/settings/info-architecture.html">Updated
+Information Architecture</a>.
+</p>
+
+<h4>Personalized Settings</h4>
+<p>
+The Android Settings app provides a list of suggestions to the users. This
+feature provides ranking for suggestions, based on any contextual signal or the
+user's past interactions with suggestions. For more information, see <a
+href="/devices/tech/settings/personalized.html">Personalized
+Settings</a>.
+</p>
+
+<h4>Implementing Settings: Universal Search</h4>
+<p>
+Android 8.0 adds expanded search capabilities for the Settings menu. This document
+describes how to add a setting and ensure it is properly indexed for Settings.
+For more information, see <a
+href="/devices/tech/settings/universal-search.html">Universal
+Search</a>.
+</p>
+
+<h3 id="storage">Storage</h3>
+
+<h4>Faster storage statistics</h4>
+<p>
+Android 8.0 leverages the ext4 filesystem's "quota" support to return disk usage
+statistics almost instantly. For more information, see <a
+href="/devices/storage/faster-stats.html">Implementing
+faster storage statistics</a>.
+</p>
+
<h2 id="april-2017">April 2017</h2>
<p>Welcome to a new source.android.com! The site has been overhauled to make it
easier for you to navigate, search, and read its ever-growing set of information.
diff --git a/zh-cn/compatibility/cdd.html b/zh-cn/compatibility/cdd.html
new file mode 100644
index 00000000..e93af033
--- /dev/null
+++ b/zh-cn/compatibility/cdd.html
@@ -0,0 +1,134 @@
+<html devsite><head>
+ <title>Android 兼容性定义文档</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 兼容性定义文档 (CDD)。本文档列举了设备需要满足哪些要求才能与最新的 Android 版本兼容。为了与 Android 兼容,设备实现必须满足此兼容性定义文档(包括以参考资料的形式纳入的任何文档)中列出的要求。对于 Android 平台的每个版本,我们都将提供详细的 CDD。CDD 代表 Android 兼容性的“政策”方向。</p>
+
+<p>请务必注意,Android 兼容性计划的政策中已明确规定,任何测试套件(包括 CTS)都不是真正综合全面的。例如,CTS 包含可检查 OpenGL 图形 API 是否存在以及行为是否正确的测试,但任何软件测试都无法验证这类图形在屏幕上实际显示时的正确性。从更笼统的角度来说,测试硬件功能(如键盘、显示密度、WLAN 和蓝牙)是否存在是不太可能的事情。</p>
+
+<p>CDD 的作用是整理和阐明具体要求,并消除歧义。CDD 并非综合全面的指南。由于 Android 代码是一系列开放源代码,因此代码本身就是其平台及 API 的综合“规范说明”。CDD 如同一个统合其他内容(如 SDK API 文档)的纲要,它提供了一个 Android 源代码的使用范式框架,从而促进最终实现一个兼容的系统。</p>
+
+<p>如果您要打造与指定 Android 版本兼容的设备,请先查看该版本的源代码,然后阅读相应的 CDD 并遵守其准则。要了解更多详情,请查看<a href="/compatibility/android-cdd.pdf">最新 CDD</a>。</p>
+
+<p>
+您可以采用 HTML 网页形式或可轻松下载的 PDF 格式查看最新 CDD:</p>
+ <ul>
+ <li><a href="android-cdd.html">HTML</a></li>
+ <li><a href="android-cdd.pdf">PDF</a></li>
+ </ul>
+
+<p>在下面查找旧版 CDD 和已获批准的发行版本字符串:</p>
+
+<table>
+ <tbody><tr>
+ <th>版本</th>
+ <th>PDF</th>
+ <th>HTML/XHTML</th>
+ <th>字符串</th>
+ </tr>
+ <tr>
+ <td>7.1</td>
+ <td><a href="7.1/android-7.1-cdd.pdf">android-7.1-cdd.pdf</a></td>
+ <td><a href="7.1/android-7.1-cdd.html">android-7.1-cdd.html</a></td>
+ <td><a href="7.1/versions.html">7.1 版</a></td>
+ </tr>
+ <tr>
+ <td>7.0</td>
+ <td><a href="7.0/android-7.0-cdd.pdf">android-7.0-cdd.pdf</a></td>
+ <td><a href="7.0/android-7.0-cdd.html">android-7.0-cdd.html</a></td>
+ <td><a href="7.0/versions.html">7.0 版</a></td>
+ </tr>
+ <tr>
+ <td>6.0</td>
+ <td><a href="6.0/android-6.0-cdd.pdf">android-6.0-cdd.pdf</a></td>
+ <td><a href="6.0/android-6.0-cdd.html">android-6.0-cdd.html</a></td>
+ <td><a href="6.0/versions.html">6.0 版</a></td>
+ </tr>
+ <tr>
+ <td>5.1</td>
+ <td><a href="5.1/android-5.1-cdd.pdf">android-5.1.cdd.pdf</a></td>
+ <td><a href="5.1/android-5.1-cdd.html">android-5.1-cdd.html</a></td>
+ <td><a href="5.1/versions.html">5.1 版</a></td>
+ </tr>
+ <tr>
+ <td>5.0</td>
+ <td><a href="5.0/android-5.0-cdd.pdf">android-5.0.cdd.pdf</a></td>
+ <td><a href="5.0/android-5.0-cdd.html">android-5.0-cdd.html</a></td>
+ <td><a href="5.0/versions.html">5.0 版</a></td>
+ </tr>
+ <tr>
+ <td>4.4</td>
+ <td><a href="4.4/android-4.4-cdd.pdf">android-4.4.cdd.pdf</a></td>
+ <td><a href="4.4/android-4.4-cdd.html">android-4.4-cdd.html</a></td>
+ <td><a href="4.4/versions.html">4.4 版</a></td>
+ </tr>
+ <tr>
+ <td>4.3</td>
+ <td><a href="4.3/android-4.3-cdd.pdf">android-4.3.cdd.pdf</a></td>
+ <td><a href="4.3/android-4.3-cdd.html">android-4.3-cdd.html</a></td>
+ <td><a href="4.3/versions.html">4.3 版</a></td>
+ </tr>
+ <tr>
+ <td>4.2</td>
+ <td><a href="4.2/android-4.2-cdd.pdf">android-4.2.cdd.pdf</a></td>
+ <td><a href="4.2/android-4.2-cdd.html">android-4.2-cdd.html</a></td>
+ <td><a href="4.2/versions.html">4.2 版</a></td>
+ </tr>
+ <tr>
+ <td>4.1</td>
+ <td><a href="4.1/android-4.1-cdd.pdf">android-4.1.cdd.pdf</a></td>
+ <td><a href="4.1/android-4.1-cdd.html">android-4.1-cdd.html</a></td>
+ <td><a href="4.1/versions.html">4.1 版</a></td>
+ </tr>
+ <tr>
+ <td>4.0</td>
+ <td><a href="4.0/android-4.0-cdd.pdf">android-4.0.cdd.pdf</a></td>
+ <td><a href="4.0/android-4.0-cdd.html">android-4.0-cdd.html</a></td>
+ <td><a href="4.0/versions.html">4.0 版</a></td>
+ </tr>
+ <tr>
+ <td>2.3</td>
+ <td><a href="2.3/android-2.3-cdd.pdf">android-2.3.cdd.pdf</a><br />
+ <a href="2.3/android-2.3.3-cdd.pdf">android-2.3.3-cdd.pdf</a></td>
+ <td><a href="2.3/android-2.3-cdd.html">android-2.3-cdd.html</a></td>
+ <td><a href="2.3/versions.html">2.3 版</a></td>
+ </tr>
+ <tr>
+ <td>2.2</td>
+ <td><a href="2.2/android-2.2-cdd.pdf">android-2.2.cdd.pdf</a></td>
+ <td><a href="2.2/android-2.2-cdd.html">android-2.2-cdd.html</a></td>
+ <td><a href="2.2/versions.html">2.2 版</a></td>
+ </tr>
+ <tr>
+ <td>2.1</td>
+ <td><a href="2.1/android-2.1-cdd.pdf">android-2.1.cdd.pdf</a></td>
+ <td><a href="2.1/android-2.1-cdd.html">android-2.1-cdd.html</a></td>
+ <td><a href="2.1/versions.html">2.1 版</a></td>
+ </tr>
+ <tr>
+ <td>1.6</td>
+ <td><a href="1.6/android-1.6-cdd.pdf">android-1.6.cdd.pdf</a></td>
+ <td><a href="1.6/android-1.6-cdd.html">android-1.6-cdd.html</a></td>
+ <td> </td>
+ </tr>
+</tbody></table>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/compatibility/cts/audio-framework.html b/zh-cn/compatibility/cts/audio-framework.html
index 62d7db13..849a0a36 100644
--- a/zh-cn/compatibility/cts/audio-framework.html
+++ b/zh-cn/compatibility/cts/audio-framework.html
@@ -26,7 +26,7 @@
<p>音频中的<a href="/devices/audio/latency_measure.html#measuringRoundTrip">往返延迟</a>是指录制、处理并回放音频信号所需的时间。</p>
-<p>要使用 CTS 验证程序测量往返延迟,请将回环插头连接到 3.5 毫米 (⅛") 耳机连接器。(如果没有回环插头,您可以按照<a href="/devices/audio/loopback.html">音频回环外接小配件</a>说明轻松制作一个回环插头。)</p>
+<p>要使用 CTS 验证程序测量往返延迟,请将回环插头连接到 3.5 毫米 (⅛") 耳机接口。(如果没有回环插头,您可以按照<a href="/devices/audio/loopback.html">音频回环外接小配件</a>说明轻松制作一个回环插头。)</p>
<table>
<tbody><tr>
@@ -238,7 +238,7 @@
<h2>音频频响未处理测试</h2>
<p>对于该测试,除了 USB 参照麦克风和外部扬声器之外,还需要使用声压级电平表(SPL 表)。
</p>
-<p>另外值得一提的是,在本测试中,每个测试的播放和测试部分都具有自己的按钮。这样做是为了帮助测试不具备轻松播放功能,但仍然可以测试未处理录音源的某些设备。</p>
+<p>另外值得一提的是,在本测试中,每个测试的播放和测试部分都具有自己的按钮。这样做是为了帮助测试不具备简便的播放功能,但仍然可以测试未处理录音源的某些设备。</p>
<table>
<tbody><tr>
<td width="50%">开始 CTS 频响未处理测试。</td>
diff --git a/zh-cn/compatibility/cts/camera-hal.html b/zh-cn/compatibility/cts/camera-hal.html
index bda08330..9a03b9df 100644
--- a/zh-cn/compatibility/cts/camera-hal.html
+++ b/zh-cn/compatibility/cts/camera-hal.html
@@ -20,15 +20,15 @@
limitations under the License.
-->
-<p>本文档列出了可用于评估 Android 相机硬件抽象层 (HAL) 的所有测试,面向的是原始设备制造商 (OEM) 和应用处理器 (AP) 供应商,旨在帮助他们确保能正确实施相机 HAL,并最大限度减少缺陷。尽管这是 Android 兼容性测试套件 (CTS) 的自愿性补充测试,但它显著扩大了相机测试覆盖范围,并且确实能够发现一些潜在错误。</p>
+<p>本文档列出了可用于评估 Android 相机硬件抽象层 (HAL) 的所有测试,它面向的是原始设备制造商 (OEM) 和应用处理器 (AP) 供应商,旨在帮助他们确保正确实现相机 HAL,并最大限度减少缺陷。尽管这是 Android 兼容性测试套件 (CTS) 的自愿性补充测试,但它显著扩大了相机测试覆盖范围,并且确实能够发现一些潜在错误。</p>
<p>通过执行这些测试,原始设备制造商 (OEM) 可验证其是否正确集成了最新的 Android 相机硬件抽象层 (HAL) 3.2 接口。当符合核对清单中的所有规范时,设备实施可被视为<em></em>完全符合新的 Android 相机 HAL 接口规范。这反过来又使得设备能够正确支持构建相机应用所依据的全新 <code>android.hardware.camera2</code> 文件包。</p>
<h2 id="camera_hal_3_2_specification">[ ] 1. 相机 HAL 3.2 规范</h2>
-<p>Android 相机 HAL 3.2 规范是有关设备必须满足哪些要求的权威信息来源;本文档提供了所有测试的摘要,可将其用作核对清单。相机 HAL 实施方(例如 AP 供应商)应逐条检查 HAL 3.2 规范,并确保其设备符合该规范。</p>
+<p>Android 相机 HAL 3.2 规范是有关设备必须满足哪些要求的权威信息来源;本文档提供了所有测试的摘要,可将其用作核对清单。相机 HAL 实现方(例如 AP 供应商)应逐条检查 HAL 3.2 规范,并确保其设备符合该规范。</p>
-<p>最新的 HAL 3.2 规范的相关定义请参见 L 常规 Android 平台开发套件 (PDK) 中的以下文件:</p>
+<p>要了解最新的 HAL 3.2 规范的相关定义,请参阅 L 常规 Android 平台开发套件 (PDK) 中的以下文件:</p>
<ul>
<li><em></em>相机 HAL 3.x 接口和规范:<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera3.h">hardware/libhardware/include/hardware/camera3.h</a></code>、<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera_common.h">hardware/libhardware/include/hardware/camera_common.h</a></code>
@@ -41,8 +41,8 @@
<p>以下是适用于最新 Android 相机的主要测试类型以及相关说明:</p>
<ul>
- <li><em><a href="#native_tests">原生</a></em>:直接针对相机 HAL 接口的测试</li><li><em><a href="#cts_tests">兼容性测试套件 (CTS)</a></em>:自动运行的标准 Android 测试,可确保设备兼容性;有关详情请参阅 <a href="/compatibility/cts/index.html">CTS 简介</a>和<a href="/devices/tech/test_infra/tradefed/index.html">贸易联盟概述</a>
- </li><li><em><a href="#its_tests">图像测试套件 (ITS)</a></em>:手动运行的测试,可确保图像正确性;有关设置说明,请参见顶级和测试专用的 <code>README</code> 文件以及 tutorial.py</li><li><em><a href="#manual_tests_with_aosp_camera_app">针对 Android 开源项目 (AOSP) 相机应用的手动测试</a></em>:对常见相机功能进行类似于用户体验的测试</li><li><em><a href="#manual_testingcam_tests">手动 TestingCam 测试</a></em>:从源中的 <code>pdk/apps/TestingCamera/</code> 运行
+ <li><em><a href="#native_tests">原生</a></em>:直接针对相机 HAL 接口的测试</li><li><em><a href="#cts_tests">兼容性测试套件 (CTS)</a></em>:自动运行的标准 Android 测试,可确保设备兼容性;有关详情,请参阅 <a href="/compatibility/cts/index.html">CTS 简介</a>和<a href="/devices/tech/test_infra/tradefed/index.html">贸易联盟概述</a>
+ </li><li><em><a href="#its_tests">图像测试套件 (ITS)</a></em>:手动运行的测试,可确保图像正确性;有关设置说明,请参阅顶级和测试专用的 <code>README</code> 文件以及 tutorial.py</li><li><em><a href="#manual_tests_with_aosp_camera_app">针对 Android 开放源代码项目 (AOSP) 相机应用的手动测试</a></em>:对常见相机功能进行用户体验之类的测试</li><li><em><a href="#manual_testingcam_tests">手动 TestingCam 测试</a></em>:从源中的 <code>pdk/apps/TestingCamera/</code> 运行
</li><li><em><a href="#manual_testingcam2_tests">手动 TestingCam2.1 测试</a></em>:从源中的 <code>pdk/apps/TestingCamera2/</code> 运行
</li></ul>
@@ -58,10 +58,10 @@
<p>设置这类测试的命令如下:</p>
-<pre>
-$ cd hardware/libhardware/tests/camera*/
-$ mm
-$ adb remount; adb sync
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">cd hardware/libhardware/tests/camera*/</code>
+<code class="devsite-terminal">mm</code>
+<code class="devsite-terminal">adb remount; adb sync</code>
</pre>
<h3 id="hal_3_x_tests">[ ] 3.1. HAL 3.x 测试</h3>
@@ -70,8 +70,8 @@ $ adb remount; adb sync
<p>运行所有测试的命令如下:</p>
-<pre>
-$ adb shell /data/nativetest/camera3_test/camera3_test
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell /data/nativetest/camera3_test/camera3_test
</pre>
<p>对于每项通过的测试,您会收到 <strong>OK</strong>。在输出信息末尾处会提供错误日志,以及有关所有已通过测试的摘要。</p>
@@ -82,22 +82,20 @@ $ adb shell /data/nativetest/camera3_test/camera3_test
<p>运行所有测试的命令如下:</p>
-<pre>
-$ adb shell /data/nativetest/camera3_test/camera3_test
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell /data/nativetest/camera3_test/camera3_test
</pre>
<p>要运行单个测试,请传递 <code>--gtest_filter</code> 参数和相应测试名称,命令如下:</p>
-<pre>
-$ adb shell /data/nativetest/camera2_test/camera2_test \
---gtest_filter=Camera2Test.OpenClose
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell /data/nativetest/camera2_test/camera2_test --gtest_filter=Camera2Test.OpenClose
</pre>
<p>要运行一小组测试,请使用带有 <code>--gtest_filter</code> 参数的通配符,命令如下:</p>
-<pre>
-$ adb shell /data/nativetest/camera2_test/camera2_test \
---gtest_filter=Camera2Test.*
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell /data/nativetest/camera2_test/camera2_test --gtest_filter=Camera2Test.*
</pre>
<h3 id="3_tests_that_interact_with_the_camera_service">[ ] 3.3. 与相机服务交互的测试</h3>
@@ -151,14 +149,14 @@ $ adb shell /data/nativetest/camera2_test/camera2_test \
<p>有关如何设置和运行测试的说明,请参阅此顶级文件夹中的最新 <code>README</code> 文件。设置方法如下:<code>make
cts</code></p>
-<pre>
-$ extract root/out/host/linux-x86/cts-verfier/android-cts-verifier.zip
-$ cd android-cts-verifier
-$ adb install -r CtsVerifier.apk
-$ cd CameraITS
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">extract root/out/host/linux-x86/cts-verfier/android-cts-verifier.zip</code>
+<code class="devsite-terminal">cd android-cts-verifier</code>
+<code class="devsite-terminal">adb install -r CtsVerifier.apk</code>
+<code class="devsite-terminal">cd CameraITS</code>
</pre>
-<p>有关脚本使用方法的演示,请参见 <code>tests</code> 子目录中的 <code>tutorial.py</code>。每项测试都归属于相应的 <code>tests/scene<#></code> 子目录。有关具体的测试说明,请参阅每个子目录中的 <code>README</code> 文件。</p>
+<p>有关脚本使用方法的演示,请参阅 <code>tests</code> 子目录中的 <code>tutorial.py</code>。每项测试都归属于相应的 <code>tests/scene<#></code> 子目录。有关具体的测试说明,请参阅每个子目录中的 <code>README</code> 文件。</p>
<p>您将需要使用由可重复使用的特定目标(如白色墙面、灰色卡片和台灯)构建的简单物理环境。Android 设备安装在三脚架上,而设备的相机功能通过脚本运行。大多数测试的结果要么是通过,要么是失败,不过有些测试还会提供一些指标。</p>
@@ -236,16 +234,16 @@ $ cd CameraITS
<p>设置这类测试的命令如下:</p>
-<pre>
-$ make mediaframeworktest
-$ adb install out/target/product/<em>&lt;name&gt;</em>/data/app/mediaframeworktest.apk
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">make mediaframeworktest</code>
+<code class="devsite-terminal">adb install out/target/product/<em>&lt;name&gt;</em>/data/app/mediaframeworktest.apk</code>
</pre>
<p>其中 <em><code><name></name></code></em> 变量表示包含供应商产品的目录。</p>
<p>查找以下目录或其子目录中的所有测试:</p>
-<pre>
+<pre class="devsite-click-to-copy">
frameworks/base/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest
</pre>
@@ -264,13 +262,13 @@ frameworks/base/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktes
<p>查看所有可用测试的命令如下:</p>
-<pre>
-$ adb shell pm list instrumentation
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell pm list instrumentation
</pre>
<p>这将会产生类似以下信息的结果:</p>
-<pre>
+<pre class="devsite-click-to-copy">
instrumentation:com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
(target=com.android.mediaframeworktest)
instrumentation:com.android.mediaframeworktest/.MediaRecorderStressTestRunner
@@ -285,7 +283,7 @@ instrumentation:com.android.mediaframeworktest/.MediaFrameworkPowerTestRunner
<p>例如:</p>
-<pre>
+<pre class="devsite-click-to-copy">
com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
com.android.mediaframeworktest/.MediaRecorderStressTestRunner
com.android.mediaframeworktest/.MediaFrameworkPerfTestRunner
@@ -294,33 +292,28 @@ com.android.mediaframeworktest/.MediaFrameworkPowerTestRunner
<p>然后,您可以将每个组件传递到 <code>adb shell am instrument</code>,如下所示:</p>
-<pre>
-$ adb shell am instrument -w &lt;component.name&gt;
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -w &lt;component.name&gt;
</pre>
<p>其中 &lt;component.name&gt; 等同于上面提取的值。例如:</p>
-<pre>
-$ adb shell am instrument -w \
-com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
</pre>
<p>请注意,虽然类路径是 Java 文件包 + 类名称,但工具包不一定与 Java 文件包相同。连接组件名称时,请确保您使用的是 AndroidManifest.xml 文件包,而不是测试运行器类所在的 Java 文件包。</p>
<p>要运行某一类测试,请传递 -e 类 <test-class> 参数,命令如下:</test-class></p>
-<pre>
-$ adb shell am instrument -e class \
-com.android.mediaframeworktest.integration.CameraBinderTest -w \
-com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -e class com.android.mediaframeworktest.integration.CameraBinderTest -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
</pre>
<p>如果只运行某个测试类中的单个方法,请将井号 (#) 和方法名称(在本例中为 <code>testConnectPro</code>)附加到类名称,如下所示:</p>
-<pre>
-$ adb shell am instrument -e class \
-'com.android.mediaframeworktest.integration.CameraBinderTest#testConnectPro' -w
-\ com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testConnectPro' -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
</pre>
<h3 id="media_settings_functional_tests">[ ] 7.2. 媒体设置功能测试</h3>
@@ -328,23 +321,21 @@ $ adb shell am instrument -e class \
<p>下面是一个运行功能测试的示例。该测试用于验证不同相机设置(即闪光灯、曝光、白平衡、场景、照片大小和地理标记)组合的基本功能。</p>
<p>运行以下测试命令:</p>
-<pre>
-$ adb shell am instrument -w -r -e delay_msec 15 -e log true -e class \
-com.android.mediaframeworktest.functional.camera.CameraPairwiseTest \
-com.android.mediaframeworktest/com.android.mediaframeworktest.CameraStressTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -w -r -e delay_msec 15 -e log true -e class com.android.mediaframeworktest.functional.camera.CameraPairwiseTest com.android.mediaframeworktest/com.android.mediaframeworktest.CameraStressTestRunner
</pre>
<h3 id="media_integration_tests">[ ] 7.3. 媒体集成测试</h3>
<p>下面是一个运行集成测试的示例,此例中包括 mediaframeworktest/integration/CameraBinderTest.java 和 mediaframeworktest/CameraStressTestRunner.java:</p>
-<pre>
-$ adb shell am instrument -e class \ 'com.android.mediaframeworktest.<strong>integration</strong>.<strong>CameraBinderTest'</strong> -w \ 'com.android.mediaframeworktest/.<strong>CameraStressTestRunner'</strong>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -e class \ 'com.android.mediaframeworktest.<strong>integration</strong>.<strong>CameraBinderTest'</strong> -w \ 'com.android.mediaframeworktest/.<strong>CameraStressTestRunner'</strong>
</pre>
<p>如果成功通过测试,则会产生类似如下输出信息的结果:</p>
-<pre>
+<pre class="devsite-click-to-copy">
-----
com.android.mediaframeworktest.integration.CameraBinderTest:...........
@@ -361,10 +352,8 @@ OK (11 tests)
<p>此预览存储空间测试将打开并释放 200 次相机预览。系统每隔 20 次迭代会记录一次 ps mediaserver 的快照,并且在 200 次迭代后比较存储空间使用量的差异。如果差异大于 150kM,则表明未通过测试。</p>
<p>运行以下测试命令:</p>
-<pre>
-$ adb shell am instrument -w -r -e class \
-com.android.mediaframeworktest.performance.MediaPlayerPerformance#testCameraPreviewMemoryUsage
-\ com.android.mediaframeworktest/.MediaFrameworkPerfTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -w -r -e class com.android.mediaframeworktest.performance.MediaPlayerPerformance#testCameraPreviewMemoryUsage com.android.mediaframeworktest/.MediaFrameworkPerfTestRunner
</pre>
<p>更详细的输出信息位于以下路径:<code>/sdcard/mediaMemOutput.txt</code></p>
@@ -373,10 +362,8 @@ com.android.mediaframeworktest.performance.MediaPlayerPerformance#testCameraPrev
<p>用于执行单元测试的命令很相似。例如,对于 CameraMetadataTest.java,测试命令如下:</p>
-<pre>
-$ adb shell am instrument -e class \
-'com.android.mediaframeworktest.unit.CameraMetadataTest' -w \
-'com.android.mediaframeworktest/.CameraStressTestRunner'
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -e class 'com.android.mediaframeworktest.unit.CameraMetadataTest' -w 'com.android.mediaframeworktest/.CameraStressTestRunner'
</pre>
<h3 id="media_stress_tests">[ ] 7.6. 媒体压力测试</h3>
@@ -385,9 +372,8 @@ $ adb shell am instrument -e class \
<p>运行以下测试命令:</p>
-<pre>
-$ adb shell am instrument -w
-com.google.android.camera.tests/com.android.camera.stress.CameraStressTestRunner
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell am instrument -w com.google.android.camera.tests/com.android.camera.stress.CameraStressTestRunner
</pre>
<p>您必须确保通过所有测试。</p>
diff --git a/zh-cn/compatibility/cts/camera-its-box-assembly.html b/zh-cn/compatibility/cts/camera-its-box-assembly.html
index 00e096e8..00d49d5c 100644
--- a/zh-cn/compatibility/cts/camera-its-box-assembly.html
+++ b/zh-cn/compatibility/cts/camera-its-box-assembly.html
@@ -20,7 +20,7 @@
limitations under the License.
-->
-<p>盒装 ITS 包含一个根据计算机辅助设计 (CAD) 图纸进行激光切割的塑料盒、一部图表平板电脑和一部被测设备 (DUT)。本页提供了组装盒装 ITS 的分步说明。</p>
+<p>盒装 ITS 由一个根据计算机辅助设计 (CAD) 图纸激光切割而成的塑料盒、一部图表平板电脑和一部被测设备 (DUT) 组成。本页提供了组装盒装 ITS 的分步说明。</p>
<p><img src="images/camera_iab_cad.png"/></p>
<p class="caption"><strong>图 1</strong>. 盒装 ITS 的 CAD 图纸。</p>
@@ -30,8 +30,8 @@
<ul>
<li>十字头螺丝刀</li>
<li>钳子</li>
-<li>手持雕刻刀</li>
-<li>钢丝钳或剪刀(可选)</li>
+<li>美工刀</li>
+<li>钢丝钳或剪刀(非必备)</li>
</ul>
<h2 id="lighting">第 1 步:照明</h2>
diff --git a/zh-cn/compatibility/cts/camera-its-box.html b/zh-cn/compatibility/cts/camera-its-box.html
index 70b62f4b..3efdb652 100644
--- a/zh-cn/compatibility/cts/camera-its-box.html
+++ b/zh-cn/compatibility/cts/camera-its-box.html
@@ -31,7 +31,7 @@
</ul>
<h2 id="get-started">开始设置</h2>
-<p>盒装 ITS 包含一个通过计算机辅助设计 (CAD) 绘图进行激光切割的塑料盒、一部图表平板电脑和一部被测设备 (DUT)。开始使用相机盒装 ITS:</p>
+<p>盒装 ITS 由一个根据计算机辅助设计 (CAD) 图纸激光切割而成的塑料盒、一部图表平板电脑和一部被测设备 (DUT) 组成。开始使用相机盒装 ITS:</p>
<ol>
<li><a href="camera_its_iab_tech_drawings.zip">下载技术图纸</a>。</li>
<li><a href="camera-its-box-assembly.html">组装盒子</a>。</li>
@@ -50,8 +50,8 @@
<ol>
<li>为平板电脑接通电源并开机。如果系统提示您设置帐号,请跳过(CameraITS 不需要与平板电脑配对任何帐号)。</li>
<li>将平板电脑更新为 Android 7.0 或更高版本(Android 6.x 及更早版本不支持 CameraITS)。</li>
-<li><em></em>通过依次转到“设置”&gt;“关于平板电脑”并点按<strong>版本号</strong>五次来启用开发者模式。</li>
-<li><em></em>返回“设置”并选择<strong>开发者选项</strong>。
+<li>依次转到“设置”&gt;“关于平板电脑”<em></em>,然后点按<strong>版本号</strong> 5 次,从而启用开发者模式。</li>
+<li>返回“设置”<em></em>并选择<strong>开发者选项</strong>。
<table>
<tbody><tr>
@@ -79,7 +79,9 @@
<li>执行三次测试,以隐藏可能会遮盖平板电脑屏幕上的图表的提示和用户提示。
<ol style="list-style-lower-alpha">
<li>将平板电脑正面朝上放在桌子上(请勿将平板电脑连接到盒子的后板)</li>
-<li>运行以下命令:<pre>$ python tools/run_all_tests.py device=$device_id camera=0 chart=$chart_id scenes=2,3</pre>场景 2 和 3 需要平板电脑来显示图像,因此平板电脑会提示您“允许云端硬盘访问您设备上的照片、媒体和文件吗?”。通过按<strong>允许</strong>清除此提示(并防止以后再次出现提示)。</li>
+<li>运行以下命令:<pre class="devsite-terminal devsite-click-to-copy">
+python tools/run_all_tests.py device=$device_id camera=0 chart=$chart_id scenes=2,3
+</pre>场景 2 和 3 需要平板电脑来显示图像,因此平板电脑会提示您“允许云端硬盘访问您设备上的照片、媒体和文件吗?”。通过按<strong>允许</strong>清除此提示(并防止以后再次出现提示)。</li>
<li>再次运行该命令。平板电脑会提示您“保留此文件的副本吗?”,并建议保存到 Google 云端硬盘。通过按“云端硬盘”图标,然后按<strong>取消</strong>上传到云端硬盘,清除此提示(并防止以后再次出现提示)。</li>
<li>最后,运行 <code>tools/run_all_tests.py</code> 并确认当前场景会随着脚本循环自动变换为不同的场景。尽管大多数测试将失败(因为相机未指向图表),但您可以验证平板电脑是否正确地循环播放场景,而不会在屏幕上显示任何提示或其他弹出式窗口。</li></ol></li></ol>
@@ -89,23 +91,29 @@
<li>一 (1) 个盒装 ITS</li>
<li>一 (1) 部用于显示场景的 Pixel C,序列号:5811000011</li>
<li>两 (2) 个 DUT,它们使用相同的版本号指纹并安装了 CTS 验证程序 7.0_8+ 应用。DUT 示例:<ul>
-<li>一 (1) 部用于后置摄像头 (0) 测试的 Pixel NOF26W,序列号:FA6BM0305016。要安装 CTS 验证程序应用,请解压缩 android-cts-verifier.zip,然后运行<pre>$ adb -s FA6BM0305016 install -r android-cts-verifier/CtsVerifier.apk</pre></li>
-<li>一 (1) 部用于前置摄像头 (1) 测试的 Pixel NOF26W,序列号:FA6BM0305439。要安装 CTS 验证程序应用,请解压缩 android-cts-verifier.zip,然后运行<pre>$ adb -s FA6BM0305439 install -r android-cts-verifier/CtsVerifier.apk</pre></li>
+<li>一 (1) 部用于后置摄像头 (0) 测试的 Pixel NOF26W,序列号:FA6BM0305016。要安装 CTS 验证程序应用,请解压缩 android-cts-verifier.zip,然后运行<pre class="devsite-terminal devsite-click-to-copy">
+adb -s FA6BM0305016 install -r android-cts-verifier/CtsVerifier.apk
+</pre></li>
+<li>一 (1) 部用于前置摄像头 (1) 测试的 Pixel NOF26W,序列号:FA6BM0305439。要安装 CTS 验证程序应用,请解压缩 android-cts-verifier.zip,然后运行<pre class="devsite-terminal devsite-click-to-copy">
+adb -s FA6BM0305439 install -r android-cts-verifier/CtsVerifier.apk
+</pre>
+</li>
</ul>
</li></ul>
<h3 id="scenes-0-4">运行场景 0-4</h3>
<p>对前置和后置摄像头并行运行场景 0-4:</p>
-<pre>$ cd android-cts-verifier/CameraITS
-$ . build/envsetup.sh
-$ python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">cd android-cts-verifier/CameraITS</code>
+<code class="devsite-terminal">. build/envsetup.sh</code>
+<code class="devsite-terminal">python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011</code>
</pre>
<p>示例:</p>
<table>
<tbody><tr>
-<td><img src="images/camera_its_cam0.png" align="center"/></td>
-<td align="center"><img src="images/camera_its_cam0.png"/></td>
+<td><img src="/compatibility/cts/images/camera_its_cam0.png" align="center"/></td>
+<td align="center"><img src="/compatibility/cts/images/camera_its_cam0.png"/></td>
</tr>
<tr>
<td align="center"><p class="caption"><strong>图 1</strong>. 相机 0 序列号:FA6BM0305016</p>
@@ -117,18 +125,27 @@ $ python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 c
<h3 id="retry-scenes">重试场景</h3>
<p>您可以为前置和后置摄像头或单个摄像头重试场景:</p><ul>
-<li>对前置和后置摄像头并行重试场景:<pre>$ python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011 scenes=3,4</pre></li>
-<li>对单个摄像头重试场景:<pre>$ python tools/run_all_tests.py device=FA6BM0305016 chart=5811000011 camera=1 scenes=3,4</pre></li>
+<li>对前置和后置摄像头并行重试场景:<pre class="devsite-terminal devsite-click-to-copy">
+python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011 scenes=3,4
+</pre>
+</li>
+<li>对单个摄像头重试场景:<pre class="devsite-terminal devsite-click-to-copy">
+python tools/run_all_tests.py device=FA6BM0305016 chart=5811000011 camera=1 scenes=3,4
+</pre>
+</li>
</ul>
<h3 id="scenes-0-4">运行场景 5</h3>
<p>场景 5 需要进行特殊设置并具有特定光线(有关详情,请参阅 CTS 验证程序下载内容中的 CameraITS.pdf 文档)。您可以单独运行场景 5(在盒子外部)以并行测试两部设备。</p>
<ul>
-<li>在两部设备上为前置和后置摄像头并行运行场景 5:<pre>$ python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011 scenes=5</pre>
-<br /><img src="images/camera_its_scene5.png" width="50%"/><br />
+<li>在两部设备上为前置和后置摄像头并行运行场景 5:<pre class="devsite-terminal devsite-click-to-copy">
+python tools/run_parallel_tests.py device0=FA6BM0305016 device1=FA6BM0305439 chart=5811000011 scenes=5
+</pre>
+<br /><img src="/compatibility/cts/images/camera_its_scene5.png" width="50%"/><br />
<strong>图 3</strong>. 相机场景 5。</li>
-<li>在单部设备上为前置和后置摄像头运行场景 5:<pre>$ python tools/run_all_tests.py device=FA6BM0305016 camera=0 scenes=5
-$ python tools/run_all_tests.py device=FA6BM0305016 camera=1 scenes=5
+<li>在单部设备上为前置和后置摄像头运行场景 5:<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">python tools/run_all_tests.py device=FA6BM0305016 camera=0 scenes=5</code>
+<code class="devsite-terminal">python tools/run_all_tests.py device=FA6BM0305016 camera=1 scenes=5</code>
</pre></li>
</ul>
@@ -137,16 +154,22 @@ $ python tools/run_all_tests.py device=FA6BM0305016 camera=1 scenes=5
</p>
<ul>
<li><strong>查看运行测试的进度</strong>。命令 <code>run_parallel_tests</code> 仅在相机场景测试完成后输出结果,因此要在执行测试期间查看结果,您必须使用 Android 设备监控器或 <code>adb logcat</code> 来验证进度和/或查看屏幕截图。<br />
-<br />adb 命令示例:<pre>$ adb -s FA6BM0305016 logcat -v time</pre>屏幕截图命令示例:<pre>$ adb -s FA6BM0305016 shell screencap -p /sdcard/screencap.png
-$ adb -s FA6BM0305016 pull /sdcard/screencap.png
-$ display ./screencap.png
+<br />adb 命令示例:<pre class="devsite-terminal devsite-click-to-copy">
+adb -s FA6BM0305016 logcat -v time
+</pre>屏幕截图命令示例:<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">adb -s FA6BM0305016 shell screencap -p /sdcard/screencap.png</code>
+<code class="devsite-terminal">adb -s FA6BM0305016 pull /sdcard/screencap.png</code>
+<code class="devsite-terminal">display ./screencap.png</code>
</pre></li>
<li><strong>查看结果</strong>。将相机 ITS 结果另存为报告:<ol>
-<li>按<strong>通过</strong>并保存报告:<br /><img src="images/camera_its_results.png" width="50%"/><br />
+<li>按<strong>通过</strong>并保存报告:<br /><img src="/compatibility/cts/images/camera_its_results.png" width="50%"/><br />
<strong>图 4</strong>. 相机 ITS 报告。</li>
-<li>从设备中提取报告:<pre>$ adb -s FA6BM0305016 pull /sdcard/verifierReports</pre></li>
+<li>从设备中提取报告:<pre class="devsite-terminal devsite-click-to-copy">
+adb -s FA6BM0305016 pull /sdcard/verifierReports
+</pre>
+</li>
<li>解压缩报告文件并查看 test_result.xml。
-<br /><img src="images/camera_its_reports.png"/><br />
+<br /><img src="/compatibility/cts/images/camera_its_reports.png"/><br />
<strong>图 5</strong>. 相机 ITS 报告。<br /></li>
</ol>
</li>
diff --git a/zh-cn/compatibility/cts/development.html b/zh-cn/compatibility/cts/development.html
index c4c154f2..2a412c3b 100644
--- a/zh-cn/compatibility/cts/development.html
+++ b/zh-cn/compatibility/cts/development.html
@@ -22,20 +22,22 @@
<h2 id="initializing-your-repo-client">初始化您的 Repo 客户端</h2>
<p>在发出 <code>repo
-init</code> 命令时,按照相关<a href="/source/downloading.html">说明</a>进行操作以获取并构建 Android 源代码,但指定一个特定的 CTS 分支名称,例如 <code>-b android-5.0_r2</code>。这可确保您的 CTS 更改将包含在下一个及后续 CTS 版本中。</p>
+init</code> 命令时,请按照相关<a href="/source/downloading.html">说明</a>进行操作以获取并构建 Android 源代码,但应指定一个特定的 CTS 分支名称,例如 <code>-b android-5.0_r2</code>。这可确保您的 CTS 更改将包含在下一个及后续 CTS 版本中。</p>
<h2 id="building-and-running-cts">构建和运行 CTS</h2>
<p>执行以下命令以构建 CTS 并启动交互式 CTS 控制台:</p>
<p class="note"><strong>注意</strong>:您可以为 <code>TARGET_PRODUCT</code> 提供以下其他值之一,以针对不同的架构进行构建:<code>aosp_x86_64</code> 或 <code>aosp_mips</code></p>
-<pre><code>cd <em>/path/to/android/root</em>
-make cts -j32 TARGET_PRODUCT=aosp_arm64
-cts-tradefed
-</code></pre>
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">cd <em>/path/to/android/root</em></code>
+<code class="devsite-terminal">make cts -j32 TARGET_PRODUCT=aosp_arm64</code>
+<code class="devsite-terminal">cts-tradefed</code>
+</pre>
<p>例如,在 cts-tf 控制台中,输入:</p>
-<pre><code>run cts --plan CTS
-</code></pre>
+<pre class="devsite-click-to-copy">
+tf&gt; run cts --plan CTS
+</pre>
<h2 id="writing-cts-tests">编写 CTS 测试</h2>
@@ -69,7 +71,7 @@ cts-tradefed
<p>对于 Android 6.0 及更早版本,请使用 CTS v1。对于 CTS v1,示例代码位于 <code>cts/tests/tests/example</code> 中。
</p>
<p>CTS v1 测试中的目录结构如下所示:</p>
-<pre class="no-pretty-print">
+<pre class="devsite-click-to-copy">
cts/
tests/
tests/
@@ -83,11 +85,11 @@ cts/
cts/
SampleDeviceTest.java
</pre>
-<h4 id="cts-v2"><strong>CTS v2</strong></h4>
+<h4 id="cts-v2">CTS v2</h4>
<p>对于 Android 7.0 及更高版本,请使用 CTS v2。有关详情,请参阅 <a href="https://android.googlesource.com/platform/cts/+/master/tests/sample/">AOSP 中的示例测试</a>。</p>
<p>CTS v2 目录结构如下所示:</p>
-<pre class="no-pretty-print">
+<pre class="devsite-click-to-copy">
cts/
tests/
<em>module-name</em>/
@@ -110,21 +112,21 @@ cts/
<p>如果您使用的是 CTS v1,请参阅 <code>cts/tests/tests/example</code> 下的示例并创建一个新目录。另外,请确保从其 <code>Android.mk</code> 中将新软件包的模块名称添加到 <code>cts/CtsTestCaseList.mk</code> 中的 <code>CTS_COVERAGE_TEST_CASE_LIST</code>。该 Makefile 由 <code>build/core/tasks/cts.mk</code> 用来将所有测试组合在一起以创建最终 CTS 软件包。</p>
<h4 id="cts-v2">CTS v2</h4>
-<p>按照下列步骤操作,使用示例测试 <code><a href="https://android.googlesource.com/platform/cts/+/master/tests/sample/">/cts/tests/sample/</a></code> 快速启动新的测试模块:</p>
+<p>按照下列步骤,使用示例测试 <code><a href="https://android.googlesource.com/platform/cts/+/master/tests/sample/">/cts/tests/sample/</a></code> 快速启动新的测试模块:</p>
<ol>
- <li>运行以下命令来创建测试目录并将示例文件复制到该目录:<pre class="no-pretty-print">$ mkdir cts/tests/<i>module-name</i> &amp;&amp; cp -r cts/tests/sample/* cts/tests/<i>module-name</i></pre>
+ <li>运行以下命令来创建测试目录并将示例文件复制到该目录:<pre class="devsite-terminal devsite-click-to-copy">mkdir cts/tests/<i>module-name</i> &amp;&amp; cp -r cts/tests/sample/* cts/tests/<i>module-name</i></pre>
</li><li>转到 <code>cts/tests/<em>module-name</em></code>,然后按照上述建议的命名规范替换掉出现的所有“[Ss]ample”。
</li><li>更新 <code>SampleDeviceActivity</code> 以运行您要测试的功能。
</li><li>更新 <code>SampleDeviceTest</code> 以确保相关测试成功或记录错误日志。</li>
</ol>
-<h4><strong>其他目录</strong></h4>
+<h4>其他目录</h4>
<p>此外,还可以添加其他 Android 目录,如 <code>assets</code>、<code>jni</code>、<code>libs</code> 和 <code>res</code>。要添加 JNI 代码,请在项目根目录中的 <code>src</code> 旁创建一个目录,并将原生代码和 <code>Android.mk</code> 包含在其中。</p>
<p>Makefile 通常包含以下设置:</p>
-<pre>
+<pre class="devsite-click-to-copy">
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libCtsSample_jni
@@ -145,7 +147,7 @@ include $(BUILD_SHARED_LIBRARY)
<p>最后,需要修改项目根目录中的 <code>Android.mk</code> 文件,以构建原生代码并依赖于该代码,如下所示:</p>
-<pre>
+<pre class="devsite-click-to-copy">
# All tests should include android.test.runner.
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/zh-cn/compatibility/cts/downloads.html b/zh-cn/compatibility/cts/downloads.html
index 3df3cf21..3484ec18 100644
--- a/zh-cn/compatibility/cts/downloads.html
+++ b/zh-cn/compatibility/cts/downloads.html
@@ -23,39 +23,39 @@
<p>感谢您对 Android 兼容性计划的关注!您可以通过以下链接访问关于该计划的重要文档和信息。随着 CTS 的更新,此网页上会陆续添加新的版本。CTS 版本在链接名称中由 R&lt;数字&gt; 表示。</p>
<h2 id="android-71">Android 7.1</h2>
-<p>Android 7.1 是代号为 Nougat-MR1 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-7.1_r6”标记同步。</p>
+<p>Android 7.1 是代号为 Nougat-MR1 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-7.1_r7”标记同步。</p>
<ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r6-linux_x86-arm.zip">Android 7.1 R6 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r6-linux_x86-x86.zip">Android 7.1 R6 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r6-linux_x86-arm.zip">Android 7.1 R6 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r6-linux_x86-x86.zip">Android 7.1 R6 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r7-linux_x86-arm.zip">Android 7.1 R7 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.1_r7-linux_x86-x86.zip">Android 7.1 R7 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r7-linux_x86-arm.zip">Android 7.1 R7 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r7-linux_x86-x86.zip">Android 7.1 R7 CTS 验证程序 - x86</a></li>
</ul>
<h2 id="android-70">Android 7.0</h2>
-<p>Android 7.0 是代号为 Nougat 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-7.0_r10”标记同步。</p>
+<p>Android 7.0 是代号为 Nougat 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-7.0_r11”标记同步。</p>
<ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r10-linux_x86-arm.zip">Android 7.0 R10 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r10-linux_x86-x86.zip">Android 7.0 R10 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r10-linux_x86-arm.zip">Android 7.0 R10 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r10-linux_x86-x86.zip">Android 7.0 R10 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r11-linux_x86-arm.zip">Android 7.0 R11 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-7.0_r11-linux_x86-x86.zip">Android 7.0 R11 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r11-linux_x86-arm.zip">Android 7.0 R11 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r11-linux_x86-x86.zip">Android 7.0 R11 CTS 验证程序 - x86</a></li>
</ul>
<h2 id="android-60">Android 6.0</h2>
-<p>Android 6.0 是代号为 Marshmallow 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-6.0_r19”标记同步。</p>
+<p>Android 6.0 是代号为 Marshmallow 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-6.0_r20”标记同步。</p>
<ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r19-linux_x86-arm.zip">Android 6.0 R19 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r19-linux_x86-x86.zip">Android 6.0 R19 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r19-linux_x86-arm.zip">Android 6.0 R19 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r19-linux_x86-x86.zip">Android 6.0 R19 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r20-linux_x86-arm.zip">Android 6.0 R20 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-6.0_r20-linux_x86-x86.zip">Android 6.0 R20 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r20-linux_x86-arm.zip">Android 6.0 R20 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r20-linux_x86-x86.zip">Android 6.0 R20 CTS 验证程序 - x86</a></li>
</ul>
<h2 id="android-51">Android 5.1</h2>
-<p>Android 5.1 是代号为 Lollipop-MR1 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-5.1_r20”标记同步。</p>
+<p>Android 5.1 是代号为 Lollipop-MR1 的开发里程碑版本。以下测试的源代码可以与开放源代码树中的“android-cts-5.1_r21”标记同步。</p>
<ul>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r20-linux_x86-arm.zip">Android 5.1 R20 兼容性测试套件 (CTS) - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r20-linux_x86-x86.zip">Android 5.1 R20 兼容性测试套件 (CTS) - x86</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r20-linux_x86-arm.zip">Android 5.1 R20 CTS 验证程序 - ARM</a></li>
-<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r20-linux_x86-x86.zip">Android 5.1 R20 CTS 验证程序 - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r21-linux_x86-arm.zip">Android 5.1 R21 兼容性测试套件 (CTS) - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-5.1_r21-linux_x86-x86.zip">Android 5.1 R21 兼容性测试套件 (CTS) - x86</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r21-linux_x86-arm.zip">Android 5.1 R21 CTS 验证程序 - ARM</a></li>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r21-linux_x86-x86.zip">Android 5.1 R21 CTS 验证程序 - x86</a></li>
</ul>
<h2 id="android-50">Android 5.0</h2>
@@ -125,6 +125,7 @@
<h2 id="cts-media-files">CTS 媒体文件</h2>
<p>以下媒体文件是进行 CTS 媒体压力测试所必需的。</p>
<ul>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.3.zip">CTS 媒体 1.3</a></li>
<li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.2.zip">CTS 媒体 1.2</a></li>
<li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip">CTS 媒体 1.1</a></li>
<li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.0.zip">CTS 媒体 1.0</a></li>
diff --git a/zh-cn/compatibility/cts/interpret.html b/zh-cn/compatibility/cts/interpret.html
index 6f69cfbd..9c2fd3c3 100644
--- a/zh-cn/compatibility/cts/interpret.html
+++ b/zh-cn/compatibility/cts/interpret.html
@@ -21,7 +21,7 @@
-->
<p>CTS 测试结果位于以下文件中:</p>
-<pre>
+<pre class="devsite-click-to-copy">
$CTS_ROOT/android-cts/repository/results/&lt;start_time&gt;.zip
</pre>
@@ -29,7 +29,7 @@ $CTS_ROOT/android-cts/repository/results/&lt;start_time&gt;.zip
<p>在 zip 压缩包中,testResult.xml 文件会包含实际的结果。在任何网络浏览器(推荐使用与 HTML 5 技术兼容的浏览器)中打开此文件,即可查看测试结果。</p>
-<p>使用 Chrome 浏览器时,如果 testResult.xml 显示空白页面,请<a href="https://www.chromium.org/developers/how-tos/run-chromium-with-flags">更改浏览器配置</a>以启用 <em>--allow-file-access-from-files</em> 命令行标记。</p>
+<p>使用 Chrome 浏览器时,如果 testResult.xml 显示空白页面,请<a href="https://www.chromium.org/developers/how-tos/run-chromium-with-flags">更改浏览器配置</a>以启用 --allow-file-access-from-files 命令行标记。<em></em></p>
<h3 id="reading-the-test-results">阅读测试结果</h3>
@@ -50,13 +50,13 @@ $CTS_ROOT/android-cts/repository/results/&lt;start_time&gt;.zip
<section class="expandable">
<h4 class="showalways">显示 CTS v1 测试摘要示例</h4>
- <img src="images/cts-test-summary.png" alt="CTS v1 测试摘要" id="figure1a"/>
+ <img src="/compatibility/cts/images/cts-test-summary.png" alt="CTS v1 测试摘要" id="figure1a"/>
<p class="img-caption"><strong>图 1a.</strong> CTS v1 测试摘要示例</p>
</section>
<section class="expandable">
<h4 class="showalways">显示 CTS v2 测试摘要示例</h4>
- <img src="images/cts-v2-test-summary.png" alt="CTS v2 测试摘要" id="figure1b"/>
+ <img src="/compatibility/cts/images/cts-v2-test-summary.png" alt="CTS v2 测试摘要" id="figure1b"/>
<p class="img-caption"><strong>图 1b.</strong> CTS v2 测试摘要示例</p>
</section>
@@ -71,13 +71,13 @@ $CTS_ROOT/android-cts/repository/results/&lt;start_time&gt;.zip
<section class="expandable">
<h4 class="showalways">显示 CTS v1 测试报告示例</h4>
- <img src="images/cts-test-report.png" alt="CTS v1 测试报告" id="figure2a"/>
+ <img src="/compatibility/cts/images/cts-test-report.png" alt="CTS v1 测试报告" id="figure2a"/>
<p class="img-caption"><strong>图 2a.</strong> CTS v1 测试报告示例</p>
</section>
<section class="expandable">
<h4 class="showalways">显示 CTS v2 测试报告示例</h4>
- <img src="images/cts-v2-test-report.png" alt="CTS v2 测试报告" id="figure2b"/>
+ <img src="/compatibility/cts/images/cts-v2-test-report.png" alt="CTS v2 测试报告" id="figure2b"/>
<p class="img-caption"><strong>图 2b.</strong> CTS v2 测试报告示例</p>
</section>
diff --git a/zh-cn/compatibility/cts/run.html b/zh-cn/compatibility/cts/run.html
index 8902cc39..fb3e5495 100644
--- a/zh-cn/compatibility/cts/run.html
+++ b/zh-cn/compatibility/cts/run.html
@@ -28,7 +28,7 @@
<li>至少连接一个设备。
</li><li>在开始运行 CTS 时,按<strong>主屏幕</strong>按钮将设备设置为显示主屏幕。</li><li>当设备在运行测试时,它不能用于执行任何其他任务,并且必须保持静止状态(以免触发传感器活动),同时要让相机指向某个可以聚焦的对象。
</li><li>在运行 CTS 时,不要按设备上的任何键。按测试设备上的键或触摸其屏幕会干扰正在运行的测试,并且可能导致测试失败。
- </li><li>通过运行 CTS 包所在的压缩文件夹中的 cts-tradefed<em></em> 脚本((例如 <code>$ ./android-cts/tools/cts-tradefed</code>))来启动 CTS 控制台。
+ </li><li><em></em>通过运行解压缩 CTS 包所得的文件夹中的 cts-tradefed 脚本(例如 <code>$ ./android-cts/tools/cts-tradefed</code>)来启动 CTS 控制台。
</li><li>通过附加以下命令启动默认测试计划(包含所有测试包):<code>run
cts --plan CTS</code>。这将启动测试兼容性所需的所有 CTS 测试。
<ul>
diff --git a/zh-cn/compatibility/cts/setup.html b/zh-cn/compatibility/cts/setup.html
index 5af2c393..607e04fb 100644
--- a/zh-cn/compatibility/cts/setup.html
+++ b/zh-cn/compatibility/cts/setup.html
@@ -39,8 +39,8 @@
<p>确保 <code>adb</code> 和 <code>aapt</code> 位于您的系统路径中。以下命令假定您已在主目录中打开了软件包归档文件:</p>
<hr />
-<pre>
-$ export PATH=$PATH:$HOME/android-sdk-linux/build-tools/&lt;version&gt;
+<pre class="devsite-terminal devsite-click-to-copy">
+export PATH=$PATH:$HOME/android-sdk-linux/build-tools/&lt;version&gt;
</pre>
<p class="note"><strong>注意:</strong>请确保起始路径和目录名称均准确无误。</p>
@@ -80,7 +80,7 @@ $ export PATH=$PATH:$HOME/android-sdk-linux/build-tools/&lt;version&gt;
<p>原始设备制造商(OEM) 可以将 <code>PRODUCT_PROPERTY_OVERRIDES</code> 添加到其 device.mk 文件以设置这项属性,具体如以下示例所示:</p>
-<pre>
+<pre class="devsite-click-to-copy">
#ro.product.first_api_level indicates the first api level, device has been commercially launched on.
PRODUCT_PROPERTY_OVERRIDES +=\
ro.product.first_api_level=21
@@ -132,7 +132,7 @@ ro.product.first_api_level=21
<p class="warning"><strong>警告:</strong>这将清空设备中的所有用户数据。</p>
</li><li>将设备的语言设置为英语(<strong>美国</strong>):<strong>设置 &gt; 语言和输入法 &gt; 语言</strong>
</li><li>如果设备上具有 GPS 或 WLAN/移动网络功能,则打开位置信息设置:<strong>设置 &gt; 位置信息 &gt; 开启</strong>
- </li><li>连接到满足以下要求的 WLAN 网络:支持 IPv6,可以将被测设备 (DUT) 视为<em>隔离客户端</em>(请参阅上文的<a href="#physical_environment">物理环境</a>部分),并可以连接到互联网:<strong>设置 &gt; WLAN</strong>
+ </li><li>连接到满足以下要求的 WLAN 网络:支持 IPv6,可以将被测设备 (DUT) 视为隔离客户端<em></em>(请参阅上文的<a href="#physical_environment">物理环境</a>部分),并可以连接到互联网:<strong>设置 &gt; WLAN</strong>
</li><li>确保设备上未设置锁定图案或密码:<strong>设置 &gt; 安全 &gt; 屏幕锁定 &gt; 无</strong>
</li><li>在设备上启用 <strong>USB 调试</strong>:<strong>设置 &gt; 开发者选项 &gt; USB 调试</strong>。
<p class="note"><strong>注意:</strong>在 Android 4.2 及更高版本中,默认情况下会隐藏<strong>开发者选项</strong>。要显示这些选项,请依次转到<strong>设置 &gt; 关于手机</strong>,然后点按<strong>版本号</strong>七次。返回上一屏幕以查找<strong>开发者选项</strong>。要查看其他详细信息,请参阅<a href="http://developer.android.com/studio/run/device.html#developer-device-options">启用设备上的开发者选项</a>。</p>
@@ -147,7 +147,7 @@ ro.product.first_api_level=21
</li><li>在设备上安装和配置帮助程序应用。
<p class="note"><strong>注意:</strong>对于 CTS 版本 2.1 R2 至 4.2 R4,请将您的设备(或模拟器)设置为通过以下命令执行无障碍测试:<br />
<code>adb install -r android-cts/repository/testcases/CtsDelegatingAccessibilityService.apk</code><br />在设备上,依次启用:<strong>设置 &gt; 无障碍 &gt; 无障碍 &gt; Delegating Accessibility</strong></p>
-<p class="note"><strong>注意:</strong>对于 7.0 之前的 CTS 版本,请在声明 <code>android.software.device_admin</code> 的设备上,将您的设备设置为使用以下命令执行设备管理测试:<br />
+<p class="note"><strong>注意</strong>:对于 7.0 之前的 CTS 版本,请在声明 <code>android.software.device_admin</code> 的设备上,将您的设备设置为使用以下命令执行设备管理测试:<br />
<code>adb install -r android-cts/repository/testcases/CtsDeviceAdmin.apk</code><br />
</p><p>依次选择“设置”&gt;“安全”&gt;“设备管理器”,然后启用两个 <code>android.deviceadmin.cts.CtsDeviceAdminReceiver*</code> 设备管理器。确保 <code>android.deviceadmin.cts.CtsDeviceAdminDeactivatedReceiver</code> 和任何其他预加载的设备管理器保持停用状态。
</p>
@@ -158,8 +158,7 @@ ro.product.first_api_level=21
</li><li>运行 <code>copy_media.sh</code>:<ul>
<li>要复制分辨率高达 720x480 的剪辑,请运行:<code>./copy_media.sh 720x480</code>
</li><li>如果您不确定最大分辨率,请尝试运行 <code>./copy_media.sh all</code>,以便复制所有文件。
- </li><li>如果 adb 下有多个设备,请将 -s(序列号)选项添加到末尾。
- 例如,要将高达 720x480 的分辨率复制到序列号为 1234567 的设备,请运行:<code>./copy_media.sh 720x480 -s 1234567</code>
+ </li><li>如果 adb 下有多个设备,请将 -s(序列号)选项添加到末尾。例如,要将高达 720x480 的分辨率复制到序列号为 1234567 的设备,请运行:<code>./copy_media.sh 720x480 -s 1234567</code>
</li></ul>
</li></ul>
</li></ol>
diff --git a/zh-cn/compatibility/cts/verifier.html b/zh-cn/compatibility/cts/verifier.html
index 81163af6..4d532fd3 100644
--- a/zh-cn/compatibility/cts/verifier.html
+++ b/zh-cn/compatibility/cts/verifier.html
@@ -28,27 +28,27 @@
<li>一台具有 USB 2.0 兼容端口的 Linux 计算机</li><li>具有已知可兼容蓝牙、WLAN 直连和 NFC 主机卡模拟 (HCE) 功能的第二台 Android 设备</li></ul>
<h3 id="setup">设置</h3>
<ul>
- <li>在 Linux 计算机上安装 <a href="http://developer.android.com/sdk/index.html">Android SDK</a></li><li>下载与被测 Android 版本对应的 <a href="downloads.html">CTS Verifier.apk</a>。</li><li>将 CTS Verifier.apk 安装到<em>被测设备</em> (DUT)。<br />
- <code>adb install -r -g CtsVerifier.apk</code>
+ <li>在 Linux 计算机上安装 <a href="http://developer.android.com/sdk/index.html">Android SDK</a></li><li>下载与被测 Android 版本对应的 <a href="downloads.html">CTS Verifier.apk</a>。</li><li>将 CTS Verifier.apk 安装到被测设备 (DUT)。<em></em>
+ <pre class="devsite-terminal devsite-click-to-copy">adb install -r -g CtsVerifier.apk</pre>
</li><li>确保设备的系统数据和时间均已正确设置。
</li></ul>
<h2 id="cts_test_procedure">CTS 验证程序测试程序</h2>
<ol>
- <li>在安装 CTS Verifier.apk 之后,启动 CTS 验证程序应用:<img src="images/cts-verifier-icon.png" alt="启动器中的 CTS 验证程序图标" id="figure1"/>
+ <li>在安装 CTS Verifier.apk 之后,启动 CTS 验证程序应用:<img src="/compatibility/cts/images/cts-verifier-icon.png" alt="启动器中的 CTS 验证程序图标" id="figure1"/>
<p class="img-caption">
<strong>图 1.</strong> CTS 验证程序图标</p>
- </li><li>打开应用后,CTS 验证程序将显示适用于手动验证的所有测试集的列表:<img src="images/cts-verifier-menu.png" alt="CTS 验证程序测试菜单" id="figure2"/>
+ </li><li>打开后,CTS 验证程序会显示适用于手动验证的所有测试集的列表:<img src="/compatibility/cts/images/cts-verifier-menu.png" alt="CTS 验证程序测试菜单" id="figure2"/>
<p class="img-caption">
<strong>图 2.</strong> CTS 验证程序测试菜单</p>
</li><li>每项测试均包含一组常用元素(在某些测试中,系统会自动确认测试结果为通过/失败):<ul>
- <li><em>信息</em> - 用于运行测试的一组说明。首次打开每个测试或每当按<strong>信息</strong>按钮 (?) 时,此信息都会以弹出窗口的形式显示。
- </li><li><em>通过</em> - 如果 DUT 符合“信息”中的说明规定的测试要求,请按<strong>通过</strong>按钮 (✓)。
- </li><li><em>失败</em> - 如果 DUT 不符合“信息”中的说明规定的测试要求,请按<strong>失败</strong>按钮 (!)。
+ <li><em></em>信息 - 用于运行测试的一组说明。首次打开每个测试或每当按<strong>信息</strong>按钮 (?) 时,此信息都会以弹出窗口的形式显示。
+ </li><li><em></em>通过 - 如果 DUT 符合“信息”中的说明规定的测试要求,请按<strong>通过</strong>按钮 (✓)。
+ </li><li><em></em>失败 - 如果 DUT 不符合“信息”中的说明规定的测试要求,请按<strong>失败</strong>按钮 (!)。
</li></ul>
-<img src="images/video-verifier.png" alt="流式视频品质验证程序" id="figure3"/>
+<img src="/compatibility/cts/images/video-verifier.png" alt="流式视频品质验证程序" id="figure3"/>
<p class="img-caption">
<strong>图 3.</strong> 视频品质验证程序</p>
@@ -60,16 +60,16 @@
<ol>
<li>将 DUT 连接到计算机。
</li><li>在计算机上执行 cts-usb-accessory 程序(存放在 CTS 验证程序包中)。
+ <pre class="devsite-terminal devsite-click-to-copy">./cts-usb-accessory</pre>
</li><li>DUT 上将显示一条弹出消息。选择 <strong>OK</strong> 进入 CTS 验证程序应用中的 USB 配件测试。
<br />
-<img src="images/screen-lock-test.png" alt="CTS 验证程序屏幕锁定测试" id="figure4"/>
+<img src="/compatibility/cts/images/screen-lock-test.png" alt="CTS 验证程序屏幕锁定测试" id="figure4"/>
<p class="img-caption">
<strong>图 4.</strong> 屏幕锁定测试</p>
</li><li>在计算机的控制台上,您将看到类似以下内容的输出内容。
</li></ol>
-<pre>
-out/host/linux-x86/cts-verifier/android-cts-verifier$ <strong>./cts-usb-accessory</strong>
+<pre class="devsite-click-to-copy">
CTS USB Accessory Tester
Found possible Android device (413c:2106) - attempting to switch to accessory
mode...
@@ -102,7 +102,7 @@ Found Android device in accessory mode (18d1:2d01)...
<p>这种视野校准程序主要用于快速确定具备适中精确度的设备视野。
</p><p><strong>设置</strong> - 打印 <a href="/compatibility/calibration-pattern.pdf">calibration-pattern.pdf</a> 目标文件,并将它贴在一个硬材质底板上。打印尺寸为 11“x 17” 或 A3。将相机设备和打印出来的图纸按如下位置和方向摆放:</p>
-<img src="images/camera-printed-target.png" alt="相机打印目标" id="figure5"/>
+<img src="/compatibility/cts/images/camera-printed-target.png" alt="相机打印目标" id="figure5"/>
<p class="img-caption">
<strong>图 5.</strong> 相机打印目标</p>
@@ -123,13 +123,13 @@ Found Android device in accessory mode (18d1:2d01)...
<ol>
<li>完成所有测试后,点按<strong>保存(磁盘)</strong>图标。
<br />
- <img src="images/verifier-save-icon.png" alt="CTS 验证程序保存图标" id="figure6"/>
+ <img src="/compatibility/cts/images/verifier-save-icon.png" alt="CTS 验证程序保存图标" id="figure6"/>
<p class="img-caption">
- <strong>图 6.</strong> CTS 验证程序保存图标。<em>注意:</em>Android 7.0 及更高版本中已移除预览功能:<img src="images/verifier-preview-icon.png" width="24" height="24"/>
+ <strong>图 6.</strong> CTS 验证程序保存图标。<em></em>注意:Android 7.0 及更高版本中已移除预览功能:<img src="/compatibility/cts/images/verifier-preview-icon.png" width="24" height="24"/>
</p>
</li>
<li>
- 所保存报告的路径将显示在弹出窗口中(例如 <code>/sdcard/verifierReports/ctsVerifierReport-date-time.zip</code>)。记录该路径。
+ 已保存报告的路径将显示在弹出窗口中(例如 <code>/sdcard/verifierReports/ctsVerifierReport-date-time.zip</code>)。记录该路径。
<br />
<img src="images/path-saved-report.png" alt="CTS 验证程序保存报告的路径" id="figure7"/>
<p class="img-caption">
@@ -142,8 +142,10 @@ Found Android device in accessory mode (18d1:2d01)...
从计算机的 SDK 安装中,运行 <code>adb pull CTSVerifierReportPath</code> 以从设备中下载报告。
<ul>
<li>
- 要下载所有报告,请运行:<code>adb pull /sdcard/verifierReports</code>
- <br />对于 Android 6.0 及更早版本,请运行:<code>adb pull /mnt/sdcard/ctsVerifierReports/</code>
+ 要下载所有报告,请运行:
+ <pre class="devsite-terminal devsite-click-to-copy">adb pull /sdcard/verifierReports</pre>
+ 对于 Android 6.0 及更早版本,请运行:
+ <pre class="devsite-terminal devsite-click-to-copy">adb pull /mnt/sdcard/ctsVerifierReports/</pre>
</li>
<li>
报告的名称会加上时间戳(基于 DUT 的系统时间)。
diff --git a/zh-cn/compatibility/index.html b/zh-cn/compatibility/index.html
index bc8abed7..f8f76872 100644
--- a/zh-cn/compatibility/index.html
+++ b/zh-cn/compatibility/index.html
@@ -20,7 +20,7 @@
limitations under the License.
-->
-<p>Android 的目的是创建一个开放平台,供开发者编译创新应用。</p>
+<p>Android 的目的是构建一个开放平台,供开发者打造创新应用。</p>
<ul>
<li>Android 兼容性计划定义了 Android 平台的技术细节,并为原始设备制造商 (OEM) 提供了各种工具,以确保开发者应用可以在各种设备上顺利运行。</li>
<li>Android SDK 为开发者提供了内置工具,方便他们清楚地说明其应用所需的设备功能。
@@ -36,24 +36,24 @@
<strong>图 1.</strong> 设备兼容性让 Android 生态系统得以蓬勃发展</p>
</div>
-<p>手机是一个高度个人化、永远在线、永远存在的互联网访问入口。我们还没有遇到过不希望通过扩展手机功能来自定义手机的用户。这就是为什么我们会将 Android 设计为用于运行售后市场应用的强大平台。</p>
+<p>手机是一个高度个人化、永远在线、永远在手边的互联网访问入口。我们还没有遇到过不希望通过扩展手机功能来自定义手机的用户。这就是为什么我们将 Android 设计为一个用于运行售后市场应用的强大平台。</p>
-<h3 id="developers-outnumber-us-all">开发者人数超过我们的总开发者人数</h3>
+<h3 id="developers-outnumber-us-all">开发者人数远超过我们的员工总数</h3>
<p>任何设备制造商都无法编写用户希望拥有的所有软件。我们需要第三方开发者来编写用户需要的应用,因此 Android 开放源代码项目 (AOSP) 的目的就是让应用开发流程尽量简单和开放。</p>
<h3 id="everyone-needs-a-common-ecosystem">所有人都需要一个共同的生态系统</h3>
-<p>开发者为解决某个错误而编写的每一行代码都是没有添加新功能的一行代码。移动设备的兼容性越高,可在这些设备上运行的应用就越多。通过打造完全兼容的 Android 设备,您可以享用针对 Android 编写的大量应用,同时还能增强促使开发者编译更多应用的动力。</p>
+<p>开发者为解决错误和问题而编写的每一行代码都是没有添加新功能的一行代码。移动设备的兼容性越高,可在这些设备上运行的应用就越多。通过打造完全兼容的 Android 设备,您不但可受益于为 Android 编写的大量应用,同时还能推动开发者构建更多应用。</p>
<h2 id="android-compatibility-is-free-and-its-easy">Android 兼容性计划是免费的,而且申请步骤很简单</h2>
<p>要打造与 Android 兼容的移动设备,请遵循以下三个步骤进行操作:</p>
<ol>
-<li><em>获取<a href="/source/index.html"> Android 软件源代码</a></em>。这是移植到您的硬件的 Android 平台源代码。</li>
-<li><em>符合 Android 兼容性定义文档 (CDD)</em>(<a href="/compatibility/android-cdd.pdf">PDF</a>、<a href="/compatibility/android-cdd.html">HTML</a>)的要求。CDD 列举了有关兼容的 Android 设备的软件和硬件要求。</li>
-<li><em>通过<a href="/compatibility/cts/">兼容性测试套件 (CTS)</a></em> 测试。在开发过程中随时借助 CTS 评估兼容性。</li> </ol>
+<li><em></em>获取 <a href="/source/index.html">Android 软件源代码</a>。这是要移植到您的硬件的 Android 平台源代码。</li>
+<li><em></em>遵循 Android 兼容性定义文档 (CDD)(<a href="/compatibility/android-cdd.pdf">PDF</a>、<a href="/compatibility/android-cdd.html">HTML</a>)的要求。CDD 列出了对兼容的 Android 设备的软件和硬件要求。</li>
+<li><em></em>通过<a href="/compatibility/cts/">兼容性测试套件 (CTS)</a> 测试。在开发过程中随时借助 CTS 评估兼容性。</li> </ol>
<p>在符合 CDD 要求且通过 CTS 测试后,您的设备即是与 Android 兼容的设备,这意味着生态系统中的 Android 应用在您的设备上运行时可提供一致的体验。有关 Android 兼容性计划的详细信息,请参阅<a href="overview.html">计划概述</a>。</p>
-<h2 id="licensing-gms">为 Google 移动服务 (GMS) 授予许可</h2>
-<p>打造 Android 兼容设备后,请考虑为在 Android 上运行的 Google 移动服务 (GMS)、Google 拥有的一系列应用(Google Play、YouTube、Google 地图、Gmail 等)授予许可。GMS 不是 Android 开放源代码项目的一部分,仅通过 Google 授予许可的方式提供。有关如何申请 GMS 许可的信息,请参阅<a href="contact-us.html">与我们联系</a>。</p>
+<h2 id="licensing-gms">申请 Google 移动服务 (GMS) 许可</h2>
+<p>打造 Android 兼容设备后,请考虑申请 Android 上的 Google 移动服务(简称 GMS,由 Google Play、YouTube、Google 地图、Gmail 等 Google 拥有的一系列应用组成)许可。GMS 不是 Android 开放源代码项目的一部分,仅通过 Google 授予许可的方式提供。有关如何申请 GMS 许可的信息,请查看<a href="contact-us.html">与我们联系</a>。</p>
</ul></body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/admin/enterprise-telephony.html b/zh-cn/devices/tech/admin/enterprise-telephony.html
new file mode 100644
index 00000000..17119ab5
--- /dev/null
+++ b/zh-cn/devices/tech/admin/enterprise-telephony.html
@@ -0,0 +1,85 @@
+<html devsite><head>
+ <title>实现企业电话服务</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>
+本文档介绍了为支持企业使用情形而在版本 7.0 中对 Android 框架的电话相关部分进行的更改。本文档的适用对象为制造商,主要介绍与框架相关的电话方面的更改。此外,本文概述了原始设备制造商 (OEM) 需要对负责处理电话相关功能的预加载应用执行哪些更改。
+</p>
+
+<p>
+Android 7.0 增加了一些用于支持企业电话使用情形的新功能,具体包括:</p>
+
+<ul>
+<li>跨资料联系人搜索功能 - 允许应用在个人资料中搜索由受管理资料联系人提供程序提供的联系人,联系人信息可存储在任何数据存储服务中,例如存储在设备本机或企业目录内</li><li>跨资料联系人标记 - 将工作联系人与个人联系人明确区分开来</li><li>使连接服务可感知受管理资料 - 受管理资料中的应用可藉此提供各种电话功能,例如提供单独的工作拨号器和工作连接服务</li>
+</ul>
+
+<h2 id="examples-and-source">示例和源代码</h2>
+
+<p>
+Android 开放源代码项目 (AOSP) 在拨号器、通讯录和短信应用的实现中集成了跨资料联系人搜索和标记功能。
+</p>
+
+<p>
+示例:
+</p><ul>
+<li><strong>为工作联系人添加标记</strong>:请参阅 <code>packages/apps/ContactsCommon</code> f3eb5a207bfe0ff3b4ed2350ae5865ed8bc59798<em></em>
+</li><li><strong>跨资料搜索</strong>:请参阅 <code>packages/apps/ContactsCommon</code> cd0b29ddbf3648e48f048196c62245d545bc6122<em></em></li>
+</ul>
+
+<h2 id="implementation">实现</h2>
+
+<p>
+设备实现人员必须在拨号器、通讯录和短信/彩信应用中实现联系人的跨资料使用、搜索、查询和标记功能。</p>
+
+<h3 id="cross-profile-contact-search">跨资料联系人搜索</h3>
+
+<p>
+跨资料联系人搜索应该使用 Enterprise Contacts API(<code>ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI</code> 等)实现。请参阅 <a href="http://developer.android.com/preview/features/afw.html#contacts">http://developer.android.com/preview/features/afw.html#contacts</a>
+</p>
+
+<h3 id="work-profile-contact-badging">工作资料联系人标记</h3>
+
+<p>
+工作资料联系人标记可通过检查 <code>ContactsContract.Directory.isEntepriseDirectoryId() </code>(如果可用)或 <a href="http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#isEnterpriseContactId(long)">http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#isEnterpriseContactId(long)</a><code> </code>实现
+</p>
+
+<h3 id="managed-profile-aware-connectionservice">可感知受管理资料的连接服务</h3>
+
+<p>
+制造商无需修改框架代码来支持该功能,但应该清楚它对电信服务和其他电话功能的影响。
+</p>
+
+<h2 id="validation">验证</h2>
+
+<p>
+跨资料联系人搜索和标记功能可通过以下方式验证:</p>
+
+<ol>
+<li>使用 <a href="https://github.com/googlesamples/android-testdpc">TestDPC</a> 在测试设备上设置受管理资料。</li><li>启用跨资料联系人搜索。
+</li><li>在受管理资料中添加本机工作联系人。
+</li><li>在系统拨号器、通讯录和短信/彩信应用的个人资料中搜索该联系人,确认该联系人可以找到并已正确标记。</li>
+</ol>
+
+<p>
+已增加的 CTS 测试可确保基本的跨资料联系人搜索 API 已在以下位置实现:<code>com/android/cts/managedprofile/ContactsTest.java</code>。
+</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/admin/managed-profiles.html b/zh-cn/devices/tech/admin/managed-profiles.html
new file mode 100644
index 00000000..053af9b3
--- /dev/null
+++ b/zh-cn/devices/tech/admin/managed-profiles.html
@@ -0,0 +1,114 @@
+<html devsite><head>
+ <title>使用受管理资料</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 <a href="multi-user.html">用户</a>。<em></em><em></em></p>
+
+<p>受管理资料的主要目的是为受管理的数据(如企业数据)创建一个隔离且安全的存储空间。资料管理员可以全权控制数据的范围、入口、出口及其有效期。这些政策可以赋予极高的权限,因此需由受管理资料(而非设备管理员)负责执行。</p>
+
+<ul>
+ <li><strong>创建</strong>:受管理资料可由主用户中的任何应用创建。用户在创建之前会收到受管理资料行为和政策执行的通知。</li>
+ <li><strong>管理</strong>:受管理资料由以编程方式调用 <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html">DevicePolicyManager</a> 类中的 API 的应用管理,并且受管理资料的使用受到限制。这类应用称为“资料所有者”,在初始资料设置时定义。<em></em>受管理资料独有的政策涉及应用限制、可更新性和 intent 行为。
+ </li>
+ <li><strong>外观处理</strong>:受管理资料中的应用、通知和微件总是带有标记,并且通常内嵌在主用户的界面元素中。</li>
+</ul>
+
+<h2 id="data_segregation">数据隔离</h2>
+<p>受管理资料使用以下数据隔离规则。</p>
+
+<h3 id="applications">应用</h3>
+
+<p>当同一应用同时存在于主用户和受管理资料中时,应用使用自己的隔离数据限定范围。通常,应用彼此独立地进行操作,并且彼此之间不能跨越资料-用户边界直接通信。</p>
+
+<h3 id="accounts">帐号</h3>
+
+<p>受管理资料中的帐号与主用户截然不同。这些帐号无法跨越资料-用户边界访问凭据。只有在各自环境中的应用才能访问其各自的帐号。</p>
+
+<h3 id="intents">Intent</h3>
+
+<p>管理员可以控制是否在/不在受管理资料中解析 Intent。在默认情况下,受管理资料中的应用的范围被限定到受管理资料内,但 Device Policy API 除外。</p>
+
+<h3 id="settings">设置</h3>
+
+<p>在通常情况下,设置的执行范围限定到受管理资料,但锁定屏幕和加密设置除外,它们的范围依然是整个设备且会在主用户和受管理资料之间共享。在其他情况下,资料所有者在受管理资料之外没有任何设备管理员权限。</p>
+
+<p>受管理资料按以下原则被实现为一种新的次要用户:</p>
+
+<pre>uid = 100000 * userid + appid</pre>
+
+<p>与常规用户一样,它们具有独立的应用数据:</p>
+
+<pre>/data/user/&lt;userid&gt;</pre>
+
+<p>系统会使用 <code>Binder.getCallingUid()</code> 为所有系统请求计算 UserId,并且所有系统状态和响应都由 UserId 分隔。您可以考虑使用 <code>Binder.getCallingUserHandle</code>(而非 <code>getCallingUid</code>),以避免在 Uid 与 UserId 之间引起混淆。</p>
+
+<p>AccountManagerService 为每个用户保留了一个单独的帐号列表。受管理资料与常规次要用户之间的主要区别如下:</p>
+
+<ul>
+ <li>受管理资料与其父用户相关联,并在启动时与主用户一起启动。</li>
+ <li>受管理资料的通知由 ActivityManagerService 启用,从而允许受管理资料与主用户共享活动堆栈。</li>
+ <li>其他共享系统服务包括 IME、A11Y 服务、WLAN 和 NFC。</li>
+ <li>借助新的 Launcher API,启动器可以在主要资料中的应用旁显示受管理资料中带有标记的应用和加入白名单的微件,而无需切换用户。</li>
+</ul>
+
+<h2 id="device_administration">设备管理</h2>
+
+<p>Android 设备管理包括以下类型的企业设备管理员:</p>
+
+<ul>
+ <li>资料所有者:<em></em>专为自带设备 (BYOD) 环境而设计</li>
+ <li>设备所有者:<em></em>专为由企业负责的环境而设计</li>
+</ul>
+
+<p>为 Android 5.0 添加的大多数新设备管理员 API 仅适用于资料或设备所有者。传统的设备管理员仍然保留,但适用于更简单的仅限消费者情况(例如,查找我的设备)。</p>
+
+<h3 id="profile_owners">资料所有者</h3>
+
+<p>Device Policy Client (DPC) 应用通常用作资料所有者。DPC 应用通常由企业移动管理 (EMM) 合作伙伴(如 Google Apps Device Policy)提供。</p>
+
+<p>资料所有者应用通过发送 <code>ACTION_PROVISION_MANAGED_PROFILE</code> intent 在设备上创建受管理资料。此类资料因具有应用标记以及个性化外观而有别于其他资料。该标记或 Android 设备管理图标标识了哪些应用是工作应用。</p>
+
+<p>EMM 仅对受管理资料(而非个人空间)进行控制,但有一些例外情况,例如执行锁定屏幕。</p>
+
+<h3 id="device_owners">设备所有者</h3>
+
+<p>只能在未配置的设备中设置设备所有者:</p>
+
+<ul>
+ <li>只能在初始设备设置时进行配置</li>
+ <li>强制披露始终以快捷设置显示</li>
+</ul>
+
+<p>设备所有者可以执行一些资料所有者无法执行的任务,如:</p>
+
+<ul>
+ <li>擦除设备数据</li>
+ <li>停用 WLAN/蓝牙</li>
+ <li>控制 <code>setGlobalSetting</code></li>
+ <li><code>setLockTaskPackages</code>(能够将可将自己固定到前台的软件包加入白名单)</li>
+ <li>设置 <code>DISALLOW_MOUNT_PHYSICAL_MEDIA</code>(默认为 <code>FALSE</code>)。如果为 <code>TRUE</code>,则便携式和可合并的物理媒体都无法装载。</li>
+</ul>
+
+<h3 id="dpm_api">DevicePolicyManager API</h3>
+
+<p>Android 5.0 及更高版本大幅改进了 DevicePolicyManager,其中包含数十个新的 API,可同时支持企业所有和自带设备 (BYOD) 的管理用例。示例包括应用限制、证书静默安装和跨资料共享 intent 访问控制。可以从示例 Device Policy Client (DPC) 应用 <a href="https://developer.android.com/samples/BasicManagedProfile/index.html">BasicManagedProfile.apk</a> 着手使用。有关详情,请参阅<a href="https://developer.android.com/training/enterprise/work-policy-ctrl.html">构建工作政策控制器</a>。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/admin/multi-user.html b/zh-cn/devices/tech/admin/multi-user.html
new file mode 100644
index 00000000..18f77e41
--- /dev/null
+++ b/zh-cn/devices/tech/admin/multi-user.html
@@ -0,0 +1,111 @@
+<html devsite><head>
+ <title>支持多用户</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 支持在一台 Android 设备上添加多名用户。例如,父母可能会允许他们的孩子使用家用平板电脑,或应急响应团队可能会共用一台移动设备用于呼叫值班。</p>
+
+<h2 id="definitions">术语</h2>
+<p>Android 在描述 Android 用户和帐号时会使用以下术语。</p>
+
+<h3 id="general_defs">通用</h3>
+<p>Android 设备管理会使用以下通用术语。</p>
+
+<ul>
+ <li>用户:<em></em>每个用户分别由一个自然人使用。每个用户都有不同的应用数据和一些独特的设置,以及可在多个用户之间明确切换的用户界面。当某个用户处于活动状态时,另一个用户可以在后台运行;系统会在适当的时候尝试关闭用户来节约资源。次要用户可直接通过主要用户界面或<a href="https://developer.android.com/guide/topics/admin/device-admin.html">设备管理</a>应用进行创建。</li>
+ <li>帐号:<em></em>帐号包含在用户中,但并非由某个用户定义;用户既不由任何特定帐号进行定义,也不会关联到任何特定帐号。用户和个人资料包含其各自的唯一帐号;不过,即使没有用户和个人资料,帐号也可以正常发挥作用。帐号列表因用户而异。有关详细信息,请参阅 <a href="https://developer.android.com/reference/android/accounts/Account.html">Account 类</a>定义。</li>
+ <li>个人资料:<em></em>个人资料具有独立的应用数据,但会共享一些系统范围内的设置(例如 WLAN 和蓝牙)。个人资料会与已存在用户绑定在一起,并是已存在用户的子集。一个用户可以有多份个人资料。个人资料通过<a href="https://developer.android.com/guide/topics/admin/device-admin.html">设备管理</a>应用进行创建。个人资料由创建个人资料的用户进行定义,它与父用户之间总是存在不可变的关联。个人资料的存在时间不会超出相应创建用户的生命周期。</li>
+ <li>应用:应用的数据存在于各关联用户中。<em></em>同一用户的其他应用的应用数据均已沙盒化。同一用户的应用可以通过 IPC 相互影响。如需了解详情,请参阅<a href="https://developer.android.com/training/enterprise/index.html">编译 Apps for Work</a>。</li>
+</ul>
+
+<h3 id="user_types">用户类型</h3>
+<p>Android 设备管理使用以下用户类型。</p>
+
+<ul>
+ <li>主要用户。<em></em>添加到设备的第一个用户。除非恢复出厂设置,否则无法移除主要用户;此外,即使其他用户在前台运行,主要用户也会始终处于运行状态。该用户还拥有只有自己可以设置的特殊权限和设置。</li>
+ <li>次要用户。<em></em>除主要用户之外添加到设备的任何用户。次要用户可以移除(由用户自行移除或由主要用户移除),且不会影响设备上的其他用户。这种用户可以在后台运行且可以继续连接到网络。</li>
+ <li>访客:临时的次要用户。<em></em>访客用户设置中有明确的删除选项,以便在访客用户帐号过期时快速将其删除。一次只能创建一个访客用户。</li>
+</ul>
+
+<h3 id="profile_types">个人资料类型</h3>
+<p>Android 设备管理使用以下个人资料类型。</p>
+
+<ul>
+ <li>受管理。<em></em>由应用创建,包含工作数据和应用。受管理个人资料专门由个人资料所有者(创建企业资料的应用)管理。启动器、通知和最近的任务均由主要用户和企业资料共享。</li>
+ <li>受限。<em></em>由主要用户(控制受限个人资料上哪些应用可用)控制的帐号。仅适用于平板电脑和电视设备。</li>
+</ul>
+
+<h2 id="applying_the_overlay">支持多用户</h2>
+
+<p>从 Android 5.0 开始,多用户功能默认处于停用状态。要启用这项功能,设备制造商必须定义资源叠加层,以取代 <code>frameworks/base/core/res/res/values/config.xml</code> 中的以下值:</p>
+
+<pre>&lt;!-- Maximum number of supported users --&gt;
+&lt;integer name="config_multiuserMaximumUsers"&gt;1&lt;/integer&gt;
+&lt;!-- Whether Multiuser UI should be shown --&gt;
+&lt;bool name="config_enableMultiUserUI"&gt;false&lt;/bool&gt;
+</pre>
+
+<p>要应用此叠加层并在设备上启用访客和次要用户,请使用 Android 编译系统的 <code>DEVICE_PACKAGE_OVERLAYS</code> 功能执行以下操作:</p>
+
+<ul>
+ <li>将 <code>config_multiuserMaximumUsers</code> 的值替换为大于 1 的数</li>
+ <li>将 <code>config_enableMultiUserUI</code> 的值替换为 <code>true</code></li>
+</ul>
+
+<p>设备制造商可以决定用户数上限。如果设备制造商或其他人修改了设置,他们必须确保短信和电话通讯遵循 <a href="/compatibility/android-cdd.pdf">Android 兼容性定义文档</a> (CDD) 中定义的说明。</p>
+
+<h2 id="managing_users">管理多个用户</h2>
+
+<p>用户和个人资料(受限个人资料除外)由以编程方式在 <code>DevicePolicyManager</code> 类中调用 API 的应用进行管理以限制使用。</p>
+
+<p>学校和企业可以将上述类型与 <a href="http://developer.android.com/reference/android/os/UserManager.html">UserManager API</a> 结合使用,以针对其使用情况构建独特的解决方案,从而借助用户和个人资料来管理设备上应用和数据的生命周期和适用范围。</p>
+
+<h2 id="effects">多用户系统行为</h2>
+
+<p>将用户添加到设备后,当其他用户在前台活动时,一些功能会受限制。由于应用数据会按用户分开,因此,这些应用的状态也会因用户而异。例如,在设备上激活某个用户和帐号之前,发往该用户帐号(当前处于未激活状态)的电子邮件将无法查看。</p>
+
+<p>默认情况下,只有主要用户拥有电话和短信的完全访问权限。次要用户可以接听呼入电话,但是不能发送或接收短信。主要用户必须为其他人启用这些功能,他们才能使用这些功能。</p>
+
+<p class="note"><strong>注意</strong>:要为次要用户启用或停用电话和短信功能,请依次转到“设置”&gt;“用户”,选择相应用户,然后将“允许接打电话和收发短信”设置切换到关闭状态。<em></em><em></em></p>
+
+<p>次要用户在后台活动时会受到一些限制。例如,后台次要用户无法显示界面或开启蓝牙服务。此外,如果设备需要更多内存才能满足前台用户的操作需求,系统进程将暂停后台次要用户的活动。</p>
+
+<p>在 Android 设备上使用多用户功能时,请注意以下几点:</p>
+
+<ul>
+ <li>通知会同时出现在一位用户的所有帐号中。</li>
+ <li>其他用户的通知在激活用户后才会显示。</li>
+ <li>每位用户都会获得用于安装和放置应用的工作区。</li>
+ <li>任何用户都无权访问其他用户的应用数据。</li>
+ <li>任何用户都可以影响为所有用户安装的应用。</li>
+ <li>主要用户可以移除次要用户所创建的应用甚至整个工作区。</li>
+</ul>
+
+<p>Android 7.0 具备一些增强功能,例如:</p>
+
+<ul>
+ <li>切换工作资料。<em></em>用户可以停用其受管理的个人资料(例如不使用时)。这项功能可以通过停止用户来实现;UserManagerService 会调用 <code>ActivityManagerNative#stopUser()</code>。
+ </li>
+ <li>始终开启的 VPN。VPN 应用现已可以由用户、设备 DPC 或 Managed Profile DPC(仅适用于受管理个人资料应用)设置为始终开启。<em></em>启用后,应用将无法访问公共网络(在连接 VPN 且连接可以通过它正常进行路由前,无法访问网络资源)。报告 <code>device_admin</code> 的设备必须实现始终开启的 VPN。</li>
+</ul>
+
+<p>有关 Android 7.0 设备管理功能的更多详细信息,请参阅 <a href="https://developer.android.com/about/versions/nougat/android-7.0.html#android_for_work">Android for Work</a>。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/admin/provision.html b/zh-cn/devices/tech/admin/provision.html
new file mode 100644
index 00000000..a77e73d9
--- /dev/null
+++ b/zh-cn/devices/tech/admin/provision.html
@@ -0,0 +1,122 @@
+<html devsite><head>
+ <title>配置设备管理</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>本页面介绍了使用 NFC 或通过云服务向企业用户部署设备的过程(要查看完整的要求列表,请参阅<a href="/devices/tech/admin/implement.html">实现设备管理</a>)。</p>
+
+<p>首先,请下载 <a href="https://github.com/googlesamples/android-NfcProvisioning">NfcProvisioning APK</a> 和 <a href="https://github.com/googlesamples/android-DeviceOwner">Android-DeviceOwner APK</a>。</p>
+
+<p class="caution"><strong>注意</strong>:如果配置已经开始,则必须先将受影响的设备恢复出厂设置。</p>
+
+<h2 id="managed_provisioning">托管配置</h2>
+
+<p>托管配置是一个框架式界面流程,用于确保用户充分了解设置设备所有者或受管理资料的含义。它旨在充当受管理资料的设置向导。</p>
+
+<p class="note"><strong>注意</strong>:只能为未配置的设备设置设备所有者。如果 <code>Settings.Secure.USER_SETUP_COMPLETE</code> 已设置,则设备被视为已配置,不能再设置设备所有者。</p>
+
+<p>如果启用设备的默认加密功能,则设备的管理配置流程会相当简单和快速。受管理配置组件会:</p>
+
+<ul>
+ <li>加密设备</li>
+ <li>创建受管理资料</li>
+ <li>停用不需要的应用</li>
+ <li>将企业移动管理 (EMM) 应用设置为资料所有者</li>
+</ul>
+
+<p>反过来,EMM 应用会:</p>
+
+<ul>
+ <li>添加用户帐号</li>
+ <li>落实设备合规性</li>
+ <li>启用任何其他系统应用</li>
+</ul>
+
+<p>在此流程中,托管配置会触发设备加密。在托管配置过程中,框架会将 EMM 应用复制到受管理资料中。受管理资料中的 EMM 应用实例在配置完成时从框架获取回调。接着,EMM 可以添加帐号并执行政策;然后调用 <code>setProfileEnabled()</code>,这样一来,启动器图标就变为可见。</p>
+
+<h2 id="profile_owner_provisioning">资料所有者配置</h2>
+
+<p>资料所有者配置假定设备的用户(而不是公司 IT 部门)监督设备管理。要启用资料所有者配置,您必须发送包含相应附加内容的 intent。例如,使用 TestDPC 应用(<a href="https://play.google.com/store/apps/details?id=com.afwsamples.testdpc&hl=zh-cn">从 Google Play 下载</a>或<a href="https://github.com/googlesamples/android-testdpc/">从 GitHub 构建</a>)。在设备上安装 TestDPC,从启动器启动该应用,然后按照应用说明进行操作。启动器抽屉式导航栏中出现带有标记的图标时,则表示配置完成。</p>
+
+<p>移动设备管理 (MDM) 应用通过发送包含操作的 intent 来触发受管理资料的创建:<a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/admin/DevicePolicyManager.java">DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE</a>。以下是触发受管理资料创建并将 DeviceAdminSample 设为资料所有者的示例 intent:</p>
+
+<pre>adb shell am start -a android.app.action.PROVISION_MANAGED_PROFILE \
+ -c android.intent.category.DEFAULT \
+ -e wifiSsid $(printf '%q' \"WifiSSID\") \
+ -e deviceAdminPackage "com.google.android.deviceadminsample" \
+ -e android.app.extra.deviceAdminPackageName $(printf '%q'
+ .DeviceAdminSample\$DeviceAdminSampleReceiver) \
+ -e android.app.extra.DEFAULT_MANAGED_PROFILE_NAME "My Organisation"
+</pre>
+
+<h2 id="device_owner_provisioning_via_nfc">设备所有者配置</h2>
+<p>使用以下方法之一来设置设备所有者 (DO) 配置。</p>
+
+<h3 id="do_provision_nfc">通过 NFC 进行配置</h3>
+<p>通过 NFC 进行 DO 配置与资料所有者的配置方法类似,但前者需要更多的引导。要使用此方法,请在初始设置步骤(即设置向导的第一页)<a href="http://developer.android.com/guide/topics/connectivity/nfc/nfc.html">NFC 触碰</a>设备。此低接触流程会配置 WLAN、安装 DPC,并将 DPC 设置为设备所有者。</p>
+
+<p>典型的 NFC 包包括以下内容:</p>
+
+<pre>
+ EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
+ EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LOCATION
+ EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
+ EXTRA_PROVISIONING_WIFI_SSID
+ EXTRA_PROVISIONING_WIFI_SECURITY_TYPE
+</pre>
+
+<p>设备必须将 NFC 配置为接受来自设置体验的托管配置 Mimetype:</p>
+
+<pre>/packages/apps/Nfc/res/values/provisioning.xml
+
+ &lt;bool name="enable_nfc_provisioning"&gt;true&lt;/bool&gt;
+ &lt;item&gt;application/com.android.managedprovisioning&lt;/item&gt;
+</pre>
+
+<h3 id="do_provision_cs">通过云服务进行配置</h3>
+<p>另一种方法是通过云服务进行设备所有者配置,其中设备可在开机设置时以设备所有者模式进行配置。设备可以收集凭据(或令牌),并使用它们来执行对云服务的查询,然后可以使用该服务来启动设备所有者的配置过程。</p>
+
+<h2 id="emm_benefits">EMM 的优势</h2>
+
+<p>企业移动管理 (EMM) 应用可以通过执行以下任务来提供帮助:</p>
+
+<ul>
+ <li>配置受管理资料</li>
+ <li>应用安全政策<ul>
+ <li>设置密码复杂度</li>
+ <li>锁定:停用屏幕截图,禁止从受管理资料中进行分享等。</li>
+ </ul></li>
+ <li>配置企业的网络连接<ul>
+ <li>使用 WifiEnterpriseConfig 配置企业 WLAN</li>
+ <li>配置设备 VPN</li>
+ <li>使用 <code>DPM.setApplicationRestrictions()</code> 配置企业 VPN</li>
+ </ul></li>
+ <li>启用企业应用单点登录 (SSO)<ul>
+ <li>安装所需的企业应用</li><li>使用 <code>DPM.installKeyPair()</code> 静默安装企业客户端证书</li>
+ <li>使用 <code>DPM.setApplicationRestrictions()</code> 配置企业应用的主机名、证书别名</li>
+ </ul></li>
+</ul>
+
+<p>托管配置只是 EMM 端到端工作流程的一部分,最终目标是让受管理资料中的应用能够访问企业数据。要获取测试指导,请参阅<a href="/devices/tech/admin/testing-setup.html">设置设备测试</a>。</p>
+
+<h2 id="automate">自动配置测试</h2>
+<p>要自动化企业配置测试过程,请使用 Android for Work (AfW) 自动化测试框架。如需了解详情,请参阅<a href="/devices/tech/admin/testing-provision.html">测试设备配置</a>。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/admin/testing-setup.html b/zh-cn/devices/tech/admin/testing-setup.html
new file mode 100644
index 00000000..85658540
--- /dev/null
+++ b/zh-cn/devices/tech/admin/testing-setup.html
@@ -0,0 +1,75 @@
+<html devsite><head>
+ <title>测试设备管理</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>为确保为受管理个人资料提供最基本的支持,原始设备制造商 (OEM) 设备必须包含以下基本元素:</p>
+
+<ul>
+ <li>个人资料所有者(如<a href="https://developer.android.com/training/enterprise/app-compatibility.html">确保与受管理个人资料的兼容性</a>中所述)</li>
+ <li>设备所有者</li>
+ </ul>
+
+<p>要查看完整的要求列表,请参阅<a href="/devices/tech/admin/implement.html">实现设备管理</a>。</p>
+
+<p>要测试设备管理功能,设备所有者可以使用 TestDPC 应用(如下所述),也可以考虑直接与其他企业移动管理 (EMM) 提供商合作。</p>
+
+<h2 id="set_up_the_device_owner_for_testing">设置设备所有者以进行测试</h2>
+<p>请按照以下说明设置设备所有者测试环境。</p>
+
+<ol>
+ <li>设置设备:<ol>
+ <li style="list-style-type: lower-alpha">将目标设备恢复出厂设置。</li>
+ <li style="list-style-type: lower-alpha">确保您未向设备添加任何用户帐号(例如,用于登录在线服务的用户帐号)。您可以依次转到“设置”-&gt;“帐号”进行确认。<em></em></li>
+ </ol></li>
+ <li>使用以下某种方法设置测试应用:<ul>
+ <li><a href="https://play.google.com/store/apps/details?id=com.afwsamples.testdpc&hl=zh-cn">下载 TestDPC 应用</a>(可从 Google Play 下载)。</li>
+ <li><a href="https://github.com/googlesamples/android-testdpc/">编译 TestDPC 应用</a>(可从 github.com 编译)。</li>
+ </ul>
+ </li>
+ <li>使用以下命令将 TestDPC 应用设置为设备所有者:<br />
+ <pre>$ adb shell dpm set-device-owner "com.afwsamples.testdpc/.DeviceAdminReceiver"</pre>
+ </li>
+ <li>在设备上完成设备所有者设置(加密、选择 WLAN 等)</li>
+</ol>
+
+<h2 id="verify_the_device_owner_was_correctly_setup">验证设备所有者设置</h2>
+<p>要验证设备所有者是否已正确设置,请依次转到“设置”&gt;“安全”&gt;“设备管理器”,并确认 TestDPC 是否已在列表中。<em></em>验证它无法被停用(这表明它就是设备所有者)。</p>
+
+<h2 id="automate">自动配置测试</h2>
+<p>要自动化企业配置进程的测试,请使用 Android for Work (AfW) 自动化测试框架。如需了解详情,请参阅<a href="/devices/tech/admin/testing-provision.html">测试设备配置</a>。</p>
+
+<h2 id="troubleshooting">错误报告和日志</h2>
+<p>在 Android 7.0 中,设备所有者 Device Policy Client (DPC) 可以获取受管理设备上企业进程的错误报告并查看日志。</p>
+
+<p>要触发错误报告(即由 <code>adb
+bugreport</code> 收集的包含 dumpsys、dumpstate 和 logcat 数据的对应数据),请使用 <code>DevicePolicyController.requestBugReport</code>。收集错误报告后,系统会提示用户同意发送错误报告数据。结果将由 <code>DeviceAdminReceiver.onBugreport[Failed|Shared|SharingDeclined]</code> 接收。要详细了解错误报告内容,请参阅<a href="/source/read-bug-reports.html">读取错误报告</a>。
+
+</p><p>此外,设备所有者 DPC 还可以收集与用户在受管理设备上执行的操作相关的日志。所有报告 device_admin 的设备均必须进行企业进程日志记录,且通过新的日志安全缓冲区(仅供系统服务器读取)进行启用(也就是说,<code>adb logcat -b security</code> 无法读取该缓冲区)。ActivityManager 服务和 Keyguard 组件会将以下事件记录到安全缓冲区:</p>
+
+<ul>
+<li>应用进程启动</li>
+<li>锁屏操作(例如,解锁失败和成功)</li>
+<li>针对设备执行 <code>adb</code> 命令</li>
+</ul>
+
+<p>要在重新启动(而非冷启动)后有选择地保留日志,并将这些日志提供给设备所有者 DPC,设备的内核必须启用 <code>pstore</code> 和 <code>pmsg</code>、支持 DRAM,并能在重新启动的所有阶段刷新,以免损坏内存中保留的日志。要启用支持,请在 <code>frameworks/base/core/res/res/values/config.xml</code> 中使用 <code>config_supportPreRebootSecurityLogs</code> 设置。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/connect_tests.html b/zh-cn/devices/tech/config/connect_tests.html
new file mode 100644
index 00000000..d6c89fb0
--- /dev/null
+++ b/zh-cn/devices/tech/config/connect_tests.html
@@ -0,0 +1,66 @@
+<html devsite><head>
+ <title>网络连接测试</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 Connectivity Testing Suite (ACTS) 测试填补了 Android 框架 API 和芯片组认证之间的测试空白。这些测试可验证 Android 框架所用的蓝牙、WLAN 和移动网络各方面的功能。</p>
+
+<h2 id="users">哪些人应该运行 ACTS 测试?</h2>
+
+<p>应该由负责 Android 堆栈的连接(蓝牙、WLAN 和移动网络)部分的开发者和集成人员运行 ACTS 测试。如果您要添加新功能、集成芯片组或驱动程序变更,这些测试可帮助您确保所做的更改功能和稳定性正常且符合基本的性能标准。</p>
+
+<p>这些测试为可选测试,任何 Android 设备认证都不强制要求完成这些测试。</p>
+
+<h2 id="how">如何运行 ACTS</h2>
+
+<p>ACTS 测试利用特权 Android API 解锁原本不可用的更深层次的测试。因此,只能使用 ACTS 来测试工程和 userdebug 版本。</p>
+
+<p>ACTS 测试旨在以最少且通常是现成的硬件运行,不过,测试也需要一些设备(因测试类型而异)。对于很多测试,两台 Android 设备或一台设备以及一个 WLAN 接入点就足够了。请参阅针对其中一个主要测试方面(蓝牙、WLAN 或移动网络)的文档,以确定具体的设置要求。</p>
+
+<h2 id="test-types">测试类型</h2>
+
+<h3 id="script-android">Android 脚本层</h3>
+
+<p><code><a href="https://android.googlesource.com/platform/external/sl4a/"><platform>/external/sl4a</platform></a></code> 中的 <a href="https://android.googlesource.com/platform/external/sl4a/+/master/README.md">Android 脚本层</a>是来自同名开放源代码项目的一个分支。该工具提供精简型 RPC 服务器来公开 Android 的 Java API。它允许测试脱机驻留,支持设备的协同自动化,从而实现更丰富的动态测试。在过去的 18 个月中,Google 已经调整、更新、扩展并使用该项目来远程运用 Android 的 Java API 测试无线连接。</p>
+
+<h3 id="script-native">原生脚本层</h3>
+
+<p><code><a href="https://android.googlesource.com/platform/packages/apps/Test/connectivity/"><platform>/packages/apps/Test/connectivity</platform></a></code> 中的<a href="https://android.googlesource.com/platform/packages/apps/Test/connectivity/+/master/sl4n/README.md">原生脚本层</a>是全新的内部发展型 RPC 服务器,用于以 Android 脚本层公开 Java API 的方式公开 Android 的原生 API。该工具目前用于测试 Brillo,我们预计该项目将迅速扩展,以满足越来越重要的原生无线 API 的测试需求。</p>
+
+<h3 id="script-android">Android 通讯测试套件</h3>
+
+<p><code><a href="https://android.googlesource.com/platform/tools/test/connectivity/"><platform>/tools/test/connectivity</platform></a></code> 中的 <a href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts/README.md">Android 通讯测试套件</a>为基于 Python 的轻量级自动化工具集,用于针对当前和即将推出的 Android 设备执行自动化测试。它提供了简洁的执行界面、一组用于访问衰减器等设备和 Android 设备的可插拔库,以及一些可进一步简化测试开发的实用函数。我们认为它是一种非常适合无线堆栈开发者或集成人员的桌面工具,无论他们是创建新的代码路径、执行基本的完整性测试,还是运行扩展的回归测试套件都没问题。</p>
+
+<p>本测试套件还包括一系列测试,很多测试在一台或两台具有 WLAN、移动网络或蓝牙连接的 Android 设备上即可运行,其中包括:</p>
+
+<ul>
+<li>针对 AP IOT、企业连接、WifiScanner、Autojoin 和 RTT 的 WLAN 测试。</li><li>针对 BLE、GATT、SPP 和 Bonding 的蓝牙测试。
+</li><li>针对 CS 和 IMS 呼叫、数据网络连接、短信、网络切换和热点的移动网络测试。</li>
+</ul>
+
+<p>我们相信,通过降低基本测试的门槛,并作为整个社区基于改进的系统测试进行协作的聚合点,这些工具的发布将帮助开发者、集成人员和测试人员等。</p>
+
+<h2 id="failures-contributors">失败和贡献</h2>
+
+<p>ACTS 测试并非认证套件,严格意义上来说,发布 Android 设备无需通过这些测试,但是,测试失败可能说明用户体验不佳。也就是说,如果测试失败,也无需感到失望。一些测试有意让您很难通过。其目的是帮助开发者推出高性能设备。</p>
+
+<p>ACTS 是一项相对较新的举措,并且来自开发社区的参与至关重要。如需添加测试、报告问题或提出问题,请在 <a href="https://code.google.com/p/android/issues/entry">Android 问题跟踪器</a>上使用连接性测试模板新开一个错误,以发起相关交流。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/index.html b/zh-cn/devices/tech/config/index.html
new file mode 100644
index 00000000..7d523ec6
--- /dev/null
+++ b/zh-cn/devices/tech/config/index.html
@@ -0,0 +1,25 @@
+<html devsite><head>
+ <title>配置</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 组件时,请参考以下部分中包含的相关信息、文档、提示和技巧。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/kernel.html b/zh-cn/devices/tech/config/kernel.html
new file mode 100644
index 00000000..1fe7c5aa
--- /dev/null
+++ b/zh-cn/devices/tech/config/kernel.html
@@ -0,0 +1,149 @@
+<html devsite><head>
+ <title>内核配置</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 内核配置的基础。设置会整理到 <code>android-base</code> 和 <code>android-recommended</code> .cfg 文件:</p><ul>
+<li><code>android-base</code>。这些选项可实现核心 Android 功能,所有设备都应该启用。</li>
+
+<li><code>android-recommended</code>。这些选项可实现高级 Android 功能,设备可选择性启用。</li>
+</ul>
+
+<p>android-base.cfg 和 android-recommended.cfg 文件均位于 android-common 内核 Repo:
+<a href="https://android.googlesource.com/kernel/common/">https://android.googlesource.com/kernel/common/</a>。</p><p>上游 Linux 内核 4.8 版本中为内核配置片段指定了新的位置 (kernel/configs)。对于基于版本 4.8 或更高版本的分支,Android 基础和建议的配置片段位于该目录中。对于基于版本 4.8 之前版本的内核分支,配置片段位于 android/ 目录中。</p>
+
+<p>如需详细了解已用于加强设备内核的控件,请参阅<a href="/security/overview/kernel-security.html">系统和内核安全</a>。如需详细了解必需的设置,请参阅 <a href="/compatibility/cdd.html">Android 兼容性定义文档 (CDD)</a>。</p>
+
+<h2 id="generating">生成内核配置</h2>
+<p>对于具有极简 defconfig 的设备,您可以使用以下命令来启用选项:</p>
+
+<pre><code>ARCH=<em>arch</em> scripts/kconfig/merge_config.sh <em>path</em>/<em>device</em>_defconfig android/configs/android-base.cfg android/configs/android-recommended.cfg</code></pre>
+
+<p>这会生成一个.config 文件,您可以使用该文件来保存新的 defconfig 或编译一个启用 Android 功能的新内核。</p>
+
+<h2 id="usb">启用 USB 主机模式选项</h2>
+
+<p>对于 USB 主机模式音频,请启用以下选项:</p>
+<pre><code>CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+# CONFIG_USB_AUDIO is for a peripheral mode (gadget) driver
+</code></pre>
+
+<p>对于 USB 主机模式 MIDI,请启用以下选项:</p>
+<pre><code>CONFIG_SND_USB_MIDI=y</code></pre>
+
+<h2 id="Seccomp-BPF-TSYNC">Seccomp-BPF 与 TSYNC</h2>
+<p>Seccomp-BPF 是一种内核安全技术,支持创建沙盒来限制进程可以进行的系统调用。TSYNC 功能可以实现从多线程程序中使用 Seccomp-BPF。这种能力仅限具有 seccomp 支持上游的架构:ARM、ARM64、x86 和 x86_64。</p>
+
+<h3 id="backport-ARM-32">用于 ARM-32、X86、X86_64 的内核 3.10 向后移植</h3>
+
+<p>确保 Kconfig 中已启用 <code>CONFIG_SECCOMP_FILTER=y</code>(截至 Android 5.0 CTS 已验证),然后择优挑选来自 AOSP kernel/common:android-3.10 存储区的以下变更:<a href="https://android.
+googlesource.com/kernel/common/+log/9499cd23f9d05ba159
+fac6d55dc35a7f49f9ce76..a9ba4285aa5722a3b4d84888e78ba8adc0046b28">9499cd23f9d05ba159fac6d55dc35a7f49f9ce76..a9ba4285aa5722a3b4d84888e78ba8adc0046b28</a>
+</p>
+
+<ul>
+<li><a href="https://android.googlesource.com/kernel/common/+/a03a2426ea9f1d9dada33cf4a824f63e8f916c9d">a03
+a242 arch: Introduce smp_load_acquire(), smp_store_release()</a>(a242 架构:引入 smp_load_acquire()、smp_store_release()),作者:Peter Zijlstra</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/987a0f1102321853565c4bfecde6a5a58ac6db11">987a0f1
+introduce for_each_thread() to replace the buggy while_each_thread()</a>(引入 for_each_thread() 以替换有问题的 while_each_thread()),作者:Oleg Nesterov</li>
+ <li><a href="https://android.googlesource.com/kernel/common/+/2a30a4386e4a7e1283157c4cf4cfcc0306b22ac8">2a30a43
+seccomp: create internal mode-setting function</a>(seccomp:创建内部 mode-setting 函数),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+
+/b8a9cff6dbe9cfddbb4d17e2dea496e523544687">b8a9cff
+seccomp: extract check/assign mode helpers</a>(seccomp:提取检查/分配模式帮助程序),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/8908dde5a7fdca974374b0dbe6dfb10f69df7216">8908dde
+seccomp: split mode setting routines</a>(seccomp:拆分模式设置例行程序),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/e985fd474debedb269fba27006eda50d0b6f07ef">e985fd4
+seccomp: add "seccomp" syscall</a>(seccomp:添加“seccomp”系统调用),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/9d0ff
+694bc22fb458acb763811a677696c60725b">9d0ff69
+sched: move no_new_privs into new atomic flags</a>(sched:将 no_new_privs 移至新的原子标志中),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/b6a12bf4dd762236c7f637b19cfe10a268304b9b">b6a12bf
+seccomp: split filter prep from check and apply</a>(seccomp:将过滤器准备工作从检查和应用流程中分离出来),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/61b6b882a0abfeb627d25a069cfa1d232b84c8eb">61b6b88
+seccomp: introduce writer locking</a>(seccomp:引入写入者锁定),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/c852ef778224ecf5fe995d74ad96087038778bca">c852ef7
+seccomp: allow mode setting across threads</a>(seccomp:允许跨线程模式设置),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/f14a5db2398afed8f416d244e6da6b23940997c6">f14a5db
+seccomp: implement SECCOMP_FILTER_FLAG_TSYNC</a>(seccomp:实施 SECCOMP_FILTER_FLAG_TSYNC),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/9ac860041db
+860a59bfd6ac82b31d6b6f76ebb52">9ac8600
+seccomp: Replace BUG(!spin_is_locked()) with assert_spin_lock</a>(seccomp:用 assert_spin_lock 替换 BUG(!spin_is_locked())),作者:Guenter Roeck</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/900e9fd0d5d15c596cacfb89ce007c933cea6e1c">900e9fd
+seccomp: fix syscall numbers for x86 and x86_64</a>(seccomp:修复 x86 和 x86_64 的系统调用号),作者:Lee Campbell</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/a9ba4285aa5722a3b4d84888e78ba8adc0046b28">a9ba428
+ARM: add seccomp syscall</a>(ARM:添加 seccomp 系统调用),作者:Kees Cook</li>
+</ul>
+
+<h3 id="backport-ARM-64">用于 ARM-64 的内核 3.10 向后移植</h3>
+<p>确保 Kconfig 中已启用 <code>CONFIG_SECCOMP_FILTER=y</code>(截至 Android 5.0 CTS 已验证),然后择优挑选来自 AOSP kernel/common:android-3.10 存储区的以下变更:</p>
+<ul>
+<li><a href="https://android.googlesource.com/kernel/common/+/cfc7e99e9e3900056028a7d90072e9ea0d886f8d">cfc7e99e9
+arm64: Add __NR_* definitions for compat syscalls</a>(arm64:为兼容性系统调用添加 __NR_* 定义),作者:JP Abgrall</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/bf11863d45eb3dac0d0cf1f818ded11ade6e28d3">bf11863
+arm64: Add audit support</a>(arm64:添加审计支持),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/3
+e21c0bb663a23436e0eb3f61860d4fedc233bab">3e21c0b
+arm64: audit: Add audit hook in syscall_trace_enter/exit()</a>(arm64:审计:在 syscall_trace_enter/exit() 中添加审计钩),作者:JP Abgrall</li>
+<li><a href="https://android.googlesource.com/kernel
+/common/+/9499cd23f9d05ba159fac6d55dc35a7f49f9ce76">9499cd2
+syscall_get_arch: remove useless function arguments</a>(syscall_get_arch:移除无用的函数参数),作者:Eric Paris</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/2a30a4386e4a7e1283157c4cf4cfcc0306b22ac8">2a30a43
+seccomp: create internal mode-setting function</a>(seccomp:创建内部 mode-setting 函数),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/b8a9cff6dbe9cfddbb4d17e2dea496e523544687">b8a9cff
+seccomp: extract check/assign mode helpers</a>(seccomp:提取检查/分配模式帮助程序),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/8908dde5a7fdca974374b0dbe6dfb10f69df7216">8908dde
+seccomp: split mode setting routines</a>(seccomp:拆分模式设置例行程序),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/e985fd474debedb269fba27006eda50d0b6f07ef">e985fd4
+seccomp: add "seccomp" syscall</a>(seccomp:添加“seccomp”系统调用),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/9d0ff694bc22fb458acb763811a677696c60725b">9d0ff69
+sched: move no_new_privs into new atomic flags</a>(sched:将 no_new_privs 移至新的原子标志中),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/b6a12bf4dd762236c7f637b19cfe10a268304b9b">b6a12bf
+seccomp: split filter prep from check and apply</a>(seccomp:将过滤器准备工作从检查和应用流程中分离出来),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/61b6b882a0abfeb627d25a069cfa1d232b84c8eb">61b6b88
+seccomp: introduce writer locking</a>(seccomp:引入写入者锁定),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/c852ef778224ecf5fe995d74ad96087038778bca">c852ef7
+seccomp: allow mode setting across threads</a>(seccomp:允许跨线程模式设置),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/f14a5db2398afed8f416d244e6da6b23940997c6">f14a5db
+seccomp: implement SECCOMP_FILTER_FLAG_TSYNC</a>(seccomp:实施 SECCOMP_FILTER_FLAG_TSYNC),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/9ac860041db860a59bfd6ac82b31d6b6f76ebb52">9ac8600
+seccomp: Replace BUG(!spin_is_locked()) with assert_spin_lock</a>(seccomp:用 assert_spin_lock 替换 BUG(!spin_is_locked())),作者:Guenter Roeck</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/900e9fd0d5d15c596cacfb89ce007c933cea6e1c">900e9fd
+seccomp: fix syscall numbers for x86 and x86_64</a>(seccomp:修复 x86 和 x86_64 的系统调用号),作者:Lee Campbell</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/a9ba4285aa5722a3b4d84888e78ba8adc0046b28">a9ba428
+ARM: add seccomp syscall</a>(ARM:添加 seccomp 系统调用),作者:Kees Cook</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/41900903483eb96602dd72e719a798c208118aad">4190090
+ARM: 8087/1: ptrace: reload syscall number after secure_computing() check</a>(ARM:8087/1:ptrace:在 secure_computing() 检查后重新加载系统调用号),作者:Will Deacon</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/abbfed9ed1a78701ef3db74f5287958feb897035">abbfed9
+arm64: ptrace: add PTRACE_SET_SYSCALL</a>(arm64:ptrace:添加 PTRACE_SET_SYSCALL),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/feb28436457d33fef9f264635291432df4b74122">feb2843
+arm64: ptrace: allow tracer to skip a system call</a>(arm64:ptrace:允许跟踪进程跳过系统调用),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/dab10731da65a0deba46402ca9fadf6974676cc8">dab1073
+asm-generic: add generic seccomp.h for secure computing mode 1</a>(asm-generic:为安全计算模式 1 添加常规 seccomp.h),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/4f12b53f28a751406a27ef7501a22f9e32a9c30b">4f12b53
+add seccomp syscall for compat task</a>(为兼容性任务添加 seccomp 系统调用),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/77227239d20ac6381fb1aee7b7cc902f0d14cd85">7722723
+arm64: add SIGSYS siginfo for compat task</a>(arm64:为兼容性任务添加 SIGSYS siginfo),作者:AKASHI Takahiro</li>
+<li><a href="https://android.googlesource.com/kernel/common/+/210957c2bb3b4d111963bb296e2c42beb8721929">210957c
+arm64: add seccomp support</a>(arm64:添加 seccomp 支持),作者:AKASHI Takahiro</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/kernel_network_tests.html b/zh-cn/devices/tech/config/kernel_network_tests.html
new file mode 100644
index 00000000..63de4b27
--- /dev/null
+++ b/zh-cn/devices/tech/config/kernel_network_tests.html
@@ -0,0 +1,47 @@
+<html devsite><head>
+ <title>内核网络单元测试</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 5.0 开始,要使 Android 网络堆栈在 Linux 内核中正常运行,开发者需要在近期内曾向上游进行过多次提交,或开发者有多次提交尚未送达上游。手动验证要求的内核功能或跟踪缺失的提交并不容易,因此,Android 团队打算共享他们使用的测试,以确保内核按预期运行。</p>
+
+<h2 id="purpose">为何要运行测试?</h2> <p>运行这些测试的原因主要有 3 个:</p> <ol> <li>设备上使用的 Linux 内核的确切版本通常是特定于设备的,如果不运行测试,就很难了解某一版本的内核运行是否正常。</li> <li>将内核补丁程序向前移植和向后移植到不同的内核版本或不同的设备树,可能会导致出现一些细微的问题;如果不运行测试,则很难发现这种问题。例如,在开发过程中,某些设备的初始版本具有从 Android-3.4 向前移植(而非从 Android-3.10 中挑选)的 UID 路由补丁程序,因而导致行为不正常。</li> <li>新的网络功能可能需要借助新的内核功能或内核错误修复来实现。</li> </ol> <p>如果测试没有通过,则设备的网络堆栈会运行异常,从而导致出现用户可见的连接错误,例如 WLAN 网络断开连接。设备还可能会无法通过 Android 兼容性测试套件 (CTS) 测试。</p>
+
+<h2 id="using">使用测试</h2> <p>测试会使用 <a href="http://user-mode-linux.sourceforge.net/">User-Mode Linux</a> 来启动内核,如同 Linux 主机上的一个进程。请参阅<a href="https://source.android.com/source/initializing.html">构建编译环境</a>,查看合适的操作系统版本。单元测试框架会使用适当的磁盘映像启动内核,并从主机文件系统运行测试。测试使用 Python 2.x 进行编写,并使用 TAP 接口来测试内核行为和套接字 API。</p>
+
+<h3 id="compiling">针对 ARCH=um 编译内核</h3> <p>要运行测试,则必须针对 <code>ARCH=um SUBARCH=x86_64</code> 编译内核。这是一个受支持的基础架构上游,位于通用 Android 内核树(例如 <code>android-3.10</code>、<code>android-3.18</code>)中。但是,有时设备内核不会在这种模式下进行编译,因为设备树会在通用文件中包含特定于设备或特定于硬件的代码(例如 <code>sys/exit.c</code>)。</p> <p>在很多情况下,确保特定于硬件的代码位于 <code>#ifdef</code> 之后就足够了。通常,这应该是配置选项中的 <code>#ifdef</code>,用于控制与代码相关的特定功能。如果没有这样的配置选项,则将特定于硬件的代码放在 <code>#ifndef CONFIG_UML</code> 块中。</p> <p>一般来说,这项修复应该由内核树提供者(例如,芯片组供应商或 SoC 供应商)负责。我们正在与原始设备制造商 (OEM) 和供应商合作,确保当前和未来的内核将针对 <code>ARCH=um
+SUBARCH=x86_64</code> 进行编译,而无需进行任何更改。</p>
+
+<h3 id="running">运行测试</h3> <p>测试位于 <a href="https://android.googlesource.com/kernel/tests/+/master/net/test"><code>kernel/tests/net/test</code></a> 下。建议您<b>从 AOSP master 运行</b>测试,因为它们是最新的;在某些情况下,指定的 Android 版本正常运行所必需的内核功能尚未在给定版本中进行全面测试。有关如何运行测试的信息,请参阅<a href="https://android.googlesource.com/kernel/tests/+/master/net/test/README">内核网络测试自述文件</a>。总而言之,从您的内核树顶部运行:</p>
+
+<pre> &lt;android tree&gt;/kernel/tests/net/test/run_net_test.sh all_tests.sh</pre>
+
+<h3 id="passing">通过测试</h3> <p>内核网络测试 Python 源文件包含注释,这些注释会指定通过测试所必需的已知内核提交。在常见内核树中,至少 AOSP 中的 <a href="https://android-review.googlesource.com/#/q/project:kernel/common"><code>kernel/common</code></a> 项目中的 <code>android-3.10</code> 和 <code>android-3.18</code> 分支应该通过测试。因此,在由 3.10 或 3.18 派生的内核树上通过测试在很大程度上而言就是从这些树中挑选补丁程序。</p>
+
+<h2 id="contributing">做出贡献</h2>
+
+<h3 id="reporting">报告问题</h3> <p>请使用<a href="https://code.google.com/p/android/issues/list?q=label%3AComponent-Networking">组件网络</a>标签在 <a href="https://code.google.com/p/android/issues/entry?template=Developer%20bug%20report">Android 问题跟踪器</a>中报告内核网络测试的任何问题。</p>
+
+<h3 id="documenting">记录提交并添加测试</h3> <p>请如上文所述报告问题;如果可能,请在发生以下情况时上传更改以修复问题:</p> <ul> <li>测试没有在通用内核树上通过</li> <li>您发现在源代码注释中没有提及某项必要的提交</li>
+<li>需要进行重大更改才能在上游内核通过测试</li>
+<li>您认为测试是多余指定的,或者未来的内核测试会失败</li> <li>您希望添加更多测试或扩大现有测试的覆盖面</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/namespaces_libraries.html b/zh-cn/devices/tech/config/namespaces_libraries.html
new file mode 100644
index 00000000..acf8971c
--- /dev/null
+++ b/zh-cn/devices/tech/config/namespaces_libraries.html
@@ -0,0 +1,51 @@
+<html devsite><head>
+ <title>原生库的命名空间</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 7.0 推出了针对原生库的命名空间,旨在限制内部 API 可见性,并解决应用在使用平台库(而非它们自己的库)时意外终止的问题。请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">通过 Android 7.0 中的私有 C/C++ 符号限制提升稳定性</a>这篇 Android 开发者博文,了解针对应用的更改。</p>
+
+<h2 id="architecture">架构</h2>
+
+<p>这项更改会将系统库与应用库分离开来,这样可以极大地避免意外使用内部系统库(反之亦然)。
+</p>
+
+<img src="images/namespace-libraries.png" alt="原生库的命名空间" id="namespace-libraries"/>
+<p class="img-caption">
+ <strong>图 1.</strong> 原生库的命名空间</p>
+
+<p>
+原生库的命名空间可防止应用使用私有平台的原生 API(例如使用 OpenSSL)。它还可以避免应用在使用平台库(而非它们自己的库)时出现意外终止的情况(如使用 <code>libpng</code> 时)。
+</p>
+
+<h2 id="adding-additional-native-libraries">添加其他原生库</h2>
+
+<p>
+除了标准的公共原生库之外,供应商还可以选择提供可供应用访问的其他原生库,方法是将它们放在 <code>/vendor</code> 库文件夹(如果是 32 位的库,则为 /vendor/lib;如果是 64 位的库,则为 /vendor/lib64)下,并将其列于 <code>/vendor/etc/public.libraries.txt</code> 中
+</p>
+
+<h2 id="updating-app-non-public">将应用更新为不使用非公共原生库</h2>
+
+<p>
+该功能仅适用于 SDK 版本为 24 或更高版本的应用;要了解向后兼容性,请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">表 1. 当您的应用链接到非公共原生库时会发生什么情况</a>。可供应用访问的 Android 原生库(又称为公共原生库)列表列于 CDD 部分 3.1.1。适用于版本 24 或更高版本且使用任何非公共库的应用应进行更新。如需了解详情,请参阅<a href="https://developer.android.com/preview/behavior-changes.html#ndk">链接到平台库的 NDK 应用</a>。
+</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/config/renderer.html b/zh-cn/devices/tech/config/renderer.html
new file mode 100644
index 00000000..57d60c07
--- /dev/null
+++ b/zh-cn/devices/tech/config/renderer.html
@@ -0,0 +1,179 @@
+<html devsite><head>
+ <title>OpenGLRenderer 配置</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>本文档介绍了以充分利用硬件为目标的性能调校。</p>
+
+<h2>OpenGLRenderer (libhwui) 属性</h2>
+<p>本文档列出了您可以用来控制 Android 的 2D 硬件加速渲染管道的所有属性。将 <code>device.mk</code> 中的这些属性设为 <code>PRODUCT_PROPERTY_OVERRIDES</code>。</p>
+
+<table>
+<tbody><tr>
+ <th>属性</th>
+ <th>类型</th>
+ <th>默认值</th>
+ <th>说明</th>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.disable_scissor_opt</code></td>
+ <td><code>boolean</code></td>
+ <td><code>false</code></td>
+ <td><p>用于启用或停用剪刀优化。接受的值为 true 和 false。如果启用剪刀优化,则 OpenGLRenderer 会尝试选择性启用和停用 GL 剪刀测试,以尽可能不使用剪刀。</p>
+ <p>如果停用优化,则 OpenGLRenderer 会让 GL 剪刀测试保持启用状态,并根据需要更改剪刀矩形。当剪刀矩形的更改频率超过启用或停用剪刀测试的频率时,某些 GPU(例如 SGX 540)的性能会更好。</p>
+ </td>
+</tr>
+
+<tr>
+
+ <td><code>ro.hwui.texture_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>24</code></td>
+ <td>定义每个进程纹理缓存的大小(以兆字节为单位)。我们建议使用大容量的缓存,以足够容纳多个 32 位纹理的屏幕(例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 4 MB 的内存,因此缓存应至少为 20 MB)。</td>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.layer_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>16</code></td>
+ <td>定义每个进程图层缓存的大小(以兆字节为单位)。我们建议使用大容量的缓存,以足够容纳 4 次 32 位屏幕。例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 4 MB 的内存,因此缓存应至少为 16 MB。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.gradient_cache_size</code></td>
+ <td><code>0.5</code></td>
+ <td><code>float</code></td>
+ <td>定义每个进程渐变缓存的大小(以兆字节为单位)。单次渐变通常占用 1-4 KB 的内存。建议使用大容量的缓存,以足够容纳至少 12 次渐变。</td>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.patch_cache_size</code></td>
+ <td><code>integer</code></td>
+ <td><code>128</code></td>
+ <td>定义每个进程中 9patch 缓存的大小(以千字节为单位)。此缓存仅保留顶点数据,因此可以保持小容量。每个顶点由 4 个浮点数或 16 个字节组成。</td>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.path_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>4</code></td>
+ <td>定义每个进程路径缓存的大小(以兆字节为单位)。我们建议使用大容量缓存,以足够容纳至少一个 32 位纹理的屏幕。例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 4 MB 的内存,因此缓存应至少为 4 MB。</td>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.shape_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>1</code></td>
+ <td>定义每个进程图形缓存的大小(以兆字节为单位)。该值由多个缓存(如圆形和圆角矩形)使用。我们建议使用大容量缓存,以足够容纳至少一个 8 位屏幕。例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 1 MB 的内存,因此缓存应至少为 1 MB。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.drop_shadow_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>2</code></td>
+ <td>定义每个进程文字阴影缓存的大小(以兆字节为单位)。我们建议使用大容量缓存,以足够容纳两个 8 位纹理的屏幕。例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 1 MB 的内存,因此缓存应至少为 2 MB。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.r_buffer_cache_size</code></td>
+ <td><code>float</code></td>
+ <td><code>2</code></td>
+ <td>定义每个进程的渲染缓冲区缓存的大小(以兆字节为单位)。我们建议您使用大容量的缓存,以足够容纳 2 次 8 位的屏幕。例如,在 1280x800 显示屏上,一次全屏缓冲使用大约 1 MB 的内存,因此缓存应至少为 2 MB。如果设备支持 4 位或 1 位模板缓冲,则可以使用更小容量的缓存。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.texture_cache_flush_rate</code></td>
+ <td><code>float</code></td>
+ <td><code>0.6</code></td>
+ <td>定义内存清理之后保留的纹理缓存所占的比例。当系统需要回收所有应用的内存时,就会触发内存清理。我们建议在这种情况下释放大约 50% 的缓存。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.text_small_cache_width</code></td>
+ <td><code>integer</code></td>
+ <td><code>1024</code></td>
+ <td>定义默认字体缓存的宽度(以像素为单位)。上限取决于 GPU 上传纹理的速度。我们建议该宽度不低于 1024 像素、不超过 2048 像素。您还应该使用二次方值。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.text_small_cache_height</code></td>
+ <td><code>integer</code></td>
+ <td><code>256</code></td>
+ <td>定义默认字体缓存的高度(以像素为单位)。上限取决于 GPU 上传纹理的速度。我们建议该高度不低于 256 像素、不超过 1024 像素。</td>
+</tr>
+<tr>
+ <td><code>ro.hwui.text_large_cache_width</code></td>
+ <td><code>integer</code></td>
+ <td><code>2048</code></td>
+ <td>定义大号字体缓存的宽度(以像素为单位)。此缓存用于字形过大难以适应默认字体缓存的情形。上限取决于 GPU 上传纹理的速度。我们建议该宽度不低于 2048 像素、不超过 4096 像素。您还应该使用二次方值。</td>
+</tr>
+
+<tr>
+ <td><code>ro.hwui.text_large_cache_height</code></td>
+ <td><code>integer</code></td>
+ <td><code>512</code></td>
+ <td>定义大号字体缓存的高度(以像素为单位)。大号字体缓存用于字形过大难以适应默认字体缓存的情形。上限取决于 GPU 上传纹理的速度。我们建议该高度不低于 512 像素、不超过 2048 像素。您还应该使用二次方值。</td>
+</tr>
+
+<tr>
+ <td><code>ro.zygote.disable_gl_preload</code></td>
+ <td><code>boolean</code></td>
+ <td><code>false</code></td>
+ <td>用于在启动时启用/停用 Zygote 中的 EGL/GL 驱动程序预加载。当此属性设为 false 时,Zygote 将通过调用 eglGetDisplay(EGL_DEFAULT_DISPLAY) 来预加载 GL 驱动程序。目标是加载 Zygote 中的动态库代码,以便与所有其他进程共享。如果驱动程序不支持共享,则将此属性设为 true。</td>
+</tr>
+
+<tr>
+ <td><code>hwui.text_gamma_correction</code></td>
+ <td><code>string</code></td>
+ <td><code>lookup</code></td>
+ <td>选择文字伽马校正方法。有以下四种方法可供选择:<ul>
+ <li><code>lookup3</code>:基于查询表校正。伽马校正针对黑白文字的表现不同(请参见下方的阈值)。</li>
+
+ <li><code>lookup</code>:基于单一查询表校正。</li>
+
+ <li><code>shader3</code>:由 GLSL 着色器应用校正。伽马校正针对黑白文字的表现不同(请参见下方的阈值)。</li>
+
+ <li><code>shader</code>:由 GLSL 着色器应用校正。</li>
+ </ul>查询伽马校正在着色器数学受限的 GPU 上表现最出色。着色器伽马校正是节省内存的最佳选择。我们建议使用默认的 <code>lookup</code> 方法,它能够在质量、速度和内存使用方面提供理想的折中方案。
+</td>
+</tr>
+
+<tr>
+ <td><code>hwui.text_gamma</code></td>
+ <td><code>float</code></td>
+ <td><code>1.4</code></td>
+ <td>定义用于文字伽马校正的伽马值。该值可以根据设备使用的显示屏进行调整。</td>
+</tr>
+<tr>
+ <td><code>hwui.text_gamma.black_threshold</code></td>
+ <td><code>integer</code></td>
+ <td><code>64</code></td>
+ <td>定义应用黑色伽马校正的亮度阈值上限。必须在 0-255 的范围内定义该值。</td>
+</tr>
+<tr>
+ <td><code>hwui.text_gamma.white_threshold</code></td>
+ <td><code>integer</code></td>
+ <td><code>192</code></td>
+ <td>定义应用白色伽马校正的亮度阈值下限。必须在 0-255 的范围内定义该值。</td>
+</tr>
+<tr>
+ <td><code>hwui.use_gpu_pixel_buffers</code></td>
+ <td><code>boolean</code></td>
+ <td><code>true</code></td>
+ <td>用于启用或停用 OpenGL ES 3.0 硬件上的 PBO。PBO 渲染程序会使用 PBO 来执行异步纹理上传,尤其是字体缓存。该属性应始终保持启用状态,但如果使用 PBO 导致出现损坏或性能低下的情况,则可以在启动或开发期间停用该属性。因此,该属性不是只读属性。</td>
+</tr>
+</tbody></table>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/connect/call-notification.html b/zh-cn/devices/tech/connect/call-notification.html
new file mode 100644
index 00000000..6bf17f3a
--- /dev/null
+++ b/zh-cn/devices/tech/connect/call-notification.html
@@ -0,0 +1,101 @@
+<html devsite><head>
+ <title>来电通知</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 7.0 将与来电通知相关的功能从 Android 平台中的通讯系统 (Telecom) 服务移至拨号器应用中。而在以前,显示与来电相关通知的职责在通讯系统和默认的拨号器应用之间是分开的,这就导致了行为不一致。在 Android 7.0 中,拨号器承担了处理来电通知的所有职责。</p>
+
+<h2 id="android_6">Android 6.x 及更早版本中的行为</h2>
+<p>在之前的 Android 版本中,通讯系统和拨号器分别承担以下职责:</p>
+
+<table>
+<tbody><tr>
+<th>功能</th>
+<th>由通讯系统执行</th>
+<th>由拨号器执行</th>
+</tr>
+
+<tr>
+<td>来电通知</td>
+<td>是(响铃、振动)</td>
+<td>是(通知显示、来电显示)</td>
+</tr>
+
+<tr>
+<td>发送至语音信箱</td>
+<td>是</td>
+<td>否</td>
+</tr>
+
+<tr>
+<td>自定义铃声</td>
+<td>是</td>
+<td>否</td>
+</tr>
+
+<tr>
+<td>未接电话通知</td>
+<td>是</td>
+<td>否</td>
+</tr>
+
+<tr>
+<td>消息等待指示(呼叫语音信箱)</td>
+<td>是(电话)</td>
+<td>否</td>
+</tr>
+
+<tr>
+<td>可视语音邮件通知</td>
+<td>否</td>
+<td>是</td>
+</tr>
+
+</tbody>
+</table>
+
+<p>因这种职责分担导致的不一致行为的示例包括:</p>
+<ul>
+<li>通讯系统负责启动振铃器/振动器,但拨号器负责显示来电通知。如果拨号器启动缓慢,则可能导致响铃数秒后才显示来电通知。</li>
+<li>通讯系统负责显示未接电话通知。由于专有功能(如 Google 来电显示)不适用于这些通知,因此可能会导致通讯系统通知与拨号器界面(如通话记录)不一致。</li>
+</ul>
+
+<h2 id="android_7">Android 7.0 及更高版本中的行为</h2>
+<p>Android 开放源代码项目 (AOSP) 拨号器会实施新的功能。有关详情,请参阅以下文档:</p>
+<ul>
+<li>未接电话通知<br />
+<a href="https://android.googlesource.com/platform/packages/services/Telecomm/+/nougat-release/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java">Telecom/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/nougat-release/src/com/android/dialer/calllog/MissedCallNotificationReceiver.java">Dialer/src/com/android/dialer/calllog/MissedCallNotificationReceiver.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/nougat-release/src/com/android/dialer/calllog/MissedCallNotifier.java">Dialer/src/com/android/dialer/calllog/MissedCallNotifier.java</a></li>
+<li>播放铃声<br />
+<a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-release/telecomm/java/android/telecom/InCallService.java">frameworks/base/telecomm/java/android/telecom/InCallService.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/services/Telecomm/+/nougat-release/src/com/android/server/telecom/InCallController.java">Telecom/src/com/android/server/telecom/InCallController.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/nougat-release/InCallUI/src/com/android/incallui/ringtone/">Dialer/InCallUI/src/com/android/incallui/ringtone</a><br />
+<a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/nougat-release/InCallUI/src/com/android/incallui/StatusBarNotifier.java">Dialer/InCallUI/src/com/android/incallui/StatusBarNotifier.java</a></li>
+<li>VVM 通知<br />
+<a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-release/telephony/java/android/telephony/TelephonyManager.java">frameworks/base/telephony/java/android/telephony/TelephonyManager.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/services/Telephony/+/nougat-release/src/com/android/phone/PhoneInterfaceManager.java">Telephony/src/com/android/phone/PhoneInterfaceManager.java</a><br />
+<a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/nougat-release/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java">Dialer/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java</a></li>
+</ul>
+
+<h2 id="implement">实现</h2>
+<p>设备实现人员可能需要更新通讯系统/电话组件(公开可供默认拨号器使用的 API)。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/connect/emergency-affordance.html b/zh-cn/devices/tech/connect/emergency-affordance.html
new file mode 100644
index 00000000..723514b8
--- /dev/null
+++ b/zh-cn/devices/tech/connect/emergency-affordance.html
@@ -0,0 +1,161 @@
+<html devsite><head>
+ <title>实施“提供紧急呼叫”功能</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>从 2017 年 1 月 1 日开始,在印度地区销售的所有移动设备都需要应印度电信部门 (DoT) 的要求提供紧急呼叫按钮。</p>
+
+<p>为符合此类法规要求,我们开发了“提供紧急呼叫”功能,以便为 Android 设备提供紧急呼叫按钮的参考实现。这项功能将在未来的 Android 版本中默认启用,不过现有版本中必须安装相应的补丁程序。目前,该功能专门针对在印度市场销售的设备;不过,鉴于该功能在印度境外无效,因此也可以在全球范围销售的所有设备上提供。</p>
+
+<h2 id="examples-source">示例和源代码</h2> <p>“提供紧急呼叫”功能在 Android 开放源代码项目 (AOSP) 的 <a href="https://android.googlesource.com/platform/frameworks/base/">frameworks/base</a> 项目中实现。它在 master 分支中提供,并将在未来的 Android 版本中默认启用。</p>
+
+<p>目前,以下分支和提交中已提供该功能。提供这些信息是为了方便设备制造商轻松将必要的更改以补丁程序的形式添加到现有版本中。想要实现 AOSP 参考“提供紧急呼叫”功能的设备制造商可以从适用的分支中挑选提交并加入到自己的版本中。</p>
+
+<p class="table-caption" id="cherry-picks-reference-implementation">
+ <strong>表 1. </strong> 挑选 AOSP 参考“提供紧急呼叫”功能</p>
+<table>
+<tbody>
+<tr>
+<th scope="col">分支</th>
+<th scope="col">提交</th>
+</tr>
+<tr>
+<td>master</td>
+<td><a href="https://android-review.googlesource.com/#/c/284723/">e0c3c66</a> 添加了“提供紧急呼叫”功能<br />
+<a href="https://android-review.googlesource.com/#/c/287188/">42a4338</a> 添加了紧急操作字符串的翻译<br />
+<a href="https://android-review.googlesource.com/#/c/286858/">4df8d64</a> 修复了“提供紧急呼叫”在平板电脑上显示的问题</td>
+</tr>
+<tr>
+<td>nougat-dev</td>
+<td><a href="https://android-review.googlesource.com/#/c/284761/">e6680d9</a> 添加了“提供紧急呼叫”功能<br />
+<a href="https://android-review.googlesource.com/#/c/287293/">95e1865</a> 添加了紧急操作字符串的翻译<br />
+<a href="https://android-review.googlesource.com/#/c/286953/">a70bb89</a> 修复了“提供紧急呼叫”在平板电脑上显示的问题</td>
+</tr>
+<tr>
+<td>marshmallow-dev</td>
+<td><a href="https://android-review.googlesource.com/#/c/284624/">cd22634</a> 添加了“提供紧急呼叫”功能<br />
+<a href="https://android-review.googlesource.com/#/c/286937/">13f51c6</a> 添加了紧急操作字符串的翻译<br />
+<a href="https://android-review.googlesource.com/#/c/287241/">6531666</a> 修复了“提供紧急呼叫”在平板电脑上显示的问题</td>
+</tr>
+<tr>
+<td class="style1">lollipop-mr1-dev</td>
+<td><a href="https://android-review.googlesource.com/#/c/284743/">5fbc86b</a> 添加了“提供紧急呼叫”功能<br />
+<a href="https://android-review.googlesource.com/#/c/287382/">1b60879</a> 添加了紧急操作字符串的翻译<br />
+<a href="https://android-review.googlesource.com/#/c/286856/">d74366f</a> 修复了“提供紧急呼叫”在平板电脑上显示的问题</td>
+
+</tr>
+</tbody>
+</table>
+
+<h2 id="implementation">实现</h2> <p>“提供紧急呼叫”功能不会更改通过 Android SDK 公开的 API。该功能启用并激活后,会提供两个可启动 112 紧急呼救(印度的唯一紧急呼救号码,由印度电信部门强制实施)的触发器。<br />紧急呼救有两种启动方式:</p> <ul>
+<li>长按锁定屏幕上的<strong>紧急呼救</strong>按钮(图 1)</li> <li>长按电源按钮,然后从显示的全局操作菜单中点按<strong>紧急呼救</strong>选项(图 2)。<em></em></li> </ul>
+
+<table>
+ <tbody><tr>
+ <td width="50%"><img src="images/emergency-button.png" alt="紧急呼叫按钮" width="246" id="emergency-button"/>
+<p class="img-caption">
+ <strong>图 1. </strong> 长按锁定屏幕上的<strong>紧急呼救</strong>按钮(已用红框突显)。</p></td>
+ <td width="50%"><img src="images/emergency-option.png" alt="紧急呼叫按钮" width="247" id="emergency-option"/>
+<p class="img-caption">
+ <strong>图 2. </strong> 点按全局操作菜单中的<strong>紧急呼救</strong>操作项。<em></em></p></td>
+ </tr>
+</tbody></table>
+
+<p>该功能引入了以下内部组件:</p> <ul>
+<li>EmergencyAffordanceManager<br />
+<code>frameworks/base/core/java/com/android/internal/policy/EmergencyAffordanceManager.java</code>
+</li> <li>EmergencyAffordanceService<br />
+<code>frameworks/base/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java</code>
+</li> </ul>
+
+<h3 id="EmergencyAffordanceManager">EmergencyAffordanceManager</h3> <p>EmergencyAffordanceManager 提供使用“提供紧急呼叫”功能的内部 API。它提供启动紧急呼救的方法,并在运行时查询是否应启用该功能。</p> <ul> <li><code>void
+performEmergencyCall()</code> - 启动紧急呼救</li>
+<li><code>boolean needsEmergencyAffordance()</code> - 确定是否应启用该功能</li> </ul> <p>该功能可在构建时永久禁用,具体方法是将 <code>EmergencyAffordanceManager.ENABLED</code> 常量改为 <code>false</code>。这会导致 <code>needsEmergencyAffordance()</code> 始终返回 false 并阻止 <code>EmergencyAffordanceService</code> 启动。</p>
+
+<h3 id="EmergencyAffordanceService">EmergencyAffordanceService</h3> <p><code>EmergencyAffordanceService</code> 是一种系统服务,用于监控所有检测到的移动网络的移动设备国家/地区代码 (MCC) 和安装的 SIM 卡的 MCC。如果任何安装的 SIM 卡或检测到的移动网络的 MCC 与印度的其中一个 MCC(404、405)相匹配,则该功能将会启用。这意味着,即使没有 SIM 卡,该功能也可以在印度启用。前提是,假设在没有安装 SIM 卡的情况下,移动网络允许注册紧急呼救。该功能将保持启用状态,直到安装了非印度 SIM 卡且没有检测到具有匹配 MCC 的网络。</p>
+
+<p>以下资源和设置会影响“提供紧急呼叫”功能的行为。如果配置类型是“资源”,则是在 <code>frameworks/base/core/res/res/values/config.xml</code> 中定义的内部资源。如果配置类型为“设置”,则是在系统设置提供程序中存储的设置。</p>
+
+<p class="table-caption" id="settings-affecting behavior">
+ <strong>表 2. </strong> 影响“提供紧急呼叫”功能行为的设置</p>
+<table>
+<tbody>
+<tr>
+<th scope="col">配置类型</th>
+<th scope="col">名称</th>
+<th scope="col">说明</th>
+</tr>
+<tr>
+<td>资源</td>
+<td>config_emergency_call_number</td>
+<td>在紧急呼救启动时自动拨打的电话号码。<br />类型:字符串<br />默认值:112</td>
+</tr>
+<tr>
+<td>资源</td>
+<td>config_emergency_mcc_codes</td>
+<td>列出应该激活该功能的 MCC 的整数数组。<br />类型:整数数组<br />默认值:{404,405}</td>
+</tr>
+<tr>
+<td>设置</td>
+<td>emergency_affordance_number</td>
+<td>使用“提供紧急呼叫”致电号码的全局设置覆盖。此配置仅影响可调试的构建映像(即构建类型为 userdebug 或 eng)。此配置仅用于测试目的。<br />类型:字符串<br />默认值:未设置</td>
+</tr>
+<tr>
+<td>设置</td>
+<td>force_emergency_affordance</td>
+<td>全局设置,是否显示“提供紧急呼叫”(无论设备状态如何)。此配置仅用于测试目的。<br />类型:布尔值(1 或 0)<br />默认值:未设置 --&gt; 0</td>
+</tr>
+</tbody>
+</table>
+
+<h3 id="112">启用“112”紧急呼救</h3> <p>“提供紧急呼叫”功能使用紧急拨号器连接通话,因此通话可以在锁屏状态下连接。紧急拨号器只能将通话连接到无线界面层 (RIL) 提供的号码列表:在未安装 SIM 卡时,通过系统属性“ril.ecclist”连接;在插入 SIM 卡且 <code><i>&lt;SimSlotNumber&gt;</i></code> 是默认订阅者的插槽 ID 时,通过“<code>ril.ecclist&lt;<i>SimSlotNumber</i>&gt;</code>”连接。<br />使用“提供紧急呼叫”功能的设备制造商必须确保在印度地区销售的设备始终将 112 作为 RIL 中的紧急呼救号码。</p>
+
+<h2 id="validation">验证</h2> <p>在可调式的构建上测试时,可以使用以下命令更改呼叫的号码:</p>
+<pre>
+$ adb shell settings put global emergency_affordance_number <i>&lt;number_to_call&gt;</i>
+</pre>
+
+<p>虽然此设置可以在普通用户构建中设置,但会被忽略。要实际连接通话,号码必须存在于 RIL 提供的紧急呼救号码列表中。这可以临时设置,具体方法是在 userdebug 设备上使用通过根 shell 执行的以下命令:</p>
+<pre>
+$ setprop ril.ecclist "$(getprop ril.ecclist),<i>&lt;number_to_call&gt;</i>"
+</pre>
+
+<p>此外,如需在未检测到印度移动网络或未插入印度 SIM 卡的情况下强制启用“提供紧急呼叫”功能,可以使用以下命令:</p>
+<pre>
+$ adb shell settings put global force_emergency_affordance 1
+</pre>
+
+<p>在测试期间,建议至少对以下情况进行测试。</p>
+
+<ul> <li>激活之后,长按锁定屏幕上的<strong>紧急呼救</strong>按钮(图 1)可呼叫指定紧急呼救号码。</li>
+<li>激活之后,全局操作菜单中会显示<strong>紧急呼救</strong>选项,点按该选项可呼叫指定紧急呼救号码。</li> <li>在未检测到印度移动网络且安装了非印度 SIM 卡的情况下,该功能<b>不会</b><b>激活</b>。</li>
+<li>在安装印度 SIM 卡的情况下,无论是否检测到移动网络,该功能都<b>会激活</b>。</li> <li>在检测到印度移动网络的情况下,无论是否安装了 SIM 卡,该功能都<b>会激活</b><b></b>。</li> </ul>
+
+<p>如果设备支持多个 SIM 卡,则测试应确保 SIM 卡 MCC 检测功能在每个 SIM 卡插槽中都能正常运行。该功能不受 Android 兼容性影响,因此不用进行 CTS 测试。</p>
+
+<h2 id="faq">常见问题解答</h2>
+
+<h5 id="q-112">问:紧急呼救号码“112”尚未在印度授权使用,仍然使用该号码吗?</h5>
+
+<p>根据集成紧急通信与应答系统 (IECRS) 的定义,“112”是即将在印度用于公共安全应答点 (PSAP) 的号码。在 PSAP 获得授权之前,所有对“112”的呼叫都将转接到现有的“100”紧急呼救号码。</p>
+
+<h5 id="q-other-triggers">问:使用其他触发操作怎么样?比如按电源按钮三次?</h5> <p>设备制造商可以选择实施其他触发操作。点按硬件电源按钮三次也是印度电信部门批准的触发操作。不过,这种触发操作在 AOSP 参考实现中不受支持,因为有大量其他广泛使用的应用使用电源按钮手势,包括重复点按电源按钮。这些应用可能会干扰紧急拨号器,或者用户在尝试触发这些应用中的操作时可能会意外触发紧急呼叫按钮。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/connect/felica.html b/zh-cn/devices/tech/connect/felica.html
new file mode 100644
index 00000000..c988cf6c
--- /dev/null
+++ b/zh-cn/devices/tech/connect/felica.html
@@ -0,0 +1,44 @@
+<html devsite><head>
+ <title>FeliCa 的主机卡模拟</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>作为一种 RFID 智能卡系统,Felicity 卡(即 FeliCa)是日本、香港以及亚太地区 (APAC) 其他市场的 NFC 标准。它已在这些地区得到了普及,且已广泛应用于公交、零售和忠诚度服务。为面向这些地区出售的 Android 设备添加 FeliCa 支持有助于提高这些设备的实用性。</p>
+
+<h2 id="implementation">实现</h2>
+
+<p>HCE FeliCa 需要使用符合 NFC-F (JIS 6319-4) 标准的 NFC 硬件。</p>
+
+<p>FeliCa 的主机卡模拟 (HCE) 在本质上是 Android 上现有 HCE 实现的并行实现;它会适时地为 FeliCa 创建新类,并会在可能的情况下与现有 HCE 实现进行合并。</p>
+
+<p>Android 开放源代码项目 (AOSP) 包括以下 Android 组件:</p>
+
+<ul>
+ <li>框架类<ul>
+ <li>公共 HostNfcFService(便捷服务类)</li><li>@hide NfcFServiceInfo</li></ul>
+ </li><li>对核心 NFC 框架的修改</li></ul>
+
+<p>与大多数 Android 平台功能一样,制造商会编写驱动程序以使硬件可与 API 协作。</p>
+
+<h2 id="validation">验证</h2>
+
+<p>请使用 <a href="/compatibility/cts/index.html">Android 兼容性测试套件</a>来确保此功能会按预期运行。CTS 验证程序 (NfcTestActivity) 会针对报告 <code>android.hardware.nfc.hcef</code> 功能常量的设备测试该实现。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/connect/ril.html b/zh-cn/devices/tech/connect/ril.html
new file mode 100644
index 00000000..ad014a25
--- /dev/null
+++ b/zh-cn/devices/tech/connect/ril.html
@@ -0,0 +1,183 @@
+<html devsite><head>
+ <title>RIL 重构</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 7.0 已对无线接口层 (RIL) 进行重构,使用一组子功能改进了 RIL 功能。要实现这些功能,您需要对合作伙伴代码进行更改;您可以自行决定是否更改,不过我们建议您进行更改。重构更改具有向后兼容性,因此您可以继续使用之前实现的已重构功能。</p>
+
+<p>RIL 重构功能中包括以下子功能。您可以实现任何或所有子功能:</p>
+
+<ul>
+<li>增强的 RIL 错误代码:代码可以返回比现有 <code>GENERIC_FAILURE</code> 代码更具体的错误代码。这样一来,系统便可以提供关于错误原因的更具体信息,从而提高错误的问题排查效率。</li>
+
+<li>增强的 RIL 版本管理:RIL 版本管理机制得到增强,可以更准确更轻松地配置版本信息。</li>
+
+<li>利用唤醒锁定机制重新设计的 RIL 通信技术:采用唤醒锁定机制的 RIL 通信技术得到增强,可以改善设备的电池性能。</li>
+</ul>
+
+<h2 id="examples">示例和源代码</h2>
+
+<p>您也可以在 <a href="https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h"><code>https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h</code></a> 中的代码注释中找到有关 RIL 版本管理的文档。</p>
+
+<h2 id="implementation">实现</h2>
+
+<p>下面的部分介绍了如何实现 RIL 重构功能的子功能。</p>
+
+<h3 id="errorcodes">实现增强的 RIL 错误代码</h3>
+
+<h4 id="errorcodes-problem">问题</h4>
+
+<p>几乎所有的 RIL 请求调用在对错误做出响应时都会返回 <code>GENERIC_FAILURE</code> 错误代码。原始设备制造商 (OEM) 返回的所有应求响应都存在这个问题。如果同一 <code>GENERIC_FAILURE</code> 错误代码由 RIL 调用出于不同的原因返回,则很难通过错误报告对问题进行调试。供应商甚至需要花费相当长的时间才能确定代码的哪一部分本应返回 <code>GENERIC_FAILURE</code> 代码。</p>
+
+<h4 id="errorcodes-solution">解决方案</h4>
+
+<p>OEM 应返回与当前归类为 <code>GENERIC_FAILURE</code> 的各个不同错误相关联的独特错误代码值。</p>
+
+<p>如果 OEM 不希望公开披露自己的自定义错误代码,则可能会以一组独特整数(例如从 1 到 x;映射为从 <code>OEM_ERROR_1</code> 到 <code>OEM_ERROR_X</code>)的形式返回错误。供应商应确保返回的每个经掩码处理的这类错误代码都可以映射到其代码中唯一的错误原因。这样做的目的是,在 OEM 每次返回一般性错误时加快 RIL 问题的调试速度。要确定导致 <code>GENERIC_FAILURE</code> 的确切原因,可能需要花费很长时间,有时甚至找不到原因。</p><p>
+
+</p><p>在 <code>ril.h</code> 中,我们针对枚举 <code>RIL_LastCallFailCause</code> 和 <code>RIL_DataCallFailCause</code> 添加了更多错误代码,以便供应商代码可以避免返回 <code>CALL_FAIL_ERROR_UNSPECIFIED</code> 和 <code>PDP_FAIL_ERROR_UNSPECIFIED</code> 等一般性错误。</p>
+
+<h3 id="version">实现增强的 RIL 版本管理</h3>
+
+<h4 id="version-problem">问题</h4>
+
+<p>RIL 版本管理机制不够准确。供应商报告其 RIL 版本时所采用的机制不明晰,进而导致供应商报告的版本不正确。目前所使用的解决方法是对版本进行评估,但这种方法可能并不准确。</p>
+
+<h4 id="version-solution">解决方案</h4>
+
+<p><code>ril.h</code> 中提供了一个文档记录部分,该部分介绍了特定 RIL 版本值对应的内容。每个 RIL 版本均记录在内,包括与相应版本对应的更改信息。针对相应版本做出更改时,供应商必须在代码中更新其版本,并在进行 <code>RIL_REGISTER</code> 时返回该版本。</p>
+
+<h3 id="wakelocks">实现利用唤醒锁定机制重新设计的 RIL 通信技术</h3>
+
+<h4 id="wakelocks-prob-sum">问题摘要</h4>
+
+<p>在 RIL 通信中使用定时唤醒锁定的方式并不精确,因而会对电池性能带来负面影响。RIL 请求既可以是应求请求,也可以自发请求。应求请求应归入以下类别之一:</p>
+
+<ul>
+<li>同步:无需较长时间即可返回响应的请求。例如,<code>RIL_REQUEST_GET_SIM_STATUS</code>。</li>
+
+<li>异步:需要相当长时间才能返回响应的请求。例如,<code>RIL_REQUEST_QUERY_AVAILABLE_NETWORKS</code>。</li>
+</ul>
+
+<p>要实现重新设计的唤醒锁定,请按以下步骤操作:</p>
+
+<ol>
+<li>根据应求 RIL 命令所需的响应时间,将其归类为同步或异步。
+<p>做出该决定时请注意以下事项:</p>
+
+<ul>
+<li>如在异步应求 RIL 请求解决方案中所述,由于此类请求需要相当长时间才会返回响应,因此当 RIL Java 收到来自供应商代码的确认信息时,会释放唤醒锁定。这可能会使应用处理器从闲置状态转为挂起状态。当收到来自供应商代码的响应时,RIL Java(应用处理器)会重新获取唤醒锁定,并对响应进行处理,然后再次转入闲置状态。从闲置状态转为挂起状态然后再返回闲置状态这一流程可能会非常耗电。</li>
+
+<li>如果响应时间不够长,则与进入挂起状态(通过释放唤醒锁定,然后在系统返回响应时唤醒)相比,在整个响应时间内保持唤醒锁定并停留在闲置状态可能会更省电。因此,供应商应使用平台专用功率测量工具,以确定时间“t”在以下情况下的阈值:当应用处理器停留在闲置状态时(在整个时间“t”内)的耗电量多于从闲置状态转为挂起状态并返回闲置状态(在同一时间“t”内)的耗电量时。找出该时间“t”的值时,所用处理时间比“t”多的 RIL 命令可归类为“异步”,而其余 RIL 命令则可归类为“同步”。</li>
+</ul>
+</li>
+
+<li>了解 <a href="#ril-comm-scenarios">RIL 通信示例情景</a>部分所述的 RIL 通信示例情景。</li>
+
+<li>修改用于处理 RIL 应求请求和自发请求的代码,按照示例情景中的解决方法说明操作。</li>
+</ol>
+
+<h4 id="ril-comm-scenarios">RIL 通信示例情景</h4>
+
+<p>要详细了解如何实施以下图表中使用的函数,请参阅 <code>ril.cpp</code> 的源代码:<code>acquireWakeLock()</code>、<code>decrementWakeLock()</code>、<code>clearWakeLock(</code>)</p>
+
+<h5>示例情景 1:来自 Java API 的 RIL 请求和针对该请求的应求异步响应</h5>
+
+<p><img src="images/ril-refactor-scenario-1.png"/></p>
+
+<h6>问题</h6>
+
+<p>如果 RIL 应求响应预计需要花费相当长的时间(例如,<code>RIL_REQUEST_GET_AVAILABLE_NETWORKS</code>),则唤醒锁定会在应用处理器端保持较长时间,这是一个问题。此外,调制解调器问题也会导致长时间的等待。</p>
+
+<h6>解决方案第 1 部分</h6>
+
+<p>在这种示例情景下,调制调解器代码会保持相应的唤醒锁定状态(RIL 请求和返回的异步响应)。</p>
+
+<p><img src="images/ril-refactor-scenario-1-solution-1.png"/></p>
+
+<p>如以上循序图所示:</p>
+
+<ol>
+<li>RIL 请求已发送,调制解调器需要获取唤醒锁定来处理请求。</li>
+
+<li>调制解调器代码会发送确认信息,这会导致 Java 端的唤醒锁定计数器的数值递减;如果唤醒锁定计数器的值为 0,则还会释放唤醒锁定。</li>
+
+<li>调制解调器处理请求后,会向供应商代码发送一个中断,该代码会获取唤醒锁定并向 ril.cpp 发送响应。随后,ril.cpp 会获取唤醒锁定并向 Java 端发送响应。</li>
+
+<li>当响应到达 Java 端时,Java 会获取唤醒锁定,并将响应发送回至调用程序。</li>
+
+<li>该响应经过所有模块处理后,系统会通过一个套接字将确认信息发送回 <code>ril.cpp</code>。随后,<code>ril.cpp</code> 会释放第 3 步中获取的唤醒锁定。</li>
+</ol>
+
+<p>请注意,由于确认信息很快就可以返回,因此请求确认序列的唤醒锁定超时时长应短于当前使用的超时时长。</p>
+
+<h6>解决方案第 2 部分</h6>
+
+<p>在这种示例情景下,调制调解器不会保持唤醒锁定,且响应会很快返回(同步 RIL 请求和响应)。</p>
+
+<p><img src="images/ril-refactor-scenario-1-solution-2.png"/></p>
+
+<p>如以上循序图所示:</p>
+
+<ol>
+<li>通过在 Java 端调用 <code>acquireWakeLock()</code> 发送 RIL 请求。</li>
+
+<li>供应商代码不需要获取唤醒锁定,且可快速处理请求并返回响应。</li>
+
+<li>当 Java 端收到响应时,会调用 <code>decrementWakeLock()</code>;这样一来,唤醒锁定计数器的数值便会减少,如果其值为 0,则还会释放唤醒锁定。</li>
+</ol>
+
+<p>请注意,此同步与异步行为已针对特定 RIL 命令按逐个调用进行硬编码。</p>
+
+<h5>示例情景 2:RIL 自发响应</h5>
+
+<p><img src="images/ril-refactor-scenario-2.png"/></p>
+
+<p>如上图所示,RIL 自发响应会在响应中标有唤醒锁定类型标记,该标记指明了是否需要针对特定响应(从供应商处接收)获取唤醒锁定。如果响应中标有标记,则系统会设置一个定时唤醒锁定,并会通过套接字将响应发送至 Java 端。当定时器到期时,系统会释放唤醒锁定。</p>
+
+<h6>问题</h6>
+
+<p>对于不同的 RIL 自发响应而言,示例情景 2 中阐述的定时唤醒锁定可能会过长或过短。</p>
+
+<h6>解决方案</h6>
+
+<p><img src="images/ril-refactor-scenario-2-solution.png"/></p>
+
+<p>如图所示,通过以下方法便可以解决该问题:从相应的 Java 代码将确认信息发送至本机端 (<code>ril.cpp</code>),而不是在发送自发响应时在本机端保持定时唤醒锁定。</p>
+
+<h2 id="validation">验证</h2>
+
+<p>下文介绍了如何验证 RIL 重构功能的子功能是否已实现。</p>
+
+<h3 id="validate-error">验证增强的 RIL 错误代码</h3>
+
+<p>添加新的错误代码来替换 <code>GENERIC_FAILURE</code> 代码后,请确保新的错误代码由 RIL 调用(而非 <code>GENERIC_FAILURE</code>)返回。</p>
+
+<h3 id="validate-version">验证增强的 RIL 版本管理</h3>
+
+<p>确保您的 RIL 代码对应的 RIL 版本在 <code>ril.h</code> 中定义的 <code>RIL_REGISTER</code> 期间(而非 <code>RIL_VERSION</code> 期间)返回。</p>
+
+<h3 id="validate-wakelocks">验证重新设计的唤醒锁定</h3>
+
+<p>验证 RIL 调用已被识别为“同步”还是“异步”。</p>
+
+<p>由于电池耗电量可能因硬件/平台而异,因此供应商应进行一些内部测试,以确定针对异步调用使用新的唤醒锁定语义是否可以节省电量。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/dalvik/configure.html b/zh-cn/devices/tech/dalvik/configure.html
new file mode 100644
index 00000000..9d7dfb19
--- /dev/null
+++ b/zh-cn/devices/tech/dalvik/configure.html
@@ -0,0 +1,285 @@
+<html devsite><head>
+ <title>配置 ART</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>本文讨论如何配置 ART 及其编译选项。本文涉及的主题包括系统映像的预编译配置、首次启动时(及 OTA 后)的 dex2oat 编译选项,以及如何在系统分区空间、数据分区空间和性能三者之间取得平衡。</p>
+
+<p>请参阅 <a href="http://source.android.com/devices/tech/dalvik/index.html">ART 与 Dalvik</a>、<a href="http://source.android.com/devices/tech/dalvik/dex-format.html">Dalvik 可执行文件格式</a>以及 source.android.com 上的其他页面,了解如何使用 ART。请参阅<a href="http://developer.android.com/guide/practices/verifying-apps-art.html">在 Android Runtime (ART) 上验证应用行为</a>,确保您的应用运行正常。</p>
+
+<h2 id="how_art_works">ART 的工作原理</h2>
+
+<p>ART 是面向 Android 5.0(Lollipop 或 L)版本及更高版本推出的新 Android 运行时。Dalvik 将不再可用。</p>
+
+<p>请注意,本节仅简要介绍 ART 的配置。如需深入了解,请参阅 2014 年 Google I/O 大会上有关 <a href="https://www.google.com/events/io/io14videos/b750c8da-aebe-e311-b297-00155d5066d7">Android Runtime</a> 的演示内容。</p>
+
+<p>ART 采用预先 (AOT) 编译的方法。这意味着,在安装时,dex 代码会被编译为 OAT 文件中的原生代码,并替换 Dalvik 的 odex 文件。这种做法有以下几点意义:</p>
+
+<ul>
+ <li>与 Dalvik 相比,性能得到了提高。在实验室中测得的能耗也有相应的改善。
+ </li><li>没有运行时代码缓存。OAT 文件被映射到内存(因此可分页)。从 Proportional Set Size(简称 PSS,或各进程之间平均共享的内存)来看,OAT 文件占用的 RAM 内存似乎更大了。不过,我们发现,由于 OAT 文件可分页,而 Dalvik JIT 缓存不可分页,因此就实际内存压力而言,对系统的影响反而有所减轻。
+ </li><li>与 zygote 中的预加载类相似,ART 在编译时会尝试预先初始化一组类。这会创建一个“boot.art”文件,其中包含预先初始化的类和相关对象的压缩堆的映像。此文件会在 zygote 启动时映射到内存中。尽管这会占用额外的存储空间(通常为 10MB),但它可以加快 zygote 的启动,并可以创造机会,让系统在内存压力较大的情况下能够交换出某些预先加载的类。此外,这还有助于改善 ART 的<a href="http://source.android.com/devices/tech/config/low-ram.html">低 RAM</a> 性能,因为在 Dalvik 中,大部分此类信息都存储在线性分配空间的脏页中。
+ </li><li>Dex 文件编译使用名为 dex2oat 的工具,比 dexopt 更耗时。所增加的时间各有不同,但是编译时间增加 2-3 倍的情况并不少见。例如,使用 dexopt 通常只需 1 秒就能安装的应用,如果使用 dex2oat,则可能需要 2-3 秒。
+ </li><li>如果启用全编译,则 OAT 文件比 odex 文件大。我们会在本文档的后面部分讨论降低此成本的选项。
+</li></ul>
+
+<h2 id="compilation_options">编译选项</h2>
+
+<p>与 dexopt 相比,Dex 文件编译需要更多时间,特别是在首次启动(恢复出厂设置或接收 OTA 后)过程中必须编译用户的所有应用时,这一点尤为明显。为了减少所需的编译量,ART 支持对系统分区中的库和应用进行预先优化的选项。纳入预先优化的 dex 文件会占用系统映像的空间。因此,这些选项实际是以牺牲首次启动时间来换取系统映像大小。请注意,OTA 相对而言不是太频繁,并且之后的启动时间,无论是否进行预先优化,都应该是相同的。</p>
+
+<h3 id="undefined">WITH_DEXPREOPT</h3>
+
+<p>预先优化由构建选项 <code>WITH_DEXPREOPT</code> 控制。在 L 版本之前,该选项在“用户”构建中默认启用。自 L 版本起,该选项为选择启用的选项,需要在产品配置(如设备的 BoardConfig.mk 文件)中启用。</p>
+
+<p>启用 <code>WITH_DEXPREOPT</code> 会导致对系统映像中的所有内容进行预先优化。如果这会导致系统映像过大,则可以指定其他选项来减少预先优化量。请注意,以下名称中带有“PREOPT”的所有构建选项都必须启用 <code>WITH_DEXPREOPT</code> 才能工作。</p>
+
+<p>使用示例(在产品的 BoardConfig.mk 中):</p>
+
+<pre><code>WITH_DEXPREOPT := true</code></pre>
+
+<h3 id="dont_dexpreopt_prebuilts">DONT_DEXPREOPT_PREBUILTS</h3>
+
+<p>启用 <code>DONT_DEXPREOPT_PREBUILTS</code> 可防止对预构建进行预先优化。这些都是在其 Android.mk 中指定了 <code>include $(BUILD_PREBUILT)</code> 的应用,例如 Gmail。跳过对可能通过 Google Play 进行更新的预构建应用的预先优化,可以节省 /system 空间,但是会增加首次启动的时间。</p>
+
+<p>使用示例(在产品的 BoardConfig.mk 中):</p>
+
+<pre><code>WITH_DEXPREOPT := true
+DONT_DEXPREOPT_PREBUILTS := true</code></pre>
+
+<h3 id="with_dexpreopt_boot_img_only">WITH_DEXPREOPT_BOOT_IMG_ONLY</h3>
+
+<p>启用 <code>WITH_DEXPREOPT_BOOT_IMG_ONLY</code> 只会预先优化启动映像。启动映像由含有映像类的 boot.art 和含有启动相关的类路径代码的 boot.oat 组成。启用该选项可大幅节省 /system 空间,但也意味着在首次启动时会对所有应用进行优化。通常情况下,最好通过 <code>DONT_DEXPREOPT_PREBUILTS</code> 或 add-product-dex-preopt-module-config 选择性地停用应用预先优化功能。</p>
+
+<p>使用示例(在产品的 BoardConfig.mk 中):</p>
+
+<pre><code>WITH_DEXPREOPT := true
+WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre>
+
+<h3 id="local_dex_preopt">LOCAL_DEX_PREOPT</h3>
+
+<p>通过在模块定义中指定 <code>LOCAL_DEX_PREOPT</code> 选项,还可以基于单个应用启用或停用预先优化功能。这有助于停用对于可能会立即收到 Google Play 更新的应用的预先优化,因为更新会在已过时的系统映像中执行预先优化的代码。此外,这还有助于节省主要版本升级 OTA 的空间,因为用户的数据分区中可能已经有了较新版本的应用。</p>
+
+<p><code>LOCAL_DEX_PREOPT</code> 支持通过值“true”和“false”分别表示启用和停用预先优化。此外,如果预先优化不应将 classes.dex 文件从 apk 或 jar 文件中剥离,还可以指定“nostripping”。通常情况下,此文件会被剥离,因为预先优化之后便不再需要该文件;但若要使第三方 APK 签名保持有效状态,则最后一个选项必不可少。</p>
+
+<p>使用示例(在应用的 Android.mk 中):</p>
+
+<pre><code>LOCAL_DEX_PREOPT := false</code></pre>
+
+<h3 id="product_dex_preopt_*">PRODUCT_DEX_PREOPT_*</h3>
+
+<p>自 L 之后的 Android 开放源代码项目 (AOSP) 版本起,我们已添加了大量标记,以进一步控制预先优化的执行方式。<code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code> 将选项传递给 dex2oat 以控制启动映像的编译方式。该选项可用于指定自定义映像类列表、已编译类的列表和编译器过滤器,这些内容将在下文进行介绍。同样,<code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS</code> 控制传递给 dex2oat 的默认标记,以编译除启动映像之外的所有文件,即 jar 和 apk 文件。</p>
+
+<p>通过 <code>PRODUCT_DEX_PREOPT_MODULE_CONFIGS</code>,可为特定模块和产品配置传递 dex2oat 选项。这通过 <code>$(call
+add-product-dex-preopt-module-config,&lt;modules&gt;,&lt;option&gt;)</code> 在产品的 device.mk 文件中进行设置,其中 &lt;modules&gt; 为 jar 和 apk 文件各自的 <code>LOCAL_MODULE</code> 和 <code>LOCAL_PACKAGE</code> 名称的列表。借助此标记,可以对每个 dex 文件和特定设备的预先优化进行精细控制。此类微调可让 /system 空间最大限度地用于改进首次启动时间。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only
+$(call add-product-dex-preopt-module-config,services,--compiler-filter=space)</code></pre>
+
+<p>通过在产品的 device.mk 文件中指定 <code>$(call
+add-product-dex-preopt-module-config,&lt;modules&gt;,disable)</code>,这些标记还可用于选择性地停用特定模块或软件包的预先优化。</p>
+
+<p>使用示例(产品的 device.mk 中):</p>
+
+<pre><code>$(call add-product-dex-preopt-module-config,Calculator,disable)</code></pre>
+
+<h2 id="other_odex">DEX_PREOPT 文件的首次启动安装</h2>
+
+<p>自 Android 7.0 起,设备可以使用两个系统分区来启用 <a href="/devices/tech/ota/ab_updates.html">A/B 系统更新</a>。要想在控制系统分区大小和实现高效首次启动的同时允许使用 DEX_PREOPT,可以将预选文件安装在未使用的第二个系统分区中。这些文件会在首次启动时被复制到数据分区。</p>
+
+<p>使用示例(在 device-common.mk 中):</p>
+
+<pre><code>PRODUCT_PACKAGES += \
+ cppreopts.sh
+PRODUCT_PROPERTY_OVERRIDES += \
+ ro.cp_system_other_odex=1
+</code></pre>
+
+<p>在设备的 BoardConfig.mk 中:</p>
+<pre><code>BOARD_USES_SYSTEM_OTHER_ODEX := true</code></pre>
+
+<p>如需在系统映像中选择性地包含编译脚本和二进制文件,请参阅<a href="/devices/tech/ota/ab_updates.html#compilation">后台中的应用编译</a>。</p>
+
+<h2 id="preloaded_classes_list">预加载类列表</h2>
+
+<p>预加载类列表是 zygote 将在启动时初始化的一个类列表。通过该列表,每个应用无需单独运行这些类初始化程序,从而可以更快地启动并共享内存中的页面。预加载类列表文件默认位于 frameworks/base/preloaded-classes 中,其中包含一个针对典型的手机用途微调的列表。这可能不适用于其他设备(如穿戴式设备),而应进行相应的微调。做微调时应格外小心,因为添加太多的类会造成加载不使用的类而浪费内存;而添加的类太少又会导致每个应用都必须拥有自己的副本,同样会造成内存浪费。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>PRODUCT_COPY_FILES += &lt;filename&gt;:system/etc/preloaded-classes</code></pre>
+
+<p class="note"><strong>注意</strong>:必须将此行放置于沿用任何从 build/target/product/base.mk 中获得默认值的产品配置 makefile 之前。</p>
+
+<h2 id="image_classes_list">映像类列表</h2>
+
+<p>映像类列表是 dex2oat 预先初始化并存储在 boot.art 文件中的类列表。通过该列表,zygote 可以在启动时从 boot.art 文件中加载这些结果,而无需在预加载期间自行运行这些类的初始化程序。其中一个重要特点是,从映像加载并在进程之间共享的页面是干净的,因此可在内存不足的情况下轻松将它们交换出去。在 L 版本中,默认情况下,映像类列表和预加载类列表使用同一个列表。自 L 之后的 AOSP 版本起,可以使用 <code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code> 指定自定义映像类。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>PRODUCT_DEX_PREOPT_BOOT_FLAGS += --image-classes=&lt;filename&gt;</code></pre>
+
+<h2 id="compiled_classes_list">已编译类的列表</h2>
+
+<p>在 L 之后的 AOSP 版本中,可以指定使用已编译类的列表,在预先优化期间编译来自启动的类路径的类子集。对于空间非常紧张且无法满足整个预先优化启动映像需求的设备来说,此选项很有帮助。不过,请注意,此列表未指定的类将不会被编译(即使在设备上也不会被编译),且必须对其进行解释,这可能会影响运行时性能。默认情况下,dex2oat 会在 $OUT/system/etc/compiled-classes 中查找已编译类的列表,因此,可以通过 device.mk 将自定义的类列表复制到该位置。此外,还可以使用 <code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code> 指定特定文件位置。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>PRODUCT_COPY_FILES += &lt;filename&gt;:system/etc/compiled-classes</code></pre>
+
+<p class="note"><strong>注意</strong>:必须将此行放置于沿用任何从 build/target/product/base.mk 中获得默认值的产品配置 makefile 之前。</p>
+
+<h2 id="compiler_filters">编译器过滤器</h2>
+
+<p>在 L 版本中,dex2oat 通过各种编译器过滤器选项来控制其编译方式。传递特定应用的编译器过滤器标记可指定其预先优化的方式。下面对各个可用选项进行了说明:</p>
+
+<ul>
+ <li>everything - 编译几乎所有内容,但太大以致无法通过编译器的内部表示法进行表示的类初始化程序及一些罕见的方法除外。<em></em>
+ </li><li>speed - 编译大多数方法并尽可能提升运行时性能,这是默认选项。<em></em>
+ </li><li>balanced - 尝试在编译投入上获得最佳性能回报。<em></em>
+ </li><li>space - 编译有限数量的方法,并优先编译存储空间相关的部分。<em></em>
+ </li><li>interpret-only - 跳过所有编译并依靠解释器来运行代码。<em></em>
+ </li><li>verify-none - 跳过验证和编译的特殊选项,应仅用于可信系统代码。<em></em>
+</li></ul>
+
+<h2 id="with_dexpreopt_pic">WITH_DEXPREOPT_PIC</h2>
+
+<p>在 Android 5.1.0 到 Android 6.0.1 的版本中,可以指定 <code>WITH_DEXPREOPT_PIC</code> 以启用位置无关代码 (PIC)。这样一来,就不必将来自映像的编译代码从 /system 迁移到 /data/dalvik-cache,因此可以节省数据分区中的空间。不过,因为该选项会停用利用位置相关代码进行的优化,所以会对运行时产生轻微的影响。通常情况下,需要节省 /data 空间的设备应启用 PIC 编译。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>WITH_DEXPREOPT := true
+WITH_DEXPREOPT_PIC := true</code></pre>
+
+<p>自 Android 7.0 起,PIC 编译默认处于启用状态。</p>
+
+<h2 id="with_art_small_mode">WITH_ART_SMALL_MODE</h2>
+
+<p>对于空间非常有限的设备,可以启用 <code>WITH_ART_SMALL_MODE</code>。此选项仅编译启动相关的类路径,由于跳过了大多数编译,因此可以大大缩短首次启动时间。此选项还可以节省存储空间,因为没有针对应用的编译代码。但是,由于必须解释应用代码,因此这会影响运行时性能。不过,由于仍会编译框架中的大部分性能敏感型代码,因此对运行时性能的影响非常有限,但是在基准化分析中的表现可能会出现退化的情况。</p>
+
+<p>使用示例(在产品的 device.mk 中):</p>
+
+<pre><code>WITH_ART_SMALL_MODE := true</code></pre>
+
+<p>在未来的版本中,该选项可以通过以下代码(在产品的 device.mk 中)来实现,因此会将其移除:</p>
+
+<pre><code>PRODUCT_PROPERTY_OVERRIDES += \
+ dalvik.vm.dex2oat-filter=interpret-only \
+ dalvik.vm.image-dex2oat-filter=speed</code></pre>
+
+<h2 id="dalvik_vm_properties">dalvik.vm 属性</h2>
+
+<p>ART 中的大多数 dalvik.vm 属性都与 Dalvik 类似,但是新增了以下属性。请注意,这些选项在设备编译期间和预先优化期间都会影响 dex2oat,但是前面讨论的大多数选项只会影响预先优化。</p>
+
+<p>在 dex2oat 编译启动映像时对其进行控制:</p>
+
+<ul>
+ <li>dalvik.vm.image-dex2oat-Xms:初始堆大小</li><li>dalvik.vm.image-dex2oat-Xmx:最大堆大小</li><li>dalvik.vm.image-dex2oat-filter:编译器过滤器选项</li><li>dalvik.vm.image-dex2oat-threads:要使用的线程数</li></ul>
+
+<p>在 dex2oat 编译除启动映像之外的所有内容时对其进行控制:</p>
+
+<ul>
+ <li>dalvik.vm.dex2oat-Xms:初始堆大小</li><li>dalvik.vm.dex2oat-Xmx:最大堆大小</li><li>dalvik.vm.dex2oat-filter:编译器过滤器选项</li></ul>
+
+<p>Android 6.0 之前的版本提供了一个适用于编译除启动映像之外的所有内容的附加选项:</p>
+<ul>
+ <li>dalvik.vm.dex2oat-threads:要使用的线程数</li></ul>
+
+<p>自 Android 6.1 起,该选项变成了两个适用于编译除启动映像之外的所有内容的附加选项:</p>
+<ul>
+ <li>dalvik.vm.boot-dex2oat-threads:启动时要使用的线程数</li><li>dalvik.vm.dex2oat-threads:启动后要使用的线程数</li></ul>
+
+<p>Android 7.1 及之后的版本提供了两个选项来控制编译除启动映像之外的所有内容时的内存使用方式:</p>
+<ul>
+ <li>dalvik.vm.dex2oat-very-large:停用 AOT 编译的最小总 dex 文件大小(以字节为单位)</li><li>dalvik.vm.dex2oat-swap:使用 dex2oat 交换文件(用于低内存设备)</li></ul>
+
+<p>控制 dex2oat 的初始堆大小和最大堆大小的选项,可以限制可对哪些应用进行编译,因此不应被减少。</p>
+
+<h2 id="sample_usage">使用示例</h2>
+
+<p>这些编译器选项的目标是通过利用系统和数据分区中的可用空间,来减少必须由设备执行的 dex2oat 的数量。</p>
+
+<p>如果设备具有充足的系统和数据空间,则启用 dex 预先优化十分必要。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true</code></pre>
+
+<p>如果这导致系统映像变得过大,可以尝试停用预构建的预先优化。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true
+DONT_DEXPREOPT_PREBUILTS := true</code></pre>
+
+<p>如果系统映像仍然很大,则可以尝试仅对启动映像进行预先优化。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true
+WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre>
+
+<p>不过,如果仅对启动映像进行预先优化,那么所有的应用就只能在首次启动时优化。为了避免出现这种情况,可以将这些高级标记与更精细的控件结合使用,以期预先优化尽可能多的应用。</p>
+
+<p>例如,如果停用对预构建的预先优化可以达到基本适合系统分区,则通过“space”选项编译启动相关的类路径就可以达到完全适合。请注意,这会减少编译启动相关的类路径中的方法,因此有可能会解释更多代码,进而影响运行时性能。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true
+DONT_DEXPREOPT_PREBUILTS := true</code></pre>
+
+<p>device.mk:</p>
+
+<pre><code>PRODUCT_DEX_PREOPT_BOOT_FLAGS := --compiler-filter=space</code></pre>
+
+<p>如果设备的系统分区空间非常有限,则可以使用已编译类列表编译启动相关的类路径中的类子集。因为必须对未包含在此列表中的启动相关的类路径方法进行解释,所以可能会影响运行时性能。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true
+WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre>
+
+<p>device.mk:</p>
+
+<pre><code>PRODUCT_COPY_FILES += &lt;filename&gt;:system/etc/compiled-classes</code></pre>
+
+<p>如果设备的系统分区空间和数据分区空间都很有限,则可以使用编译器过滤器标记来停用对某些应用的编译。在这种情况下,由于不会有任何编译代码,因此会节省系统和数据分区的空间,但是必须对这些应用进行解释。此示例配置会预先优化启动相关的类路径,但会阻止编译不属于预构建的其他应用。不过,为了防止 system_server 出现明显的性能下降,仍会对 services.jar 进行编译,但对空间占用进行了优化。请注意,用户安装的应用仍将使用默认的 speed 编译器过滤器。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true
+DONT_DEXPREOPT_PREBUILTS := true</code></pre>
+
+<p>device.mk:</p>
+
+<pre><code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only
+$(call add-product-dex-preopt-module-config,services,--compiler-filter=space)</code></pre>
+
+<p>对于主要版本升级 OTA,由于某些应用可能已过期,因此将它们添加到黑名单以避免对其进行预先优化,会非常有帮助。可以通过指定 <code>LOCAL_DEX_PREOPT</code>(针对所有产品)或使用 <code>PRODUCT_DEX_PREOPT_MODULE_CONFIGS</code>(针对特定产品)来实现。
+
+</p><p>BoardConfig.mk:</p>
+
+<pre><code>WITH_DEXPREOPT := true</code></pre>
+
+<p>Android.mk(已添加到黑名单的应用):</p>
+
+<pre><code>LOCAL_DEX_PREOPT := false</code></pre>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/dalvik/constraints.html b/zh-cn/devices/tech/dalvik/constraints.html
new file mode 100644
index 00000000..70751e54
--- /dev/null
+++ b/zh-cn/devices/tech/dalvik/constraints.html
@@ -0,0 +1,532 @@
+<html devsite><head>
+ <title>约束</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><code>.dex</code> 文件是 Dalvik 字节码的传输格式。要成为有效的 <code>.dex</code> 文件,文件必须在语法和语义上受到一定的约束;此外,要仅支持有效的 .dex 文件,还需要运行时。</p>
+
+ <h2 id="gen-constraints">.dex 的一般完整性约束</h2>
+
+ <p>一般完整性约束涉及较大结构的 <code>.dex</code> 文件,详见 <a href="dex-format.html"><code>.dex</code> 格式</a>。</p>
+
+ <table>
+ <tbody><tr>
+ <th>标识符</th>
+
+ <th>说明</th>
+ </tr>
+
+ <tr>
+ <td>G1</td>
+
+ <td><code>.dex</code> 文件的 <code>magic</code> 数值必须是 <code>dex\n035\0</code> 或 <code>dex\n037\0</code>。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G2</td>
+
+ <td>校验和必须是除了 <code>magic</code> 和 <code>checksum</code> 字段之外的整个文件内容的 Adler-32 校验和。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G3</td>
+
+ <td>签名必须是除了 <code>magic</code>、<code>checksum</code> 和 <code>signature</code> 之外的整个文件内容的 SHA-1 哈希值。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G4</td>
+
+ <td><code>file_size</code> 必须与实际文件大小(以字节为单位)相匹配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G5</td>
+
+ <td><code>header_size</code> 的值必须为 <code>0x70</code>
+ </td>
+ </tr>
+
+ <tr>
+ <td>G6</td>
+
+ <td><code>endian_tag</code> 的值必须为 <code>ENDIAN_CONSTANT</code> 或 <code>REVERSE_ENDIAN_CONSTANT</code>
+ </td>
+ </tr>
+
+ <tr>
+ <td>G7</td>
+
+ <td>对于 <code>link</code>、<code>string_ids</code>、<code>type_ids</code>、<code>proto_ids</code>、<code>field_ids</code>、<code>method_ids</code>、<code>class_defs</code> 和 <code>data</code> 各区段,<code>offset</code> 和 <code>size</code> 字段必须都为零或都为非零。在后一种情况下,偏移必须四字节对齐。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G8</td>
+
+ <td>标头中除 <code>map_off</code> 之外的所有偏移字段都必须四字节对齐。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G9</td>
+
+ <td><code>map_off</code> 字段必须为零或指向数据区段。在后一种情况下,<code>data</code> 区段必须存在。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G10</td>
+
+ <td><code>link</code>、<code>string_ids</code>、<code>type_ids</code>、<code>proto_ids</code>、<code>field_ids</code>、<code>method_ids</code>、<code>class_defs</code> 和 <code>data</code> 区段都不得彼此重叠或者与标头重叠。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G11</td>
+
+ <td>如果存在映射,则每个映射条目都必须具有有效的类型。每种类型最多可以出现一次。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G12</td>
+
+ <td>如果存在映射,则每个映射条目必须具有非零偏移和大小。偏移必须指向文件的相应区段(即,<code>string_id_item</code> 必须指向 <code>string_ids</code> 区段),并且项的显式或隐式大小必须与该区段的实际内容和大小相匹配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G13</td>
+
+ <td>如果存在映射,则映射条目 <code>n+1</code> 的偏移量必须大于或等于映射条目 <code>n plus than size of map entry n</code> 的偏移量。这意味着条目互不重叠且从低到高排序。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G14</td>
+
+ <td>以下类型的条目必须具有四字节对齐的偏移量:<code>string_id_item</code>、<code>type_id_item</code>、<code>proto_id_item</code>、<code>field_id_item</code>、<code>method_id_item</code>、<code>class_def_item</code>、<code>type_list</code>、<code>code_item</code>、<code>annotations_directory_item</code>。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G15</td>
+
+ <td>对于每个 <code>string_id_item</code>,<code>string_data_off</code> 字段必须包含对 <code>data</code> 区段的有效引用。对于引用的 <code>string_data_item</code>,<code>data</code> 字段必须包含有效的 MUTF-8 字符串,并且 <code>utf16_size</code> 必须与字符串的解码长度相匹配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G16</td>
+
+ <td>对于每个 <code>type_id_item</code>,<code>descriptor_idx</code> 字段必须包含对 <code>string_ids</code> 列表的有效引用。引用的字符串必须是有效的类型描述符。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G17</td>
+
+ <td>对于每个 <code>proto_id_item</code>,<code>shorty_idx</code> 字段必须包含对 <code>string_ids</code> 列表的有效引用。引用的字符串必须是有效的短描述符。此外,<code>return_type_idx</code> 字段必须是 <code>type_ids</code> 区段的有效索引,并且 <code>parameters_off</code> 字段必须为零或指向 <code>data</code> 区段的有效偏移量。如果为非零,则参数列表不得包含任何空白条目。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G18</td>
+
+ <td>对于每个 <code>field_id_item</code>,<code>class_idx</code> 和 <code>type_idx</code> 字段都必须是 <code>type_ids</code> 列表的有效索引。<code>class_idx</code> 引用的条目必须是非数组引用类型。此外,<code>name_idx</code> 字段必须是对 <code>string_ids</code> 区段的有效引用,且引用条目的内容必须符合 <code>MemberName</code> 规范。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G19</td>
+
+ <td>对于每个 <code>method_id_item</code>,<code>class_idx</code> 字段必须是 <code>type_ids</code> 区段的有效索引,且引用的条目必须是非数组引用类型。<code>proto_id</code> 字段必须是对 <code>proto_ids</code> 列表的有效引用。<code>name_idx</code> 字段必须是对 <code>string_ids</code> 区段的有效引用,且引用条目的内容必须符合 <code>MemberName</code> 规范。
+ </td>
+ </tr>
+
+ <tr>
+ <td>G20</td>
+
+ <td>对于每个 <code>field_id_item</code>,<code>class_idx</code> 字段必须是 <code>type_ids</code> 列表的有效索引。引用的条目必须是非数组引用类型。
+ </td>
+ </tr>
+
+</tbody></table>
+
+<h2 id="static-constraints">静态字节码约束</h2>
+
+ <p>静态约束是对字节码的各个元素的约束。通常,可以在不使用控制或数据流分析技术的情况下检查这类约束。
+ </p>
+
+ <table>
+ <tbody><tr>
+ <th>标识符</th>
+
+ <th>说明</th>
+ </tr>
+
+ <tr>
+ <td>A1</td>
+
+ <td><code>insns</code> 数组不能为空。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A2</td>
+
+ <td><code>insns</code> 数组中第一个运算码的索引必须为零。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A3</td>
+
+ <td><code>insns</code> 数组必须只包含有效的 Dalvik 运算码。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A4</td>
+
+ <td>指令 <code>n+1</code> 的索引必须等于指令 <code>n</code> 的索引加上指令 <code>n</code> 的长度,同时要考虑可能的运算数。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A5</td>
+
+ <td><code>insns</code> 数组中最后一条指令必须以索引 <code>insns_size-1</code> 结尾。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A6</td>
+
+ <td>所有 <code>goto</code> 和 <code>if-&lt;kind&gt;</code> 目标必须是同一方法中的运算码。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A7</td>
+
+ <td><code>packed-switch</code> 指令的所有目标必须是同一方法中的运算码。目标的大小和列表必须一致。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A8</td>
+
+ <td><code>sparse-switch</code> 指令的所有目标必须是同一方法中的运算码。相应的表必须一致,并从低到高排序。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A9</td>
+
+ <td><code>const-string</code> 和 <code>const-string/jumbo</code> 指令的 <code>B</code> 运算数必须是字符串常量池中的有效索引。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A10</td>
+
+ <td><code>iget&lt;kind&gt;</code> 和 <code>iput&lt;kind&gt;</code> 指令的 <code>C</code> 运算数必须是字段常量池中的有效索引。引用的条目必须表示一个实例字段。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A11</td>
+
+ <td><code>sget&lt;kind&gt;</code> 和 <code>sput&lt;kind&gt;</code> 指令的 <code>C</code> 运算数必须是字段常量池中的有效索引。引用的条目必须表示静态字段。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A12</td>
+
+ <td><code>invoke-virtual</code>、<code>invoke-super</code>、<code>invoke-direct</code> 和 <code>invoke-static</code> 指令的 <code>C</code> 运算数必须是方法常量池中的有效索引。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A13</td>
+
+ <td><code>invoke-virtual/range</code>、<code>invoke-super/range</code>、<code>invoke-direct/range</code> 和 <code>invoke-static/range</code> 指令的 <code>B</code> 运算数必须是方法常量池中的有效索引。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A14</td>
+
+ <td>名称以“&lt;”开头的方法只能由 VM 隐式调用,而不能由 <code>.dex</code> 文件生成的代码调用。唯一的例外是实例初始化程序,它可以由 <code>invoke-direct</code> 调用。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A15</td>
+
+ <td><code>invoke-interface</code> 指令的 <code>C</code> 运算数必须是方法常量池中的有效索引。引用的 <code>method_id</code> 必须属于接口(而非类)。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A16</td>
+
+ <td><code>invoke-interface/range</code> 指令的 <code>B</code> 运算数必须是方法常量池中的有效索引。引用的 <code>method_id</code> 必须属于接口(而非类)。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A17</td>
+
+ <td><code>const-class</code>、<code>check-cast</code>、<code>new-instance</code> 和 <code>filled-new-array/range</code> 指令的 <code>B</code> 运算数必须是类型常量池中的有效索引。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A18</td>
+
+ <td><code>instance-of</code>、<code>new-array</code> 和 <code>filled-new-array</code> 指令的 <code>C</code> 运算数必须是类型常量池中的有效索引。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A19</td>
+
+ <td>由 <code>new-array</code> 指令创建的数组维数必须小于 <code>256</code>。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A20</td>
+
+ <td><code>new</code> 指令不得引用数组类、接口和抽象类。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A21</td>
+
+ <td><code>new-array</code> 指令引用的类型必须是有效的非引用类型。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A22</td>
+
+ <td>指令以单精度宽度(非值对)方式形式引用的所有寄存器必须对当前方法有效。也就是说,它们的索引必须是非负数,并且小于 <code>registers_size</code>。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A23</td>
+
+ <td>指令以双精度宽度(值对)形式引用的所有寄存器必须对当前方法有效。也就是说,它们的索引必须是非负数,并且小于 <code>registers_size-1</code>。
+ </td>
+ </tr>
+ <tr>
+ <td>A24</td>
+
+ <td><code>invoke-virtual</code> 和 <code>invoke-direct</code> 指令的 <code>method_id</code> 运算数必须属于一个类(而不是一个接口)。在版本 <code>037</code> 之前的 Dex 文件中,<code>invoke-super</code> 和 <code>invoke-static</code> 指令也是如此。
+ </td>
+ </tr>
+
+ <tr>
+ <td>A25</td>
+
+ <td><code>invoke-virtual/range</code> 和 <code>invoke-direct/range</code> 指令的 <code>method_id</code> 运算数必须属于一个类(而不是一个接口)。在版本 <code>037</code> 之前的 Dex 文件中,<code>invoke-super/range</code> 和 <code>invoke-static/range</code> 指令也是如此。
+ </td>
+ </tr>
+ </tbody></table>
+
+ <h2 id="struct-constraints">结构字节码约束</h2>
+
+ <p>结构约束是对字节码的若干元素之间的关系的约束。通常,无法在不使用控制或数据流分析技术的情况下检查这类约束。
+ </p>
+
+ <table>
+ <tbody><tr>
+ <th>标识符</th>
+
+ <th>说明</th>
+ </tr>
+
+ <tr>
+ <td>B1</td>
+
+ <td>参数(寄存器和立即值)的数量和类型必须始终与指令相匹配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B2</td>
+
+ <td>寄存器对绝不能分解。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B3</td>
+
+ <td>必须先分配寄存器(或寄存器对),然后才能读取。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B4</td>
+
+ <td><code>invoke-direct</code> 指令必须仅在当前类或其一个超类中调用实例初始化程序或方法。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B5</td>
+
+ <td>必须只在未初始化的实例上调用实例初始化程序。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B6</td>
+
+ <td>只能在已初始化的实例上调用实例方法,并且只能在已初始化的实例上访问实例字段。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B7</td>
+
+ <td>如果在实例初始化之前再次执行相同的 <code>new-instance</code> 指令,则不能使用保留 <code>new-instance</code> 指令结果的寄存器。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B8</td>
+
+ <td>实例初始化程序必须调用另一个实例初始化程序(相同的类或超类),然后才能访问任何实例成员。异常是非继承的实例字段,通常可在调用另一个初始化程序和 <code>Object</code> 类之前进行分配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B9</td>
+
+ <td>所有实际的方法参数必须与其各自的形式参数分配兼容。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B10</td>
+
+ <td>对于每个实例方法调用,实际实例必须与指令中指定的类或接口分配兼容。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B11</td>
+
+ <td><code>return&lt;kind&gt;</code> 指令必须与其方法的返回类型相匹配。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B12</td>
+
+ <td>访问超类的受保护成员时,被访问实例的实际类型必须是当前类或它的其中一个子类。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B13</td>
+
+ <td>存储到静态字段中的值的类型必须与字段的类型分配兼容或可转换为字段的类型。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B14</td>
+
+ <td>存储在字段中的值的类型必须与字段的类型分配兼容或可转换为字段的类型。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B15</td>
+
+ <td>存储到数组中的每个值的类型必须与数组的组件类型分配兼容。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B16</td>
+
+ <td><code>throw</code> 指令的 <code>A</code> 运算数必须与 <code>java.lang.Throwable</code> 分配兼容。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B17</td>
+
+ <td>方法的最后一个可访问指令必须是向后的 <code>goto</code> 或分支、<code>return</code> 或 <code>throw</code> 指令。不能将 <code>insns</code> 数组留在底部。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B18</td>
+
+ <td>前一寄存器对中未分配的一半地址可能不会被读取(被视为无效地址),在其他一些指令重新分配之后才会使用。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B19</td>
+
+ <td><code>move-result&lt;kind&gt;</code> 指令之前(在 <code>insns</code> 数组中)必须紧接 <code>invoke-&lt;kind&gt;</code> 指令。唯一的例外情况是 <code>move-result-object</code> 指令,该指令前面也可以接 <code>filled-new-array</code> 指令。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B20</td>
+
+ <td><code>move-result&lt;kind&gt;</code> 指令前面(在实际控制流程中)必须直接是紧接匹配的 <code>return-&lt;kind&gt;</code> 指令(不能跳转到该指令)。唯一的例外情况是 <code>move-result-object</code> 指令,它前面也可以接 <code>filled-new-array</code> 指令。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B21</td>
+
+ <td><code>move-exception</code> 指令必须仅作为异常处理程序中的第一条指令出现。
+ </td>
+ </tr>
+
+ <tr>
+ <td>B22</td>
+
+ <td>控制流不得访问 <code>packed-switch-data</code>、<code>sparse-switch-data</code> 和 <code>fill-array-data</code> 伪指令。
+ </td>
+ </tr>
+ </tbody></table>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/dalvik/index.html b/zh-cn/devices/tech/dalvik/index.html
new file mode 100644
index 00000000..d808ab50
--- /dev/null
+++ b/zh-cn/devices/tech/dalvik/index.html
@@ -0,0 +1,92 @@
+<html devsite><head>
+ <title>ART 和 Dalvik</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 Runtime (ART) 是 Android 上的应用和部分系统服务使用的托管运行时。ART 及其前身 Dalvik 最初是专为 Android 项目打造的。作为运行时的 ART 会执行 Dalvik 可执行文件并遵循 Dex 字节码规范。</p>
+
+<p>ART 和 Dalvik 是运行 Dex 字节码的兼容运行时,因此针对 Dalvik 开发的应用也能在 ART 环境中运作。不过,Dalvik 采用的一些技术并不适用于 ART。有关最重要问题的信息,请参阅<a href="http://developer.android.com/guide/practices/verifying-apps-art.html">在 Android Runtime (ART) 上验证应用行为</a>。</p>
+
+<h2 id="features">ART 功能</h2>
+
+<p>以下是 ART 实现的一些主要功能。</p>
+
+<h3 id="AOT_compilation">预先 (AOT) 编译</h3>
+
+<p>ART 推出了预先 (AOT) 编译,可提高应用的性能。ART 还具有比 Dalvik 更严格的安装时验证。</p>
+
+<p>在安装时,ART 使用设备自带的 <strong>dex2oat</strong> 工具来编译应用。该实用工具接受 <a href="http://source.android.com/devices/tech/dalvik/dex-format.html">DEX</a> 文件作为输入,并针对目标设备生成已编译应用的可执行文件。该实用工具应能够毫不费力地编译所有有效的 DEX 文件。但是,一些后处理工具会生成无效文件,Dalvik 可以接受这些文件,但 ART 无法编译这些文件。有关详情,请参阅<a href="http://developer.android.com/guide/practices/verifying-apps-art.html#GC_Migration">解决垃圾回收问题</a>。</p>
+
+<h3 id="Improved_GC">优化的垃圾回收</h3>
+
+<p>垃圾回收 (GC) 可能会损害应用的性能,从而导致显示不稳定、界面响应速度缓慢以及其他问题。ART 通过以下几种方式优化垃圾回收:</p>
+
+<ul>
+ <li>采用一个而非两个 GC 暂停</li>
+ <li>在 GC 保持暂停状态期间并行处理</li>
+ <li>采用总 GC 时间更短的回收器清理最近分配的短时对象这种特殊情况</li>
+ <li>优化了垃圾回收人机工程学,这样能够更加及时地进行并行垃圾回收,这使得 <a href="http://developer.android.com/tools/debugging/debugging-memory.html#LogMessages"><code>GC_FOR_ALLOC</code></a> 事件在典型用例中极为罕见</li>
+ <li>压缩 GC 以减少后台内存使用和碎片</li>
+</ul>
+
+<h3 id="Debugging_Imp">开发和调试优化</h3>
+
+<p>ART 提供了大量功能来优化应用开发和调试。</p>
+
+<h4 id="Sampling_Profiler">支持采样分析器</h4>
+
+<p>一直以来,开发者都使用 <a href=" http://developer.android.com/tools/help/traceview.html">Traceview</a> 工具(旨在跟踪应用执行)作为分析器。虽然 Traceview 可提供有用的信息,但其根据每次方法调用开销得出的 Dalvik 分析结果会出现偏差,而且使用该工具明显会影响运行时性能。</p>
+
+<p>ART 添加了对没有这些限制的专用采样分析器的支持,从而更准确地了解应用执行情况,而不会明显减慢速度。KitKat 版本为 Dalvik 的 Traceview 添加了采样支持。</p>
+
+<h4 id="Debugging_Features">支持更多调试功能</h4>
+
+<p>ART 支持许多新的调试选项,特别是与监控和垃圾回收相关的功能。例如,您可以:</p>
+
+<ul>
+ <li>查看堆栈跟踪中保留了哪些锁,然后跳转到持有锁的线程。</li>
+ <li>询问指定类的当前活动的实例数、请求查看实例,以及查看使对象保持有效状态的参考。</li>
+ <li>过滤特定实例的事件(如断点)。</li>
+ <li>查看方法退出(使用“method-exit”事件)时返回的值。</li>
+ <li>设置字段观察点,以在访问和/或修改特定字段时暂停程序执行。</li>
+</ul>
+
+<h4 id="Crash_Reports">优化了异常和崩溃报告中的诊断详细信息</h4>
+
+<p>当发生运行时异常时,ART 会为您提供尽可能多的上下文和详细信息。ART 会提供 <code><a href="http://developer.android.com/reference/java/lang/ClassCastException.html">java.lang.ClassCastException</a></code>、<code><a href="http://developer.android.com/reference/java/lang/ClassNotFoundException.html">java.lang.ClassNotFoundException</a></code> 和 <code><a href="http://developer.android.com/reference/java/lang/NullPointerException.html">java.lang.NullPointerException</a></code> 的更多异常详细信息。(更高版本的 Dalvik 提供 <code><a href="http://developer.android.com/reference/java/lang/ArrayIndexOutOfBoundsException.html">java.lang.ArrayIndexOutOfBoundsException</a></code> 和 <code><a href="http://developer.android.com/reference/java/lang/ArrayStoreException.html">java.lang.ArrayStoreException</a></code> 的更多异常详细信息,现在包括数组大小和超出范围的偏移量。同样,ART 也提供此类信息。)</p>
+
+<p>例如,<code><a href="http://developer.android.com/reference/java/lang/NullPointerException.html">java.lang.NullPointerException</a></code> 现在显示有关应用尝试处理 null 指针所进行操作(例如应用尝试写入的字段或尝试调用的方法)的信息。一些典型常见示例如下:</p>
+
+<pre class="no-pretty-print">
+java.lang.NullPointerException: Attempt to write to field 'int
+android.accessibilityservice.AccessibilityServiceInfo.flags' on a null object
+reference</pre>
+
+<pre class="no-pretty-print">
+java.lang.NullPointerException: Attempt to invoke virtual method
+'java.lang.String java.lang.Object.toString()' on a null object reference</pre>
+
+<p>ART 还通过纳入 Java 和原生堆栈信息在应用原生代码崩溃报告中提供优化的上下文信息。</p>
+
+<h2 id="Reporting_Problems">报告问题</h2>
+
+<p>如果您遇到任何并非由应用 JNI 问题导致的问题,请访问 <a href="http://b.android.com">http://b.android.com</a>,通过 Android 开放源代码项目问题跟踪器报告这些问题。请包含 <code>"adb bugreport"</code> 和应用在 Google Play 商店中的链接(如果有)。否则,如果可能,请附加可重现该问题的 APK。请注意,这些问题(包括附件)都是公开可见的。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/datausage/excluding-network-types.html b/zh-cn/devices/tech/datausage/excluding-network-types.html
new file mode 100644
index 00000000..610994ab
--- /dev/null
+++ b/zh-cn/devices/tech/datausage/excluding-network-types.html
@@ -0,0 +1,26 @@
+<html devsite><head>
+ <title>从流量消耗数据中排除特定的网络类型</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>移动运营商可能希望从由设备计算的流量消耗总量中排除特定的网络类型。例如,移动运营商可能想对通过 MMS APN 传送的网络流量进行“零分级”。为了支持达成这一目的,系统已允许在构建时通过 <code>config_data_usage_network_types</code> 资源来配置这组用于计算流量消耗总量的网络类型。</p>
+<p>一些移动无线装置实现可分别为每个有效的 APN 提供一个具有唯一性的 Linux 网络接口,另一些无线装置则可能会强制多个 APN 在同一个接口上共存。对于这两种设计,Android 均可从中收集网络统计信息,但 <code>config_data_usage_network_types</code> 无法有效地排除被强制在同一个接口上共存的 APN。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/datausage/iface-overview.html b/zh-cn/devices/tech/datausage/iface-overview.html
new file mode 100644
index 00000000..8a6e55da
--- /dev/null
+++ b/zh-cn/devices/tech/datausage/iface-overview.html
@@ -0,0 +1,28 @@
+<html devsite><head>
+ <title>网络接口统计信息概览</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 4.0 中,Linux 网络接口所报告的统计信息会不时进行记录,并用于强制执行网络配额限制、呈现用户可见的图表等操作。</p>
+<p>每个网络设备驱动程序(包括 WLAN)都必须遵循标准的内核设备生命周期,并通过 <code>dev_get_stats()</code> 返回正确的统计信息。特别是即便接口处于激活状态时,返回的统计信息也必须严格保持单调统一性。驱动程序可能仅在成功完成 <code>unregister_netdev()</code> 或者为通过 <code>register_netdevice_notifier()</code> <code>register_inetaddr_notifier()</code>/<code>register_inet6addr_notifier()</code> 注册的回调生成 <code>NETDEV_UNREGISTER</code> 事件的类似命令时重置统计信息。</p>
+<p>移动运营商通常会在网络层 (IP) 计算数据流量。为了在 Android 4.0 中匹配这种方法,我们依赖于这样一个事实:对于内核设备,我们关注 <code>dev_get_stats()</code> 所返回的 <code>rx_bytes</code> 和 <code>tx_bytes</code> 值是否准确返回所传输的网络层 (<code>IP</code>) 字节。我们也知道,对其他设备而言可能并非如此。现在,该功能依赖于这一特性。新的驱动程序应该也拥有该属性,且 <code>dev_get_stats()</code> 值不得包含较低网络层(如以太网标头)的任何封装开销,且最好不包含其他流量(如 ARP),除非可以忽略不计。</p>
+<p>Android 框架仅从 <code>ConnectivityService</code> 中与 <code>NetworkStateTracker</code> 关联的网络接口收集统计信息。这样一来,框架就可以具体识别每个网络接口,包括其类型(如 <code>TYPE_MOBILE</code> 或 <code>TYPE_WIFI</code>)以及订阅者身份(如 IMSI)。用于路由数据的所有网络接口都应由 <code>NetworkStateTracker</code> 表示,以便正确计算统计信息。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/datausage/index.html b/zh-cn/devices/tech/datausage/index.html
new file mode 100644
index 00000000..65f115c5
--- /dev/null
+++ b/zh-cn/devices/tech/datausage/index.html
@@ -0,0 +1,27 @@
+<html devsite><head>
+ <title>数据使用情况技术信息</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 4.0 引入了新功能,可帮助用户了解和控制他们的设备如何使用网络数据。这项新功能可监测数据的整体使用情况,并支持将会触发通知或停用移动数据(当数据用量超出特定配额时)的警告或限制阈值。</p>
+<p>该功能还会跟踪每个应用的数据使用情况,这样一来,用户就可以在“设置”应用中直观地了解过往的数据使用情况。用户还可以限制特定应用在后台运行时的数据使用方式。</p>
+<p>本部分中的文档面向系统集成商和移动运营商,目的是向他们说明将 Android 移植到特定设备时应注意的技术细节。这些细节在下文中有总结,若要进一步讨论,请前往 <a href="mailto:android-porting+subscribe@googlegroups.com">android-porting</a> 论坛。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/datausage/tags-explained.html b/zh-cn/devices/tech/datausage/tags-explained.html
new file mode 100644
index 00000000..2f25b965
--- /dev/null
+++ b/zh-cn/devices/tech/datausage/tags-explained.html
@@ -0,0 +1,34 @@
+<html devsite><head>
+ <title>已说明的流量使用情况标签</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>标签是跟踪流量消耗计数器的指标之一。默认情况下,标签仅以隐性方式基于 UID。UID 被用作监管的基础,不容忽视。因此,标签始终至少代表一个 UID (uid_tag)。可以通过与 UID 关联的“帐号标签”明确增强某个标签。用户空间可以使用 <code>TrafficStats.setThreadStatsTag()</code> 设置标签的 acct_tag 部分,然后将标签与套接字配合使用:属于相应套接字的所有数据都将被计入该标签。之后,监管基于该标签的 uid_tag 部分,并单独收集 acct_tag 部分的统计信息。</p>
+<p>如果没有显式标记,则 qtaguid 模块将假设 <code>default_tag:  {acct_tag=0, uid_tag=10003}</code></p>
+<pre><code> a:  {acct_tag=1, uid_tag=10003}
+ b:  {acct_tag=2, uid_tag=10003}
+ c:  {acct_tag=3, uid_tag=10003}
+</code></pre>
+<p><code>a, b, c…</code> 表示与特定套接字关联的显式标签。</p>
+<p><code>default_tag (acct_tag=0)</code> 是包含相应 uid 的总流量(包括所有未标记的流量)的默认帐号标签,通常用于强制执行监管/配额规则。</p>
+<p>这些标签可用于将应用的网络流量划分到独立的逻辑类别中(在网络套接字级别)。可在运行时移除、重新应用或修改这些标签。</p>
+<p>qtaguid 模块已在 <a href="https://android-review.googlesource.com/#/q/project:kernel/common+branch:android-3.0,n,z">kernel/common branch of android-3.0</a> 上实现</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/datausage/usage-cycle-resets-dates.html b/zh-cn/devices/tech/datausage/usage-cycle-resets-dates.html
new file mode 100644
index 00000000..4a247cdf
--- /dev/null
+++ b/zh-cn/devices/tech/datausage/usage-cycle-resets-dates.html
@@ -0,0 +1,25 @@
+<html devsite><head>
+ <title>流量统计周期的重置日期</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>用户可以指定在每月的某一天重置其流量消耗情况。在内部,周期边界被定为于所请求日期的午夜 <code>(00:00) UTC</code> 结束。如果某月因天数不够多而不包含所请求的日期,相应周期将会于下月的第一天重置。例如,如果周期的重置时间为每月的第 30 天,系统便会在 1 月 30 日的 <code>00:00 UTC</code> 和 3 月 1 日的 <code>00:00 UTC</code> 进行重置。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/asan.html b/zh-cn/devices/tech/debug/asan.html
new file mode 100644
index 00000000..a98a9430
--- /dev/null
+++ b/zh-cn/devices/tech/debug/asan.html
@@ -0,0 +1,172 @@
+<html devsite><head>
+ <title>AddressSanitizer</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>AddressSanitizer (ASan) 是一种基于编译器的快速检测工具,用于检测原生代码中的内存错误。它与 Valgrind(Memcheck 工具)相差无几,不同之处在于,ASan:</p>
+
+<ul>
+ <li>+ 检测堆栈和全局对象是否有溢出</li><li>- 不检测未初始化的读取和内存泄露</li><li>+ 速度更快(Valgrind 的 20-100x 与其相比,慢 2-3 倍)</li><li>+ 内存占用空间较少</li></ul>
+
+<p>本文档介绍了如何使用 AddressSanitizer 构建和运行 Android 平台的组成部分。如果您希望利用 AddressSanitizer 构建独立的(即 SDK/NDK)应用,请改为参阅 <a href="https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid">AddressSanitizerOnAndroid</a> 公共项目网站。</p>
+
+<p>AddressSanitizer 包括一个编译器 (<code>external/clang</code>) 和一个运行时库 (<code>external/compiler-rt/lib/asan</code>)。</p>
+
+<p class="note"><strong>注意</strong>:请立即使用当前的 master 分支获取对 <a href="#sanitize_target">SANITIZE_TARGET</a> 功能的访问权限,并获取利用 AddressSanitizer 构建整个 Android 平台的能力。否则,您将只能使用 <code>LOCAL_SANITIZE</code>。</p>
+
+<h2 id="building_with_clang">使用 Clang 构建</h2>
+
+<p>要构建使用 ASan 进行测试的二进制文件,第一步是要确保您的代码是使用 Clang 进行构建的。默认情况下,系统会在 master 分支上完成这一步骤,因此您无需执行任何操作。如果您认为自己要测试的模块是使用 GCC 构建的,则可以向构建规则中添加 <code>LOCAL_CLANG:=true</code>,从而切换至 Clang。Clang 可以发现 GCC 遗漏的代码错误。</p>
+
+<h2 id="building_executables_with_addresssanitizer">使用 AddressSanitizer 构建可执行文件</h2>
+
+<p>将 <code>LOCAL_SANITIZE:=address</code> 添加到可执行文件的构建规则中。</p>
+
+<pre>
+LOCAL_SANITIZE:=address
+</pre>
+
+<p>检测到错误时,ASan 会向标准输出文件和 <code>logcat</code> 发送一份详细报告,然后让相应进程崩溃。</p>
+
+<h2 id="building_shared_libraries_with_addresssanitizer">使用 AddressSanitizer 构建共享库</h2>
+
+<p>根据 ASan 的工作原理,未采用 ASan 构建的可执行文件将无法使用采用 ASan 构建的库。</p>
+
+<p class="note">注意:如果 ASan 库加载到错误的进程,则在运行时,您会看到开头为 <code>_asan</code> 或 <code>_sanitizer</code> 的未解决错误符号信息。</p>
+
+<p>要清理多个可执行文件(并非所有这些可执行文件都是使用 ASan 构建的)使用的共享库,您需要获取该库的 2 个副本。要获取副本,建议您针对相应的模块向 <code>Android.mk</code> 中添加以下内容:</p>
+
+<pre>
+LOCAL_SANITIZE:=address
+LOCAL_MODULE_RELATIVE_PATH := asan
+</pre>
+
+<p>这样一来,系统会将库放置到 <code>/system/lib/asan</code>(而非 <code>/system/lib</code>)中。然后,使用以下方法运行您的可执行文件:<code>LD_LIBRARY_PATH=/system/lib/asan</code></p>
+
+<p>对于系统守护程序,将以下内容添加到 <code>/init.rc</code> 或 <code>/init.$device$.rc</code> 的相应部分。</p>
+
+<pre>
+setenv LD_LIBRARY_PATH /system/lib/asan
+</pre>
+
+<p class="warning"><strong>警告</strong>:<code>LOCAL_MODULE_RELATIVE_PATH</code> 设置会将您的库<strong>移动</strong>至 <code>/system/lib/asan</code>,这意味着,如果从头开始重写并重新构建,则会导致库从 <code>/system/lib</code> 中缺失,且很可能会产生无法启动的映像。这是当前构建系统存在的一个令人遗憾的限制。不要重写;而是进行 <code>make -j $N</code> 和 <code>adb
+sync</code>。</p>
+
+<p>当通过读取 <code>/proc/$PID/maps</code> 显示相应进程时,验证其使用的是否为来自 <code>/system/lib/asan</code> 的库。如果不是,您可能需要停用 SELinux,如下所示:</p>
+
+<pre>
+$ adb root
+$ adb shell setenforce 0
+# restart the process with adb shell kill $PID
+# if it is a system service, or may be adb shell stop; adb shell start.
+</pre>
+
+<h2 id="better_stack_traces">更出色的堆栈跟踪</h2>
+
+<p>AddressSanitizer 使用基于框架指针的快速展开程序,针对程序中的每个内存分配和取消分配事件记录堆栈跟踪。大部分 Android 平台都未使用框架指针进行构建。因此,您通常仅会获得 1 个或 2 个有意义的框架。要解决此问题,请使用 ASan(推荐)或以下方法重新构建库:</p>
+
+<pre>
+LOCAL_CFLAGS:=-fno-omit-frame-pointer
+LOCAL_ARM_MODE:=arm
+</pre>
+
+<p>或者在进程环境中设置 <code>ASAN_OPTIONS=fast_unwind_on_malloc=0</code>。后者可能对 CPU 要求极高,具体取决于负载。</p>
+
+<h2 id="symbolization">符号化</h2>
+
+<p>最初,ASan 报告中包含对二进制文件和共享库中的偏移量的引用。您可以通过以下两种方法获取源文件和行信息:</p>
+
+<ul>
+ <li>确保 <code>/system/bin</code> 中有 llvm-symbolizer 二进制文件。Llvm-symbolizer 在 <code>third_party/llvm/tools/llvm-symbolizer</code> 的源文件中构建 </li><li>通过 <code>external/compiler-rt/lib/asan/scripts/symbolize.py</code> 脚本过滤报告。
+</li></ul>
+
+<p>由于可以使用主机上的符号化库,因此第二种方法可以提供更多数据(即 file:line 位置)。</p>
+
+<h2 id="addresssanitizer_in_the_apps">应用中的 AddressSanitizer</h2>
+
+<p>AddressSanitizer 无法了解 Java 代码的情况,但可以检测 JNI 库中的错误。为此,您需要使用 ASan 构建可执行文件,在此情况下是 <code>/system/bin/app_process(<em>32|64</em></code>)。这样一来,便可以同时启用设备上所有应用中的 ASan,这会给设备带来一点压力,但 2GB RAM 设备可以从容处理任何情况。</p>
+
+<p>向 <code>frameworks/base/cmds/app_process</code> 中的 app_process 构建规则添加常规 <code>LOCAL_SANITIZE:=address</code>。暂时忽略同一文件中的 <code>app_process__asan</code> 目标(如果当您阅读该文档时仍存在于文件中)。修改 <code>system/core/rootdir/init.zygote(<em>32|64</em>).rc</code> 中的 Zygote 记录,以添加以下行:</p>
+
+<pre>
+setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
+setenv ASAN_OPTIONS
+allow_user_segv_handler=true
+</pre>
+
+<p>构建,进行 adb 同步,fastboot 刷写启动,然后重新启动。</p>
+
+<h2 id="using_the_wrap_property">使用 wrap 属性</h2>
+
+<p>上一部分中的方法将 AddressSanitizer 放置到了系统的每个应用中(实际上是放置到了 Zygote 进程的每个子级元素中)。可以仅运行一个(或几个)具有 ASan 的应用,从而占用部分内存空间,使应用启动速度变慢。</p>
+
+<p>为实现这一目标,您可以借助“wrap”属性(用于在 Valgrind 下运行应用的同一属性)启动应用。下面是在 ASan 下运行 Gmail 应用的示例:</p>
+
+<pre>
+$ adb root
+$ adb shell setenforce 0 # disable SELinux
+$ adb shell setprop wrap.com.google.android.gm "asanwrapper"
+</pre>
+
+<p>在这种情况下,asanwrapper 会将 <code>/system/bin/app_process</code> 重写至 <code>/system/bin/asan/app_process</code>(使用 AddressSanitizer 构建)。此外,它还会在动态库搜索路径的开头处添加 <code>/system/lib/asan</code>。这样一来,借助 asanwrapper 运行应用时,与 <code>/system/lib</code> 中的普通库相比,系统更倾向于使用 <code>/system/lib/asan</code> 中用 ASan 进行测试的库。</p>
+
+<p>同样,如果发现错误,应用会崩溃,且系统会将报告记录到日志中。</p>
+
+<h2 id="sanitize_target">SANITIZE_TARGET</h2>
+
+<p>master 分支支持立即使用 AddressSanitizer 构建整个 Android 平台。</p>
+
+<p>在同一构建树中运行以下命令。</p>
+
+<pre>
+$ make -j42
+$ SANITIZE_TARGET=address make -j42
+</pre>
+
+<p>在此模式下,<code>userdata.img</code> 中包含其他库,必须也刷写到设备上。请使用以下命令行:</p>
+
+<pre>
+$ fastboot flash userdata &amp;&amp; fastboot flashall
+</pre>
+
+<p>写入时,现今的 Nexus 和 Pixel 设备会启动到该模式中的界面。</p>
+
+<p>其工作原理是构建两组共享库:<code>/system/lib</code> 中的常规库(第一次 make 调用),<code>/data/asan/lib</code> 中使用 ASan 进行测试的库(第二次 make 调用)。第二次构建中的可执行文件会覆盖第一次构建中的可执行文件。通过使用 PT_INTERP 中的“/system/bin/linker_asan”,使用 ASan 进行测试的可执行文件会获得一个不同的库搜索路径,该路径会在 <code>/system/lib</code> 前添加 <code>/data/asan/lib</code>。</p>
+
+<p>如果 <code>$SANITIZE_TARGET</code> 值已更改,则构建系统会重写中间对象目录。这样一来,系统便会强制重新构建所有目标,同时保留 <code>/system/lib</code> 下已安装的二进制文件。</p>
+
+<p>以下目标不能使用 ASan 进行构建:</p>
+
+<ul>
+ <li>静态关联的可执行文件。
+ </li><li><code>LOCAL_CLANG:=false</code> 目标</li><li>不会针对 <code>SANITIZE_TARGET=address</code> 进行 ASan 操作的 <code>LOCAL_SANITIZE:=false</code>
+</li></ul>
+
+<p>在 SANITIZE_TARGET 构建中,系统会跳过此类可执行文件,且会将第一次 make 调用中的版本留在 <code>/system/bin</code> 中。</p>
+
+<p>此类库只是未使用 ASan 进行构建,但它们仍然可以包含一些来自自己依赖的静态库的 ASan 代码。</p>
+
+<h2 id="supporting_documentation">支持文档</h2>
+
+<p><a href="https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid">AddressSanitizerOnAndroid</a> 公共项目网站</p>
+<p><a href="https://www.chromium.org/developers/testing/addresssanitizer">AddressSanitizer 和 Chromium</a></p>
+<p><a href="https://github.com/google/sanitizers">其他 Google 清理程序</a></p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/dumpsys.html b/zh-cn/devices/tech/debug/dumpsys.html
new file mode 100644
index 00000000..2568280e
--- /dev/null
+++ b/zh-cn/devices/tech/debug/dumpsys.html
@@ -0,0 +1,89 @@
+<html devsite><head>
+ <title>dumppsys 系统诊断</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><code>dumpsys</code> 工具可在设备上运行,并提供有关系统服务状态的信息。</p>
+
+<h2 id="how_to_use_dumpsys">如何使用 dumpsys</h2>
+
+<p>如果您运行 <code>adb shell dumpsys</code>,则会获得所有系统服务的诊断输出内容,这些输出内容通常比您需要的还要多。要获得更易于处理的输出内容,请指定要检查的服务。</p>
+
+<p>例如,运行以下命令:</p>
+
+<pre>
+$ adb shell dumpsys input
+</pre>
+
+<p>提供输入组件(例如触摸屏或内置键盘)的系统数据。</p>
+
+<h2 id="list_of_system_services">系统服务列表</h2>
+
+<p>要获取可用于 dumpsys 的系统服务的完整列表,请尝试运行以下命令:</p>
+
+<pre class="no-pretty-print">
+$ adb shell dumpsys -l
+Currently running services:
+ DockObserver
+ SurfaceFlinger
+ accessibility
+ account
+ activity
+ alarm
+ android.security.keystore
+ appops
+ appwidget
+ assetatlas
+ audio
+ backup
+ battery
+ batteryproperties
+ batterystats
+ bluetooth_manager
+ clipboard
+ connectivity
+ consumer_ir
+ content
+ country_detector
+ cpuinfo
+ dbinfo
+...
+</pre>
+
+<h2 id="dumpsys_command-line_options">dumppsys 命令行选项</h2>
+
+<p>命令行选项因服务而异。以下是几个常见的命令行选项:</p>
+
+<ul>
+ <li>对于许多服务,您可以附加 <code>-h</code> 来查看帮助文本。
+ </li><li>对于某些服务,您可以附加 <code>-c</code> 来查看计算机可读取格式的数据。</li></ul>
+
+<h2 id="understanding_diagnostic_output">了解诊断输出</h2>
+
+<p>要详细了解一些最常用的 dumpsys 服务,请参阅以下文章:</p>
+
+<ul>
+ <li> <a href="/devices/input/diagnostics.html">查看输入诊断信息 (dumpsys input)</a>
+ </li><li> <a href="procstats.html">查看 RAM 使用情况数据 (dumpsys procstats)</a>
+ </li><li> <a href="netstats.html">查看网络数据 (dumpsys netstats)</a>
+ </li><li> <a href="/devices/tech/power/batterystats.html">查看电池使用情况数据 (dumpsys batterystats)</a>
+</li></ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/eval_perf.html b/zh-cn/devices/tech/debug/eval_perf.html
new file mode 100644
index 00000000..4ae40504
--- /dev/null
+++ b/zh-cn/devices/tech/debug/eval_perf.html
@@ -0,0 +1,127 @@
+<html devsite><head>
+ <title>评估性能</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>在性能方面,有两项用户可见指标:</p>
+
+<ul>
+<li><strong>可预测、可察觉的性能</strong>。界面是否掉帧或始终以 60 帧/秒的帧速率渲染?音频在没有软件工件或弹出的情况下会播放吗?用户在触摸屏幕后要多久显示屏上才会显示相应结果?</li>
+<li><strong>耗时操作所需的时间长短</strong>(如打开应用)。</li>
+</ul>
+
+<p>前者比后者更显而易见。用户通常会注意到卡顿情况,但分辨不出 500 毫秒和 600 毫秒应用启动时间的差别,除非将两台设备并排进行对比。触摸延迟立刻就能被发现,且严重影响用户对设备的印象。</p>
+
+<p>因此,在速度较快的设备中,相较于其他使界面通道保持正常运转所必需的要素,界面通道是最重要的。这意味着,如果不是保持界面流畅运转所必需的任务,都应为界面通道让路。要让界面保持流畅运转,后台同步、通知发送及类似的任务都必须延迟(如果界面任务可以运行的话)。可以牺牲耗时操作(HDR+ 运行时、应用启动等)的性能来保持界面的流畅性。</p>
+
+<h2 id="capacity_vs_jitter">容量和抖动</h2>
+<p>在考虑设备性能时,容量和抖动是两项重要指标。<em></em><em></em></p>
+
+<h3 id="capacity">容量</h3>
+<p>容量是设备在一段时间内拥有的某种资源的总量。这种资源可以是 CPU 资源、GPU 资源、I/O 资源、网络资源、存储设备带宽或其他类似指标。在检测整个系统的性能时,抽取各个组件并假设某单项指标决定着性能将很有帮助(尤其是调试新设备时,因为在新设备上运行的工作负载可能是固定的)。</p>
+
+<p>系统容量因在线计算资源而异。更改 CPU/GPU 频率是改变容量的主要方式,但也有其他方式,如更改在线 CPU 核心数。相应地,系统的容量与耗电量相对应,<strong>更改容量一定会导致耗电量出现类似的变化。</strong></p>
+
+<p>特定时间内所需的容量在绝大多数情况下取决于正在运行的应用。因此,平台几乎不能调整特定工作负载所需的容量,调整所用的方式也仅限于运行时改进(Android 框架、ART、Bionic、GPU 编译器/驱动程序、内核)。</p>
+
+<h3 id="jitter">抖动</h3>
+<p>工作负载所需的容量很容易看出来,抖动却是一个比较模糊的概念。有关抖动是快速系统的一种障碍的介绍,请参阅 <em><a href="http://permalink.lanl.gov/object/tr?what=info:lanl-repo/lareport/LA-UR-03-3116">THE CASE OF THE MISSING SUPERCOMPUTER PERFORMANCE: ACHIEVING OPTIMAL PERFORMANCE ON THE 8,192 PROCESSORS OF ASCl Q</a></em>。(这是一项针对 ASCI Q 超级计算机为何达不到预期性能的调查,同时充分介绍了如何优化大型系统。)</p>
+
+<p>本页使用“抖动”这一术语来介绍 ASCI Q 论文中提到的噪点。<em></em>抖动是一种随机的系统行为,会阻止可察觉任务的运行。通常是必须运行的任务,但可能对在任一特定时间运行没有严格的定时要求。因为抖动具有随机性,所以很难证明某一特定工作负载不存在抖动,也很难证明某已知抖动源是导致某个特定性能问题的原因。诊断抖动原因最常用的工具(如跟踪或日志记录)可能会引入它们自己的抖动。</p>
+
+<p>在实际的 Android 实现中遇到的抖动源包括:</p>
+<ul>
+<li>调度程序延迟</li>
+<li>中断处理程序</li>
+<li>驱动程序代码在抢占或中断被停用的情况下运行时间过长</li>
+<li>运行时间较长的软中断</li>
+<li>锁争用(应用、框架、内核驱动程序、Binder 锁、mmap 锁)</li>
+<li>文件描述符争用,低优先级的线程持有某个文件的锁,以防止高优先级线程运行</li>
+<li>在可能会延迟的工作队列中运行界面关键型代码</li>
+<li>CPU 空闲转换</li>
+<li>记录</li>
+<li>I/O 延迟</li>
+<li>创建不必要的进程(如 CONNECTIVITY_CHANGE 广播)</li>
+<li>释放内存不足所导致的页面缓存颠簸</li>
+</ul>
+
+<p>特定时段内的抖动所需的时间不一定会随着容量的增加而减少。例如,如果驱动程序在等待来自 i2c 总线的读取时使中断处于停用状态,那么无论 CPU 是 384MHz 还是 2GHz,所需要的时间都是固定的。涉及抖动时,增加容量并非提升性能的可行解决方案。因此,<strong>更快的处理器在抖动受限的情况下通常不会提升性能。</strong></p>
+
+<p>最后,与容量不同的是,抖动几乎完全存在于系统供应商的网域中。</p>
+
+<h3 id="memory_consumption">内存消耗</h3>
+<p>一直以来,人们都将性能不佳归因于内存消耗。虽然消耗本身不是性能问题,但是它可能会通过 lowmemorykiller 开销、服务重启和页面缓存颠簸引起抖动。减少内存消耗可以避免导致性能不佳的直接原因,但是还有其他可避免这些原因的具有针对性的改进(如固定框架以防止在不久之后进行的分页过程中将其分出)。</p>
+
+<h2 id="analyze_initial">分析初始设备性能</h2>
+<p>从运行正常但性能不佳的系统开始,并尝试通过查看用户可见的糟糕性能的每个个案来修复系统的行为,这种做法并<strong>非</strong>良策。因为性能不佳通常不易重现(如抖动)或者由应用问题导致,整个系统中可阻止此策略发挥作用的变量非常多。因此,很容易错误地识别原因并做出微小的改进,而错失修复整个系统性能的系统性机会。</p>
+
+<p>相反,在启动新设备时,请使用以下常规方法:</p>
+<ol>
+<li>使系统启动到所有驱动程序运行的界面和一些基本的频率调节器设置(如果更改频率调节器设置,请重复以下所有步骤)。</li>
+<li>确保内核支持 <code>sched_blocked_reason</code> 跟踪点以及显示通道中指示何时将帧发送到显示屏的其他跟踪点。</li>
+<li>在运行轻量级的一致性工作负载(如 <a href="https://android.googlesource.com/platform/frameworks/base.git/+/master/tests/UiBench/">UiBench</a> 或 <a href="#touchlatency">TouchLatency 中的球测试</a>)的同时,对整个界面通道(从通过 IRQ 接收输入到最终的扫描输出)进行长时间的跟踪。</li>
+<li>修复在轻量级的一致性工作负载中检测到的帧丢失。</li>
+<li>重复执行第 3-4 步,直到您可以在零丢帧的情况下一次运行 20 秒以上的时间。</li>
+<li>转向用户可见的其他卡顿源。</li>
+</ol>
+
+<p>您可以在设备启动早期执行的其他简单操作包括:</p>
+
+<ul>
+<li>确保您的内核有 <a href="https://android.googlesource.com/kernel/msm/+/c9f00aa0e25e397533c198a0fcf6246715f99a7b%5E!/">sched_blocked_reason 跟踪点补丁程序</a>。该跟踪点通过 systrace 中的 sched 跟踪类别启用,并在线程进入不间断休眠时提供负责休眠的函数。它对性能分析非常重要,因为不间断休眠是非常常见的抖动指标。</li>
+<li>确保您拥有足够的 GPU 和显示通道的跟踪。在最近的 Qualcomm SOC 上,跟踪点的启用方法是:</li>
+<pre>$ adb shell "echo 1 &gt; /d/tracing/events/kgsl/enable"
+$ adb shell "echo 1 &gt; /d/tracing/events/mdss/enable"</pre>
+
+<p>运行 systrace 时,这些事件将保持启用状态,以便您在 <code>mdss_fb0</code> 部分的跟踪记录中查看有关显示通道 (MDSS) 的其他信息。在 Qualcomm SOC 上,您无法在 systrace 标准视图下看到有关 GPU 的其他信息,只能看到跟踪记录本身所显示的结果(如需了解详情,请参阅<a href="/devices/tech/debug/systrace.html">了解 systrace</a> 一文)。</p>
+
+<p>您希望从这种显示跟踪中了解的是,直接指明某个帧已被发送至显示屏的单个事件。在这里,您可以确定是否成功满足帧时间;如果事件 Xn 的发生时间在事件 Xn-1 发生后的 16.7 毫秒内(假设为 60Hz 的显示屏),您就会知道没有卡顿。<em></em><em></em>如果您的 SOC 不提供这种信号,请与您的供应商联系以进行获取。如果没有明确的帧完成信号,很难调试抖动。</p></ul>
+
+<h3 id="synthetic_benchmarks">使用合成基准</h3>
+<p>合成基准有助于确保设备的基本功能是存在的。不过,将基准视为感知设备性能的代理毫无用处。</p>
+
+<p>根据 SOC 使用体验,SOC 之间的合成基准性能的差异与可察觉的界面性能(丢失帧数、第 99 个百分位帧时间等)中的类似差异不相关。合成基准属于仅限容量的基准;抖动仅可以从基准的批量操作中窃取时间来影响这些基准衡量的性能。因此,合成基准得分在作为用户可察觉的性能的指标时是最不相关的指标。</p>
+
+<p>考虑两种运行可渲染 1000 帧界面的基准 X 的 SOC,并报告总渲染时间(得分越低越好)。</p>
+
+<ul>
+<li>SOC 1 在 10 毫秒内渲染每帧基准 X,得分为 10000。</li>
+<li>SOC 2 在 1 毫秒内渲染 99% 的帧,但是在 100 毫秒内渲染 1% 的帧,得分为 19900,得分明显较好。</li>
+</ul>
+
+<p>如果基准代表实际的界面性能,则 SOC 2 将无法使用。假设刷新率为 60Hz,SOC 2 在每 1.5 秒的操作内将出现一次卡顿帧。与此同时,SOC 1(根据基准 X 得出的较慢的 SOC)将会非常流畅。</p>
+
+<h3 id="bug_reports">使用缺陷报告</h3>
+<p>缺陷报告有时对于性能分析非常有用,但是因为这类报告的内容全面而复杂,因此对调试分散的卡顿问题用处不大。报告可能会提供一些有关系统在特定时间内所执行操作的线索,尤其是卡顿出现在应用转换(会被记录在缺陷报告中)时。缺陷报告还可以指出可能会减少其有效容量的系统大范围出错(如温控调频或内存碎片)的时间。</p>
+
+<h3 id="touchlatency">使用 TouchLatency</h3>
+<p>一些不良行为的示例来自于 TouchLatency(即用于 Pixel 和 Pixel XL 的首选周期性工作负载),可通过 <code>frameworks/base/tests/TouchLatency</code> 找到,具有两种模式:触摸延迟和弹力球(要切换模式,请点击右上角的按钮)。</p>
+
+<p>弹力球测试就跟看上去的一样简单:无论用户输入什么内容,球都会一直在屏幕上弹跳。这通常也是<strong>目前为止</strong>最难完美运行的测试,不过,越接近在没有丢失帧的情况下运行,就说明您的设备越好。弹力球测试很难执行,因为它是以很低的时钟频率运行的琐碎但完全一致的工作负载(此时假设设备配有频率调节器;不过,如果设备是以固定的时钟频率运行,则在首次运行弹力球测试时将 CPU/GPU 降频到接近最小值)。当系统静止且时钟频率降至接近空闲时,每帧所需的 CPU/GPU 时间增加。您可以查看球以及卡顿的对象,还可以在 systrace 中查看丢失的帧。</p>
+
+<p>因为工作负载非常一致,所以在大多数用户可见的工作负载中,您可以在每个丢失的帧期间跟踪系统上正在运行的工作负载(而非界面通道),从而更轻松地确定大多数抖动源。<strong>较低的时钟频率会使任何抖动都更有可能造成帧丢失,从而放大抖动的效果。</strong> 因此,TouchLatency 越接近 60 帧/秒,您在较大的应用中遇到导致分散、难以重现的卡顿的不良系统行为的可能性越小。</p>
+
+<p>由于抖动通常(但不总是)时钟速度不变,请使用以非常低的时钟速度运行的测试来诊断抖动,原因如下:</p>
+<ul>
+<li>并非所有抖动都是时钟速度不变,很多来源仅占用 CPU 时间。</li>
+<li>频率调节器应通过降频获取接近截止时间的平均帧时间,这样运行非界面任务所花费的时间可将其推至掉帧的边缘。</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/ftrace.html b/zh-cn/devices/tech/debug/ftrace.html
new file mode 100644
index 00000000..7a193ca8
--- /dev/null
+++ b/zh-cn/devices/tech/debug/ftrace.html
@@ -0,0 +1,169 @@
+<html devsite><head>
+ <title>使用 ftrace</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>ftrace 是一种调试工具,用于了解 Linux 内核中的情况。以下部分详细介绍了 ftrace 的基本功能、ftrace 与 atrace(捕获内核事件)如何配合使用,以及动态 ftrace。</p>
+
+<p>有关 systrace 中没有的 ftrace 高级功能的详情,请参阅位于以下位置的 ftrace 文档:<a href="https://www.kernel.org/doc/Documentation/trace/ftrace.txt"><code>&lt;kernel
+tree&gt;/Documentation/trace/ftrace.txt</code></a>。</p>
+
+<h2 id="atrace">通过 atrace 捕获内核事件</h2>
+<p>atrace (<code>frameworks/native/cmds/atrace</code>) 使用 ftrace 来捕获内核事件。反之,systrace.py(或更高版本的 <a href="https://github.com/catapult-project/catapult">Catapult</a> 中的 run_systrace.py)使用 adb 在设备上运行 atrace。atrace 执行以下操作:</p>
+<ul>
+<li>通过设置属性 (<code>debug.atrace.tags.enableflags</code>) 来设置用户模式跟踪。</li>
+<li>通过写入适当的 ftrace sysfs 节点来启用所需的 ftrace 功能。不过,由于 ftrace 支持的功能更多,您可以自行设置一些 sysfs 节点,然后使用 atrace。</li>
+</ul>
+
+<p>除了启动时跟踪之外,还可以通过使用 atrace 将属性设置为适当的值。属性是一个位掩码,除了查找适当的标头(在不同的 Android 版本之间会有所变化),没有确定正确值更好的办法了。</p>
+
+<h2 id="enabling_events">启用 ftrace 事件</h2>
+
+<p>ftrace sysfs 节点位于 <code>/d/tracing</code> 中,trace 事件在 <code>/d/tracing/events</code> 中被划分为多个类别。
+
+</p><p>要按类别启用事件,请使用:</p><pre>$ echo 1 &gt; /d/tracing/events/irq/enable</pre>
+
+<p>要按事件启用事件,请使用:</p><pre>$ echo 1 &gt; /d/tracing/events/sched/sched_wakeup/enable</pre>
+
+<p>如果通过写入 sysfs 节点启用了额外的事件,这些事件将<strong>不会</strong>被 atrace 重置。Qualcomm 设备启动的常用模式是启用 <code>kgsl</code> (GPU) 和 <code>mdss</code>(显示管道)跟踪点,然后使用 atrace 或 <a href="/devices/tech/debug/systrace.html">systrace</a>:</p>
+
+<pre>$ adb shell "echo 1 &gt; /d/tracing/events/mdss/enable"
+$ adb shell "echo 1 &gt; /d/tracing/events/kgsl/enable"
+$ ./systrace.py sched freq idle am wm gfx view binder_driver irq workq ss sync -t 10 -b 96000 -o full_trace.html</pre>
+
+<p>您还可以单独使用 ftrace(不使用 atrace 或 systrace),这在您需要仅限内核的跟踪(或者您已经花时间手动写入用户模式跟踪属性)时很有帮助。如需只运行 ftrace,请执行以下操作:</p>
+
+<ol>
+<li>将缓冲区大小设置为足以用于您跟踪的值:<pre>$ echo 96000 &gt; /d/tracing/buffer_size_kb</pre></li>
+<li>启用跟踪:<pre>$ echo 1 &gt; /d/tracing/tracing_on</pre></li>
+<li>运行您的测试,然后停用跟踪:<pre>$ echo 0 &gt; /d/tracing/tracing_on</pre></li>
+<li>转储跟踪:<pre>$ cat /d/tracing/trace &gt; /data/local/tmp/trace_output</pre>
+</li></ol>
+
+<p>trace_output 以文本形式提供跟踪记录。要使用 Catapult 将其可视化,请从 Github 获取 <a href="https://github.com/catapult-project/catapult/tree/master/">Catapult 存储区</a>并运行 trace2html:</p>
+
+<pre>$ catapult/tracing/bin/trace2html ~/path/to/trace_file</pre>
+
+<p>默认情况下,此操作会将 <code>trace_file.html</code> 写入同一目录中。</p>
+
+<h2 id="correlate">相关事件</h2>
+<p>同时查看 Catapult 可视化内容和 ftrace 日志通常很有帮助,例如,某些 ftrace 事件(尤其是特定于供应商的事件)未经 Catapult 可视化。不过,Catapult 的时间戳与跟踪记录中的第一个事件或 atrace 所转储的特定时间戳相关,而原始的 ftrace 时间戳则基于 Linux 内核中的特别绝对时钟源。</p>
+
+<p>要从 Catapult 事件中查找特定的 ftrace 事件,请执行以下操作:</p>
+
+<ol>
+<li>打开原始的 ftrace 日志。最新版本的 systrace 中的跟踪记录默认经过压缩:<ul>
+<li>如果您使用 <code>--no-compress</code> 捕获 systrace,则跟踪记录在 html 文件中以 BEGIN TRACE 开头的部分。</li>
+<li>如果没有,请从 <a href="https://github.com/catapult-project/catapult/tree/master/">Catapult 树</a> (<code>tracing/bin/html2trace</code>) 运行 html2trace 来解压缩跟踪记录。</li>
+</ul>
+</li>
+<li>在 Catapult 可视化中查找相对时间戳。</li>
+
+<li>在跟踪记录的开头找到一行包含 <code>tracing_mark_sync</code> 的内容。该行应该与以下内容相似:<pre>&lt;5134&gt;-5134 (-----) [003] ...1 68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286</pre>
+
+<br />如果此行不存在(或者您使用没有 atrace 的 ftrace),则计时将与 ftrace 日志中的第一个事件相关。
+<ol style="list-style-type: lower-alpha">
+<li>将相对时间戳(以毫秒为单位)添加到 <code>parent_ts</code>(以秒为单位)中的值。</li>
+<li>搜索新时间戳。</li>
+</ol>
+</li>
+</ol>
+<p>按照这些步骤操作之后,您应该会找到(或至少非常接近于)要找的事件。</p>
+
+<h2 id="dftrace">使用动态 ftrace</h2>
+<p>当 systrace 和标准 ftrace 不足时,还有最后一种可用资源:动态 ftrace。<em></em>动态 ftrace 涉及在启动后重写内核代码,因此出于安全考虑,它在正式版内核中不可用。不过,2015 和 2016 版中的每个严重性能错误最终都使用动态 ftrace 找出了根本原因。它在调试不间断休眠方面的功能尤其强大,因为每次命中触发不间断休眠的函数时,您都会获得内核中的堆栈跟踪记录。您还可以调试中断和抢占被停用的部分,这对证明问题非常有帮助。</p>
+
+<p>要开启动态 ftrace,请修改您内核的 defconfig:</p>
+
+<ol>
+<li>移除 CONFIG_STRICT_MEMORY_RWX(如果存在)。如果您使用的是 3.18 或更新版本以及 arm64,则不存在。</li>
+<li>添加以下内容:CONFIG_DYNAMIC_FTRACE=y、CONFIG_FUNCTION_TRACER=y、CONFIG_IRQSOFF_TRACER=y、CONFIG_FUNCTION_PROFILER=y 和 CONFIG_PREEMPT_TRACER=y</li>
+<li>重建和启动新内核。</li>
+<li>运行以下代码以检查可用的跟踪工具:<pre>$ cat /d/tracing/available_tracers</pre></li>
+<li>确认命令返回 <code>function</code>、<code>irqsoff</code>、<code>preemptoff</code> 和 <code>preemptirqsoff</code>。</li>
+<li>运行以下命令以确保动态 ftrace 正常运行:<pre>$ cat /d/tracing/available_filter_functions | grep &lt;a function you care about&gt;</pre>
+</li>
+</ol>
+
+<p>完成这些步骤之后,动态 ftrace、函数分析器、irqsoff 分析器以及 preemptoff 分析器便处于可用状态。我们<strong>强烈建议</strong>您在使用之前阅读有关这些主题的 ftrace 文档,因为它们虽然功能强大,但比较复杂。irqsoff 和 preemptoff 主要用于确认驱动程序是否会使中断或抢占处于关闭状态的时间过长。</p>
+<p>函数分析器是诊断性能问题的最佳选择,通常用于查找函数被调用的位置。</p>
+
+<section class="expandable">
+<h4 class="showalways">显示问题:HDR 照片 + 旋转取景器</h4>
+
+<p>在此问题中,每次使用 Pixel XL 拍摄 HDR + 照片后立即旋转取景器时都会造成卡顿。我们使用函数分析器不到一个小时就调试了该问题。要按照示例进行操作,请<a href="perf_traces.zip">下载跟踪记录的 ZIP 文件</a>(其中包括本部分中提到的其他跟踪记录),解压下载的文件,然后在浏览器中打开 trace_30898724.html 文件。</p>
+
+<p>跟踪记录显示 cameraserver 进程中的一些线程在 <code>ion_client_destroy</code> 上的不间断休眠模式下被屏蔽。此为高代价函数,但不得经常调用,因为 ion 客户端应该包含多项分配。最初是将原因归咎于 Halide 中的 Hexagon 代码,它确实是其中一个原因(它为每个 ion 分配创建新的客户端,并在分配被释放时破坏相应客户端,其代价太高了)。转为适用于所有 Hexagon 分配的单个 ion 客户端改善了这种情况,但卡顿问题并没有得到解决。</p>
+<p>此时,我们需要知道谁在调用 <code>ion_client_destroy</code>,这就要使用函数分析器:</p>
+<p></p>
+<ol>
+<li>由于编译人员有时会对函数进行重命名,因此通过使用以下命令确认 <code>ion_client_destroy</code> 是否存在:<pre>$ cat /d/tracing/available_filter_functions | grep ion_client_destroy</pre>
+</li>
+<li>确认存在之后,将其用作 ftrace 过滤器:<pre>$ echo ion_client_destroy &gt; /d/tracing/set_ftrace_filter</pre></li>
+<li>开启函数分析器:<pre>$ echo function &gt; /d/tracing/current_tracer</pre></li>
+<li>每次调用筛选器函数时均开启堆栈跟踪:<pre>$ echo func_stack_trace &gt; /d/tracing/trace_options</pre></li>
+<li>增加缓冲区大小:<pre>$ echo 64000 &gt; /d/tracing/buffer_size_kb</pre></li>
+<li>开启跟踪功能:<pre>$ echo 1 &gt; /d/tracing/trace_on</pre></li>
+<li>运行测试并获取跟踪记录:<pre>$ cat /d/tracing/trace &gt; /data/local/tmp/trace</pre></li>
+<li>查看跟踪,以查看大量堆栈跟踪记录:<pre> cameraserver-643 [003] ...1 94.192991: ion_client_destroy &lt;-ion_release
+ cameraserver-643 [003] ...1 94.192997: &lt;stack trace&gt;
+ =&gt; ftrace_ops_no_ops
+ =&gt; ftrace_graph_call
+ =&gt; ion_client_destroy
+ =&gt; ion_release
+ =&gt; __fput
+ =&gt; ____fput
+ =&gt; task_work_run
+ =&gt; do_notify_resume
+ =&gt; work_pending</pre></li>
+ </ol>
+
+<p>对 ion 驱动程序进行检查后,我们可以发现,<code>ion_client_destroy</code> 被将 fd 关闭到 <code>/dev/ion</code>(而非随机内核驱动程序)的用户空间函数所破坏。通过在 Android 代码库中搜索 <code>\"/dev/ion\"</code>,我们发现一些供应商驱动程序与 Hexagon 驱动程序的功能相同,每次在需要新的 ion 分配时打开/关闭 <code>/dev/ion</code>(创建和破坏新的 ion 客户端)。将其更改为在进程的生命周期中<a href="https://android.googlesource.com/platform/hardware/qcom/camera/+/8f7984018b6643f430c229725a58d3c6bb04acab">使用单个 ion 客户端</a>即修复了该错误。</p>
+</section>
+<hr />
+
+<p>如果函数分析器的数据不够具体,您可以将 ftrace 跟踪点与函数分析器结合使用。此外,还可以像平常一样启用 ftrace 事件,这些事件会与您的跟踪记录交错。如果您要调试的特定函数中偶尔存在不间断的长时间休眠,这会非常有用:将 ftrace 过滤器设置为所需函数,启用跟踪点,然后进行跟踪。您可以使用 <code>trace2html</code> 解析得出的跟踪记录,查找所需的事件,然后获取原始跟踪记录中相邻的堆栈跟踪记录。</p>
+
+<h2 id="lock_stat">使用 lockstat</h2>
+<p>有时,只有 ftrace 是不够的,您必须调试内核锁争用。还有一种内核选项值得尝试:<code>CONFIG_LOCK_STAT</code>。这是最后一种方法,因为要在 Android 设备上应用这一方法非常困难,原因是它会使内核的大小超出大多数设备可以处理的范围。</p>
+<p>不过,lockstat 使用调试锁基础设施,这对很多其他应用都有帮助。负责设备启动的所有人都应想出方法来使该选项适用于每台设备,因为您<strong>也许</strong>会想“如果我可以开启 <code>LOCK_STAT</code>,就可以在 5 分钟(而不是 5 天)内确认或反驳这一问题”。</p>
+
+<section class="expandable">
+<h4 class="showalways">显示问题:当内核以最大负载运行 non-SCHED_FIFO 时,SCHED_FIFO 终止</h4>
+
+<p>在这个问题中,当所有内核以最大负载运行 non-SCHED_FIFO 线程时,SCHED_FIFO 线程便会终止。我们的跟踪记录显示 VR 应用中的 fd 存在明显的锁争用,但是我们无法轻松确定相关 fd。要按照示例进行操作,请<a href="perf_traces.zip">下载跟踪记录的 ZIP 文件</a>(其中包括本部分中提到的其他跟踪记录),解压下载文件,然后在浏览器中打开 trace_30905547.html 文件。
+</p>
+
+<p>我们假设 ftrace 本身是锁争用的来源,当优先级较低的线程开始写入 ftrace 管道时,却在释放锁之前被抢占。这是最糟糕的一种情况,一些优先级极低的线程写入 ftrace 标记,同时另一些优先级较高的线程在 CPU 上旋转以模拟完全负载的设备,从而进一步加重情况。</p>
+<p>由于我们无法使用 ftrace 进行调试,因此运行 <code>LOCK_STAT</code>,然后关闭应用的所有其他跟踪功能。结果表明,锁争用实际上来自 ftrace,因为当 ftrace 不运行时,锁跟踪记录中没有出现任何争用情况。</p>
+</section>
+<hr />
+
+<p>如果您可以使用配置选项启动内核,则锁跟踪与 ftrace 类似:</p>
+<ol>
+<li>启用跟踪:<pre>$ echo 1 &gt; /proc/sys/kernel/lock_stat</pre></li>
+<li>运行您的测试。</li>
+<li>停用跟踪:<pre>$ echo 0 &gt; /proc/sys/kernel/lock_stat</pre></li>
+<li>转储您的跟踪记录:<pre>$ cat /proc/lock_stat &gt; /data/local/tmp/lock_stat</pre></li>
+</ol>
+
+<p>有关解释所生成的输出结果的帮助内容,请参阅 lockstat 文档:<a href="https://www.kernel.org/doc/Documentation/locking/lockstat.txt"><code>&lt;kernel&gt;/Documentation/locking/lockstat.txt</code></a>。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/jank_capacity.html b/zh-cn/devices/tech/debug/jank_capacity.html
new file mode 100644
index 00000000..9e39328e
--- /dev/null
+++ b/zh-cn/devices/tech/debug/jank_capacity.html
@@ -0,0 +1,63 @@
+<html devsite><head>
+ <title>识别与负载能力相关的卡顿</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>负载能力是设备在一段时间内拥有的某种资源(CPU、GPU 等)的总量。本页介绍了如何识别和应对负载能力相关的卡顿问题。</p>
+
+<h2 id="governor">调节器反应缓慢</h2>
+<p>要避免卡顿,CPU 频率调节器必须能对突发性的工作负载做出快速响应。大多数界面应用出现卡顿的规律基本上是一样的:</p>
+<ol>
+<li>用户浏览屏幕。</li>
+<li>用户触摸屏幕:点按某个按钮、滚动等</li>
+<li>屏幕滚动、更改活动,或以某种动画方式响应输入。</li>
+<li>随着新内容的显示,系统发生停顿。</li>
+<li>用户返回以浏览屏幕。</li>
+</ol>
+
+<p>Pixel 和 Nexus 设备实施了触摸增强,以修改 CPU 频率调节器(和调度程序)应对触摸的行为。为了避免系统缓慢爬升到高时钟频率(这可能会导致触摸时掉帧),触摸增强通常会在 CPU 上设置频率下限,以确保在用户触摸时有足够的 CPU 负载能力。下限设置会在用户触摸后持续一定时间(通常为 2 秒左右)。</p>
+
+<p>Pixel 还会使用 Energy Aware Scheduling (EAS) 提供的 schedtune cgroup 作为额外触摸增强信号:顶层应用可通过 schedtune 增加权重,以确保获得足够的 CPU 负载能力来实现快速运行。在 Nexus 5X 和 6P 上,小 CPU 集群与大 CPU 集群(分别是 A53 和 A57)之间的性能差距大于采用 Kryo CPU 的 Pixel。我们发现,小 CPU 集群并不能始终保证界面顺畅呈现,尤其是在设备上存在其他抖动来源时。</p>
+
+<p>相应地,在 Nexus 5X 和 6P 上,触摸增强会修改调度程序行为,使前台应用更有可能移动到大核心上(从概念上类似于 CPU 频率下限)。如果不进行调度程序更改以增加前台应用移动到大 CPU 集群的可能性,则在调度程序决定将线程均衡负载到大 CPU 核心之前,前台应用可能没有足够的 CPU 负载能力来进行呈现。通过在触摸增强期间更改调度程序行为,界面线程更有可能立即在大核心上运行并避免卡顿,同时又不会强制它始终在大核心上运行(这会对耗电量造成严重影响)。</p>
+
+<h2 id="thermal-throttling">温控调频</h2>
+<p>当设备必须减少整体热输出时,则会发生温控调频,通常通过减少 CPU、GPU 和 DRAM 时钟周期数来执行。毫无意外,这通常会导致卡顿,因为系统可能无法再在给定的时间片内提供足够的负载能力来进行呈现。避免温控调频的唯一方法是减少用电量。实现这一目标的方法不是很多,不过根据我们处理以往 SOC 的经验,我们可以为系统供应商提供一些建议。</p>
+
+<p>首先,在使用异构 CPU 架构构建新 SOC 时,请确保 CPU 集群的性能(功耗)曲线重叠在一起。整个处理器的整体性能(功耗)曲线应该是一条连续的线。性能(功耗)曲线不连续会迫使调度程序和频率调节器猜测工作负载的需要;为避免卡顿,调度程序和频率调节器会为工作负载提供超过实际要求的负载能力。这样会导致消耗过多电量,进而导致温控调频。</p>
+
+<p>假设 SOC 有两个 CPU 集群:</p>
+<ul>
+<li>集群 1 是小集群,功耗为 100-300mW,根据基于时钟数的吞吐量基准,其得分为 100-300。</li>
+<li>集群 2 是大集群,功耗为 1000-1600mW,根据基于时钟数的吞吐量基准,其得分为 800-1200。</li>
+</ul>
+<p>在此基准测试中,得分越高,速度越快。不过,就可取性而言,快速并不比慢速更富吸引力,因为速度快意味着耗电量高。</p>
+
+<p>如果调度程序认为界面工作负载需要 310 分(根据该吞吐量基准)的负载能力,则避免卡顿的最佳选择是以最低频率运行大集群,但会浪费大量电量。(这取决于 cpuidle 行为和加速进入闲置模式;拥有连续性能(功耗)曲线的 SOC 更易于优化。)</p>
+
+<p>其次,使用 cpuset。确保您已在内核和 <code>BoardConfig.mk</code> 中启用了 cpuset。您还必须在设备特有的 <code>init.rc</code> 中设置实际的 cpuet 分配。一些供应商并未在自己的 BSP 中启用 cpuset,而是寄希望于能够使用其他提示来影响调度程序的行为,我们认为这种做法不可取。cpuset 之所以有助于确保 CPU 之间的负载平衡,其方法是反映出用户在设备上实际进行的操作。</p>
+
+<p>ActivityManager 会根据应用(最上层应用、前台应用、后台应用)的相对重要程度,将应用分配到不同的 cpuset,更重要的应用使用 CPU 核心的权限更高。这有助于确保前台和最上层应用的服务质量。</p>
+
+<p>cpusets 对于同构 CPU 配置很有用,但您不应在未启用 cpuset 的情况下为设备实施异构 CPU 配置。Nexus 6P 是关于如何基于异构 CPU 配置使用 cpuset 的范例;您可以使用它作为皆准来配置自己的设备。</p>
+
+<p>cpuset 还有助于降低功耗,它可以确保非性能关键型的后台线程不会被均衡负载到大 CPU 核心,从而不会发生耗电量大幅增加而用户方面无任何受益的情况。这也有助于避免温控调频。虽然温控调频是负载能力问题,但抖动改进也会对温控调频期间的界面性能产生巨大影响。由于系统的运行会更加接近呈现 60 帧/秒所需的负载能力,因此会更容易因为抖动而掉帧。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/native-crash.html b/zh-cn/devices/tech/debug/native-crash.html
new file mode 100644
index 00000000..e5018bde
--- /dev/null
+++ b/zh-cn/devices/tech/debug/native-crash.html
@@ -0,0 +1,400 @@
+<html devsite><head>
+ <title>诊断原生代码崩溃问题</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>如果您之前从未遇到过原生代码崩溃问题,请从<a href="/devices/tech/debug/index.html">调试原生 Android 平台代码</a>着手。
+</p>
+
+<h2 id="crashtypes">原生代码崩溃问题的类型</h2>
+<p>以下部分详细介绍了最常见的几类原生代码崩溃问题。每类崩溃问题都包含一段 <code>debuggerd</code> 输出示例,其中的关键证据可以帮助您区分特定类型的崩溃问题(以橙色斜体突出显示)。
+</p>
+<h3 id="abort">中止</h3>
+<p>中止操作很有趣,因为这是刻意而为。中止方法多种多样(包括调用 <code><a href="http://man7.org/linux/man-pages/man3/abort.3.html">abort(3)</a></code>、<code><a href="http://man7.org/linux/man-pages/man3/assert.3.html">assert(3)</a></code> 失败、使用 Android 专用的严重记录类型之一),但所有这些方法都涉及调用 <code>abort</code>。调用 <code>abort</code> 基本上表示调用的线程附加了 SIGABRT,因此在 <code>libc.so</code> 中有 SIGABRT 并显示“abort”的帧是要在 <code>debuggerd</code> 的输出中查找以识别这种情况。
+
+</p><p>如上文所述,可能会显示明确的“中止消息”行。不过,您还应该查看 <code>logcat</code> 输出,看看此线程在刻意终止自身之前记录的内容,因为基本的中止基元不接受消息。
+</p>
+<p>旧版 Android(特别是 32 位 ARM 的 Android)遵循原始中止调用(此处为帧 4)与信号实际发送(此处为帧 0)之间的复杂路径:</p>
+<pre class="no-pretty-print">
+pid: 1656, tid: 1656, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 6 (<i style="color:Orange">SIGABRT</i>), code -6 (SI_TKILL), fault addr --------
+<i style="color:Orange">Abort message</i>: 'some_file.c:123: some_function: assertion "false" failed'
+ r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8
+ r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c
+ r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c
+ ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010
+backtrace:
+ #00 pc 00042c98 /system/lib/libc.so (tgkill+12)
+ #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32)
+ #02 pc 0001bb87 /system/lib/libc.so (raise+10)
+ #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34)
+ #04 pc 000168e8 /system/lib/<i style="color:Orange">libc.so</i> (<i style="color:Orange">abort</i>+4)
+ #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16)
+ #06 pc 00018d35 /system/lib/libc.so (__assert2+20)
+ #07 pc 00000f21 /system/xbin/crasher
+ #08 pc 00016795 /system/lib/libc.so (__libc_init+44)
+ #09 pc 00000abc /system/xbin/crasher
+</pre>
+<p>较新版本直接从 <code>abort</code> 调用 <code><a href="http://man7.org/linux/man-pages/man2/tgkill.2.html">tgkill(2)</a></code>,因此您在到达所关注帧之前需要跳过的堆栈帧更少:</p><pre class="no-pretty-print">pid: 25301, tid: 25301, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+ r0 00000000 r1 000062d5 r2 00000006 r3 00000008
+ r4 ffa09dd8 r5 000062d5 r6 000062d5 r7 0000010c
+ r8 00000000 r9 00000000 sl 00000000 fp ffa09f0c
+ ip 00000000 sp ffa09dc8 lr eac63ce3 pc eac93f0c cpsr 000d0010
+backtrace:
+ #00 pc 00049f0c /system/lib/libc.so (tgkill+12)
+ #01 pc 00019cdf /system/lib/libc.so (abort+50)
+ #02 pc 000012db /system/xbin/crasher (maybe_abort+26)
+ #03 pc 000015b7 /system/xbin/crasher (do_action+414)
+ #04 pc 000020d5 /system/xbin/crasher (main+100)
+ #05 pc 000177a1 /system/lib/libc.so (__libc_init+48)
+ #06 pc 000010e4 /system/xbin/crasher (_start+96)
+</pre>
+<p>您可以使用 <code>crasher
+abort</code> 重现此类崩溃问题的实例
+</p>
+<h3 id="nullpointer">纯 Null 指针解引用</h3>
+<p>这是典型的原生代码崩溃问题,虽然它只是下一类崩溃问题的特殊情况,但值得单独说明,因为这类崩溃问题通常无需细细思量。
+</p>
+<p>在以下示例中,尽管崩溃函数在 <code>libc.so</code> 中,但因为字符串函数仅在指定给它们的指针上进行操作,所以您可以推断出 <code><a href="http://man7.org/linux/man-pages/man3/strlen.3.html">strlen(3)</a></code> 通过 Null 指针进行调用,且此类崩溃问题应直接发送给调用代码的作者。在这种情况下,帧 #01 是不良调用程序。
+</p>
+
+<pre class="no-pretty-print">pid: 25326, tid: 25326, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 11 (<i style="color:Orange">SIGSEGV</i>), code 1 (SEGV_MAPERR), <i style="color:Orange">fault addr 0x0</i>
+ r0 00000000 r1 00000000 r2 00004c00 r3 00000000
+ r4 ab088071 r5 fff92b34 r6 00000002 r7 fff92b40
+ r8 00000000 r9 00000000 sl 00000000 fp fff92b2c
+ ip ab08cfc4 sp fff92a08 lr ab087a93 pc efb78988 cpsr 600d0030
+
+backtrace:
+ #00 pc 00019988 /system/lib/libc.so (strlen+71)
+ #01 pc 00001a8f /system/xbin/crasher (strlen_null+22)
+ #02 pc 000017cd /system/xbin/crasher (do_action+948)
+ #03 pc 000020d5 /system/xbin/crasher (main+100)
+ #04 pc 000177a1 /system/lib/libc.so (__libc_init+48)
+ #05 pc 000010e4 /system/xbin/crasher (_start+96)
+</pre>
+<p>您可以使用 <code>crasher
+strlen-NULL</code> 重现此类崩溃问题的实例
+</p>
+<h3 id="lowaddress">低地址 Null 指针解引用</h3>
+<p>在许多情况下,故障地址不会为 0,而是其他一些小数字。两位或三位地址尤其常见,而六位地址几乎肯定不是 Null 指针解引用 - 这需要 1 MiB 的偏移量。通常,当您有代码将 Null 指针解引用为看似有效的结构时,就会发生这种情况。常见的函数是 <code><a href="http://man7.org/linux/man-pages/man3/fprintf.3.html">fprintf(3)</a></code>(或任何其他使用 FILE* 的函数)和 <code><a href="http://man7.org/linux/man-pages/man3/readdir.3.html">readdir(3)</a></code>,因为代码通常无法确认是 <code><a href="http://man7.org/linux/man-pages/man3/fopen.3.html">fopen(3)</a></code> 还是 <code><a href="http://man7.org/linux/man-pages/man3/opendir.3.html">opendir(3)</a></code> 实际首先成功调用。
+
+</p><p>以下是 <code>readdir</code> 的示例:</p>
+<pre class="no-pretty-print">pid: 25405, tid: 25405, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 11 (<i style="color:Orange">SIGSEGV</i>), code 1 (SEGV_MAPERR), <i style="color:Orange">fault addr 0xc</i>
+ r0 0000000c r1 00000000 r2 00000000 r3 3d5f0000
+ r4 00000000 r5 0000000c r6 00000002 r7 ff8618f0
+ r8 00000000 r9 00000000 sl 00000000 fp ff8618dc
+ ip edaa6834 sp ff8617a8 lr eda34a1f pc eda618f6 cpsr 600d0030
+
+backtrace:
+ #00 pc 000478f6 /system/lib/libc.so (pthread_mutex_lock+1)
+ #01 pc 0001aa1b /system/lib/libc.so (readdir+10)
+ #02 pc 00001b35 /system/xbin/crasher (readdir_null+20)
+ #03 pc 00001815 /system/xbin/crasher (do_action+976)
+ #04 pc 000021e5 /system/xbin/crasher (main+100)
+ #05 pc 000177a1 /system/lib/libc.so (__libc_init+48)
+ #06 pc 00001110 /system/xbin/crasher (_start+96)
+</pre>
+<p>这里,崩溃问题的直接原因是 <code><a href="http://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html">pthread_mutex_lock(3)</a></code> 尝试访问地址 0xc(帧 0)。但是 <code>pthread_mutex_lock</code> 执行的第一项操作是解引用指定给它的 <code>pthread_mutex_t*</code> 的 <code>state</code> 元素。如果您查看源代码,则会发现该元素在结构中的偏移量为零,这表示指定给 <code>pthread_mutex_lock</code> 的指针 0xc 无效。从帧 1 可以看出,<code>readdir</code> 将该指针指定给它,这会从指定的 <code>DIR*</code> 中提取 <code>mutex_</code> 字段。通过查看该结构,您会发现 <code>struct DIR</code> 中 <code>mutex_</code> 的偏移量为 <code>sizeof(int) + sizeof(size_t) + sizeof(dirent*)</code>,在 32 位设备上即 4 + 4 + 4 = 12 = 0xc,由此找到错误所在:调用程序向 <code>readdir</code> 传递了一个 Null 指针。此时,您可以将该堆栈粘贴到堆栈工具中,以找出这个问题在 logcat 中的发生位置。<em></em>
+
+</p><pre class="no-pretty-print">
+ struct DIR {
+ int fd_;
+ size_t available_bytes_;
+ dirent* next_;
+ pthread_mutex_t mutex_;
+ dirent buff_[15];
+ long current_pos_;
+ };
+</pre>
+<p>在大多数情况下,实际上您可以跳过此分析。一个充分的低位故障地址通常意味着您可以跳过堆栈中的任意 <code>libc.so</code> 帧,并直接归咎于调用的代码。但情况并非总是如此,这些例外将是您用作展示的绝佳机会。
+</p>
+<p>您可以使用 <code>crasher
+fprintf-NULL</code> 或 <code>crasher readdir-NULL</code> 重现此类崩溃问题的实例
+</p>
+<h3 id="fortify">FORTIFY 失败</h3>
+<p>FORTIFY 失败是中止的一种特殊情况,当 C 库检测到可能导致安全漏洞的问题时,就会发生 FORTIFY 失败。很多 C 库函数已得到加强;它们需要一个额外的参数来确定缓冲区的实际大小,并在运行时检查您尝试执行的操作是否真的适合。<em></em>以下示例显示代码尝试 <code>read(fd, buf, 32)</code> 入实际上只有 10 字节长的缓冲区…
+</p>
+<pre class="no-pretty-print">pid: 25579, tid: 25579, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+Abort message: '<i style="color:Orange">FORTIFY: read: prevented 32-byte write into 10-byte buffer'</i>
+ r0 00000000 r1 000063eb r2 00000006 r3 00000008
+ r4 ff96f350 r5 000063eb r6 000063eb r7 0000010c
+ r8 00000000 r9 00000000 sl 00000000 fp ff96f49c
+ ip 00000000 sp ff96f340 lr ee83ece3 pc ee86ef0c cpsr 000d0010
+
+backtrace:
+ #00 pc 00049f0c /system/lib/libc.so (tgkill+12)
+ #01 pc 00019cdf /system/lib/libc.so (abort+50)
+ #02 pc 0001e197 /system/lib/libc.so (<i style="color:Orange">__fortify_fatal</i>+30)
+ #03 pc 0001baf9 /system/lib/libc.so (__read_chk+48)
+ #04 pc 0000165b /system/xbin/crasher (do_action+534)
+ #05 pc 000021e5 /system/xbin/crasher (main+100)
+ #06 pc 000177a1 /system/lib/libc.so (__libc_init+48)
+ #07 pc 00001110 /system/xbin/crasher (_start+96)
+</pre>
+<p>您可以使用 <code>crasher
+fortify</code> 重现此类型崩溃问题的实例
+</p>
+<h3 id="stackcorruption">-fstack-protector 检测到的堆栈损坏</h3>
+<p>编译器的 <code>-fstack-protector</code> 选项会在具有栈上缓冲区的函数中插入检查机制,以防止缓冲区溢出。默认情况下,此选项会为平台代码而非应用启用。如果启用此选项,编译器会向<a href="https://en.wikipedia.org/wiki/Function_prologue">函数序言</a>添加指令,以在堆栈上写入刚刚超过上一局部值的随机值,并向函数结尾添加指令以进行回读并确认是否发生更改。如果该值已更改,则已被缓冲区溢出覆盖,因此该结尾会调用 <code>__stack_chk_fail</code> 来记录消息和中止。
+</p>
+<pre class="no-pretty-print">pid: 26717, tid: 26717, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+<i style="color:Orange">Abort message: 'stack corruption detected'</i>
+ r0 00000000 r1 0000685d r2 00000006 r3 00000008
+ r4 ffd516d8 r5 0000685d r6 0000685d r7 0000010c
+ r8 00000000 r9 00000000 sl 00000000 fp ffd518bc
+ ip 00000000 sp ffd516c8 lr ee63ece3 pc ee66ef0c cpsr 000e0010
+
+backtrace:
+ #00 pc 00049f0c /system/lib/libc.so (tgkill+12)
+ #01 pc 00019cdf /system/lib/libc.so (abort+50)
+ #02 pc 0001e07d /system/lib/libc.so (__libc_fatal+24)
+ #03 pc 0004863f /system/lib/libc.so (<i style="color:Orange">__stack_chk_fail</i>+6)
+ #04 pc 000013ed /system/xbin/crasher (smash_stack+76)
+ #05 pc 00001591 /system/xbin/crasher (do_action+280)
+ #06 pc 00002219 /system/xbin/crasher (main+100)
+ #07 pc 000177a1 /system/lib/libc.so (__libc_init+48)
+ #08 pc 00001144 /system/xbin/crasher (_start+96)
+</pre>
+<p>您可以通过回溯中是否出现 <code>__stack_chk_fail</code> 以及特定中止消息将此中止与其他类型的中止区分开来。
+</p>
+<p>您可以使用 <code>crasher
+smash-stack</code> 重现此类型崩溃问题的实例
+</p>
+
+<h2 id="crashdump">崩溃转储</h2>
+
+<p>如果您现在没有正在调查的特定崩溃问题,则平台来源包括用于测试 <code>debuggerd</code> 的工具,名为 crasher。如果您在 <code>system/core/debuggerd/</code> 中 <code>mm</code>,则您的路径中会出现 <code>crasher</code> 和 <code>crasher64</code>(您可以借助后者测试 64 位崩溃问题)。根据您提供的命令行参数,crasher 崩溃的方式多种多样。使用 <code>crasher --help</code> 可查看当前支持的选择。</p>
+
+<p>为了介绍崩溃转储中的各个方面,我们来看看以下崩溃转储示例:</p>
+
+<pre class="no-pretty-print">
+*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+Build fingerprint: 'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys'
+Revision: '0'
+ABI: 'arm'
+pid: 1656, tid: 1656, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+Abort message: 'some_file.c:123: some_function: assertion "false" failed'
+ r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8
+ r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c
+ r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c
+ ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010
+backtrace:
+ #00 pc 00042c98 /system/lib/libc.so (tgkill+12)
+ #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32)
+ #02 pc 0001bb87 /system/lib/libc.so (raise+10)
+ #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34)
+ #04 pc 000168e8 /system/lib/libc.so (abort+4)
+ #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16)
+ #06 pc 00018d35 /system/lib/libc.so (__assert2+20)
+ #07 pc 00000f21 /system/xbin/crasher
+ #08 pc 00016795 /system/lib/libc.so (__libc_init+44)
+ #09 pc 00000abc /system/xbin/crasher
+Tombstone written to: /data/tombstones/tombstone_06
+</pre>
+
+<pre class="no-pretty-print">*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***</pre>
+
+<p>如果您要搜索原生代码崩溃问题的日志,则带有空格的星号行很有帮助。字符串“*** ***”很少出现在日志中,除了在原生代码崩溃问题开始的时候。</p>
+
+<pre class="no-pretty-print">
+Build fingerprint:
+'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys'
+</pre>
+
+<p>您可以通过指纹准确识别崩溃问题发生的版本号。这与 <code>ro.build.fingerprint</code> 系统属性完全相同。</p>
+
+<pre class="no-pretty-print">
+Revision: '0'
+</pre>
+
+<p>revision 指的是硬件,而不是软件。通常情况下不使用 revision,但使用 revision 有助于您自动忽略由不良硬件导致的已知错误。这与 <code>ro.revision</code> 系统属性完全相同。</p>
+
+<pre class="no-pretty-print">
+ABI: 'arm'
+</pre>
+
+<p>ABI 是 arm、arm64、mips、mips64、x86 或 x86-64 之一。这对上面提到的 <code>stack</code> 脚本最有用,这样它就知道要使用的工具链。</p>
+
+<pre class="no-pretty-print">
+pid: 1656, tid: 1656, name: crasher &gt;&gt;&gt; crasher &lt;&lt;&lt;
+</pre>
+
+<p>此行可标识崩溃进程中的特定线程。在这种情况下,它是进程的主线程,因此进程 ID 和线程 ID 一致。第一个名称是线程名称,在 &gt;&gt;&gt; 和 &lt;&lt;&lt; 中间的名称是进程名称。对于应用,进程名称通常是完全限定的文件包名称(如 com.facebook.katana),这在提交错误或尝试在 Google Play 中查找相应应用时很有用。在查找崩溃问题之前的相关日志行方面,pid 和 tid 也很有用。</p>
+
+<pre class="no-pretty-print">
+signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+</pre>
+
+<p>您可从该行得知接收的信号 (SIGABRT) 以及有关如何接收该信号的更多信息 (SI_TKILL)。<code>debuggerd</code> 报告的信号是 SIGABRT、SIGBUS、SIGFPE、SIGILL、SIGSEGV 和 SIGTRAP。信号专用的代码因特定信号而异。</p>
+
+<pre class="no-pretty-print">
+Abort message: 'some_file.c:123: some_function: assertion "false" failed'
+</pre>
+
+<p>并非所有崩溃问题都会有中止消息行,但发生中止时,会出现该消息行。这是从此 pid/tid 的最后一行严重 logcat 输出中自动收集而来的,而在有意中止的情况下,这可以解释该程序自行终止的原因。</p>
+
+<pre class="no-pretty-print">
+r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8
+r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c
+r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c
+ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010
+</pre>
+
+<p>寄存器转储显示收到信号时 CPU 寄存器的内容。(本区段在各 ABI 之间变化很大。)这些内容的有用程度取决于确切的崩溃问题。</p><p>
+
+</p><pre class="no-pretty-print">
+backtrace:
+ #00 pc 00042c98 /system/lib/libc.so (tgkill+12)
+ #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32)
+ #02 pc 0001bb87 /system/lib/libc.so (raise+10)
+ #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34)
+ #04 pc 000168e8 /system/lib/libc.so (abort+4)
+ #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16)
+ #06 pc 00018d35 /system/lib/libc.so (__assert2+20)
+ #07 pc 00000f21 /system/xbin/crasher
+ #08 pc 00016795 /system/lib/libc.so (__libc_init+44)
+ #09 pc 00000abc /system/xbin/crasher
+</pre>
+
+<p>您可以通过回溯得知崩溃问题发生时我们所处的代码位置。第一列是帧号(与 gdb 的样式一致,其中最底下的帧是 0)。PC 值与共享库的位置(而非绝对地址)相关。下一列是映射区域的名称(通常是共享库或可执行文件,但可能不适用于经过 JIT 编译的代码)。最后,如果有符号,则会显示与 PC 值对应的符号以及到该符号的偏移量(以字节为单位)。您可以结合使用此符号和 <code>objdump(1)</code> 来找到相应的编译器指令。</p>
+
+<h2 id="tombstones">Tombstone</h2>
+
+<pre class="no-pretty-print">
+Tombstone written to: /data/tombstones/tombstone_06
+</pre>
+
+<p>您可由此得知 <code>debuggerd</code> 写入额外信息的位置。
+<code>debuggerd</code> 会保留最多 10 个 tombstone,从编号 00 至 09 循环并根据需要覆盖现有 tombstone。</p>
+
+<p>Tombstone 包含与崩溃转储相同的信息,还包含一些其他信息。例如,它包含所有线程的回溯(不仅仅是崩溃线程)、浮点寄存器、寄存器中地址周围的原始堆栈转储和内存转储。<i></i>最有用的是,它还包含完整的内存映射(类似于 <code>/proc/<i>pid</i>/maps</code>)。以下是 32 位 ARM 进程崩溃的注释示例:</p>
+
+<pre class="no-pretty-print">
+memory map: (fault address prefixed with ---&gt;)
+---&gt;ab15f000-ab162fff r-x 0 4000 /system/xbin/crasher (BuildId:
+b9527db01b5cf8f5402f899f64b9b121)
+</pre>
+
+<p>这里需要注意两点。第一点是该行带有前缀“---&gt;”。当您的崩溃问题不仅仅是 Null 指针解引用时,这些映射最有用。如果故障地址较小,则其很可能是 Null 指针解引用的某个变体。否则,通过查看故障地址周围的映射,您通常可以了解发生的问题。通过查看映射可识别的一些可能存在的问题包括:</p>
+
+<ul>
+<li>读/写延伸到内存块末尾之外。</li>
+<li>在内存块开始之前读/写。</li>
+<li>尝试执行非代码内容。</li>
+<li>在堆栈末尾之外运行。</li>
+<li>尝试写入代码(如上例所述)。</li>
+</ul>
+
+<p>需要注意的第二点是,可执行文件和共享库文件将在 Android M 和更高版本中显示 BuildId(如果有),因此您可以确切地看到崩溃代码的版本。(从 Android M 开始,平台二进制文件默认包含 BuildId。NDK r12 和更高版本还会自动将 <code>-Wl,--build-id</code> 传递到链接器。)</p><p>
+
+</p><pre class="no-pretty-print">
+ab163000-ab163fff r-- 3000 1000 /system/xbin/crasher
+ab164000-ab164fff rw- 0 1000
+f6c80000-f6d7ffff rw- 0 100000 [anon:libc_malloc]
+</pre>
+
+<p>在 Android 上,该堆不一定是单个区域。堆区域将被标记为 <code>[anon:libc_malloc]</code>。</p>
+
+<pre class="no-pretty-print">
+f6d82000-f6da1fff r-- 0 20000 /dev/__properties__/u:object_r:logd_prop:s0
+f6da2000-f6dc1fff r-- 0 20000 /dev/__properties__/u:object_r:default_prop:s0
+f6dc2000-f6de1fff r-- 0 20000 /dev/__properties__/u:object_r:logd_prop:s0
+f6de2000-f6de5fff r-x 0 4000 /system/lib/libnetd_client.so (BuildId: 08020aa06ed48cf9f6971861abf06c9d)
+f6de6000-f6de6fff r-- 3000 1000 /system/lib/libnetd_client.so
+f6de7000-f6de7fff rw- 4000 1000 /system/lib/libnetd_client.so
+f6dec000-f6e74fff r-x 0 89000 /system/lib/libc++.so (BuildId: 8f1f2be4b37d7067d366543fafececa2) (load base 0x2000)
+f6e75000-f6e75fff --- 0 1000
+f6e76000-f6e79fff r-- 89000 4000 /system/lib/libc++.so
+f6e7a000-f6e7afff rw- 8d000 1000 /system/lib/libc++.so
+f6e7b000-f6e7bfff rw- 0 1000 [anon:.bss]
+f6e7c000-f6efdfff r-x 0 82000 /system/lib/libc.so (BuildId: d189b369d1aafe11feb7014d411bb9c3)
+f6efe000-f6f01fff r-- 81000 4000 /system/lib/libc.so
+f6f02000-f6f03fff rw- 85000 2000 /system/lib/libc.so
+f6f04000-f6f04fff rw- 0 1000 [anon:.bss]
+f6f05000-f6f05fff r-- 0 1000 [anon:.bss]
+f6f06000-f6f0bfff rw- 0 6000 [anon:.bss]
+f6f0c000-f6f21fff r-x 0 16000 /system/lib/libcutils.so (BuildId: d6d68a419dadd645ca852cd339f89741)
+f6f22000-f6f22fff r-- 15000 1000 /system/lib/libcutils.so
+f6f23000-f6f23fff rw- 16000 1000 /system/lib/libcutils.so
+f6f24000-f6f31fff r-x 0 e000 /system/lib/liblog.so (BuildId: e4d30918d1b1028a1ba23d2ab72536fc)
+f6f32000-f6f32fff r-- d000 1000 /system/lib/liblog.so
+f6f33000-f6f33fff rw- e000 1000 /system/lib/liblog.so
+</pre>
+
+<p>通常,共享库会有 3 个相邻条目。一个是可读且可执行条目(代码),一个是只读条目(只读数据),还有一个是读写条目(可变数据)。第一列显示映射的地址范围,第二列显示权限(采用常规 Unix <code>ls(1)</code> 样式),第三列显示到文件的偏移量(十六进制),第四列显示区域大小(十六进制),第五列显示文件(或其他区域名称)。</p>
+
+<pre class="no-pretty-print">
+f6f34000-f6f53fff r-x 0 20000 /system/lib/libm.so (BuildId: 76ba45dcd9247e60227200976a02c69b)
+f6f54000-f6f54fff --- 0 1000
+f6f55000-f6f55fff r-- 20000 1000 /system/lib/libm.so
+f6f56000-f6f56fff rw- 21000 1000 /system/lib/libm.so
+f6f58000-f6f58fff rw- 0 1000
+f6f59000-f6f78fff r-- 0 20000 /dev/__properties__/u:object_r:default_prop:s0
+f6f79000-f6f98fff r-- 0 20000 /dev/__properties__/properties_serial
+f6f99000-f6f99fff rw- 0 1000 [anon:linker_alloc_vector]
+f6f9a000-f6f9afff r-- 0 1000 [anon:atexit handlers]
+f6f9b000-f6fbafff r-- 0 20000 /dev/__properties__/properties_serial
+f6fbb000-f6fbbfff rw- 0 1000 [anon:linker_alloc_vector]
+f6fbc000-f6fbcfff rw- 0 1000 [anon:linker_alloc_small_objects]
+f6fbd000-f6fbdfff rw- 0 1000 [anon:linker_alloc_vector]
+f6fbe000-f6fbffff rw- 0 2000 [anon:linker_alloc]
+f6fc0000-f6fc0fff r-- 0 1000 [anon:linker_alloc]
+f6fc1000-f6fc1fff rw- 0 1000 [anon:linker_alloc_lob]
+f6fc2000-f6fc2fff r-- 0 1000 [anon:linker_alloc]
+f6fc3000-f6fc3fff rw- 0 1000 [anon:linker_alloc_vector]
+f6fc4000-f6fc4fff rw- 0 1000 [anon:linker_alloc_small_objects]
+f6fc5000-f6fc5fff rw- 0 1000 [anon:linker_alloc_vector]
+f6fc6000-f6fc6fff rw- 0 1000 [anon:linker_alloc_small_objects]
+f6fc7000-f6fc7fff rw- 0 1000 [anon:arc4random _rsx structure]
+f6fc8000-f6fc8fff rw- 0 1000 [anon:arc4random _rs structure]
+f6fc9000-f6fc9fff r-- 0 1000 [anon:atexit handlers]
+f6fca000-f6fcafff --- 0 1000 [anon:thread signal stack guard page]
+</pre>
+
+<p>请注意,从 Android 5.0 (Lollipop) 开始,C 库会对其大部分匿名映射区域命名,因此神秘区域越来越少。
+</p>
+
+<pre class="no-pretty-print">
+f6fcb000-f6fccfff rw- 0 2000 [stack:5081]
+</pre>
+
+<p>名为 <code>[stack:<i>tid</i>]</code> 的区域是指定线程的堆栈。
+</p>
+
+<pre class="no-pretty-print">
+f6fcd000-f702afff r-x 0 5e000 /system/bin/linker (BuildId: 84f1316198deee0591c8ac7f158f28b7)
+f702b000-f702cfff r-- 5d000 2000 /system/bin/linker
+f702d000-f702dfff rw- 5f000 1000 /system/bin/linker
+f702e000-f702ffff rw- 0 2000
+f7030000-f7030fff r-- 0 1000
+f7031000-f7032fff rw- 0 2000
+ffcd7000-ffcf7fff rw- 0 21000
+ffff0000-ffff0fff r-x 0 1000 [vectors]
+</pre>
+
+<p>您能否看到 <code>[vector]</code> 或 <code>[vdso]</code> 取决于架构。ARM 使用 [vector],而所有其他架构使用 <a href="http://man7.org/linux/man-pages/man7/vdso.7.html">[vdso]</a>。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/netstats.html b/zh-cn/devices/tech/debug/netstats.html
new file mode 100644
index 00000000..f22e35a2
--- /dev/null
+++ b/zh-cn/devices/tech/debug/netstats.html
@@ -0,0 +1,125 @@
+<html devsite><head>
+ <title>查看网络使用情况数据</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>使用命令 <code>adb shell dumpsys netstats detail</code> 提供自设备启动后收集的网络使用情况统计信息。</p>
+
+<h2 id="input">输入</h2>
+
+<p>要查看网络使用情况统计信息,请运行以下命令:</p>
+
+<pre class="prettyprint">
+$ adb shell dumpsys netstats detail
+</pre>
+
+<h2 id="output">输出</h2>
+
+<p>报告的一系列信息因 Android 的版本而异,但由以下几个部分组成:</p>
+
+<ul>
+ <li> 活动接口
+ </li><li> 活动 UID 接口
+ </li><li> 开发统计信息
+ </li><li> Xt 统计信息
+ </li><li> UID 统计信息(有时也称为“详细的 UID 统计信息”)
+ </li><li> UID 代码统计信息
+</li></ul>
+
+<h3 id="active_interfaces_active_uid_interfaces">活动接口/活动 UID 接口</h3>
+
+<p>以下是活动接口和活动 UID 接口部分的输出示例:</p>
+
+<pre>
+Active interfaces:
+ iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="GoogleGuest"}]
+Active UID interfaces:
+ iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="GoogleGuest"}]
+</pre>
+
+<p>此处显示的是整个设备的网络统计信息。在大多数情况下,这两个部分的信息是相同的。</p>
+
+<h3 id="dev_stats_xt_stats">开发统计信息/Xt 统计信息</h3>
+
+<p>以下是开发统计信息部分的输出示例:</p>
+
+<pre>
+Dev stats:
+  Pending bytes: 170775
+  Complete history:
+  ident=[[type=MOBILE_HIPRI, subType=COMBINED, subscriberId=311111...]] uid=-1 set=ALL tag=0x0
+    NetworkStatsHistory: bucketDuration=3600000
+      bucketStart=1406138400000 activeTime=3603995 rxBytes=19467 rxPackets=53 txBytes=7500 txPackets=61 operations=0
+      bucketStart=1406142000000 activeTime=20730 rxBytes=25403 rxPackets=66 txBytes=9140 txPackets=74 operations=0
+      bucketStart=1406145600000 activeTime=29161 rxBytes=9263 rxPackets=37 txBytes=5180 txPackets=38 operations=0
+      bucketStart=1406149200000 activeTime=9054 rxBytes=12387 rxPackets=31 txBytes=4052 txPackets=35 operations=0
+  ident=[[type=WIFI, subType=COMBINED, networkId="MySSID"]] uid=-1 set=ALL tag=0x0
+    NetworkStatsHistory: bucketDuration=3600000
+      bucketStart=1406138400000 activeTime=4811082 rxBytes=335913292 rxPackets=265144 txBytes=9729261 txPackets=117220 operations=0
+      bucketStart=1406142000000 activeTime=3513477 rxBytes=1193606876 rxPackets=956855 txBytes=29450792 txPackets=306634 operations=0
+      bucketStart=1406145600000 activeTime=3297986 rxBytes=729381849 rxPackets=586396 txBytes=24247211 txPackets=237438 operations=0
+      bucketStart=1406149200000 activeTime=3580941 rxBytes=57168575 rxPackets=51610 txBytes=5291167 txPackets=29260 operations=0
+  ident=[[type=WIFI, subType=COMBINED, networkId="MySecondSSID"]] uid=-1 set=ALL tag=0x0
+    NetworkStatsHistory: bucketDuration=3600000
+</pre>
+
+<h3 id="uid_stats">UID 统计信息</h3>
+
+<pre>
+UID stats:
+  Pending bytes: 744
+  Complete history:
+  ident=[[type=MOBILE_SUPL, subType=COMBINED, subscriberId=311111...], [type=MOBILE, subType=COMBINED, subscriberId=311111...]] uid=10007 set=DEFAULT tag=0x0
+    NetworkStatsHistory: bucketDuration=7200000
+      bucketStart=1406167200000 activeTime=7200000 rxBytes=4666 rxPackets=7 txBytes=1597 txPackets=10 operations=0
+  ident=[[type=WIFI, subType=COMBINED, networkId="MySSID"]] uid=10007 set=DEFAULT tag=0x0
+    NetworkStatsHistory: bucketDuration=7200000
+      bucketStart=1406138400000 activeTime=7200000 rxBytes=17086802 rxPackets=15387 txBytes=1214969 txPackets=8036 operations=28
+      bucketStart=1406145600000 activeTime=7200000 rxBytes=2396424 rxPackets=2946 txBytes=464372 txPackets=2609 operations=70
+      bucketStart=1406152800000 activeTime=7200000 rxBytes=200907 rxPackets=606 txBytes=187418 txPackets=739 operations=0
+      bucketStart=1406160000000 activeTime=7200000 rxBytes=826017 rxPackets=1126 txBytes=267342 txPackets=1175 operations=35
+</pre>
+
+<h3 id="interpreting_the_results">解读结果</h3>
+
+<p>要查找应用的 UID,您可以运行以下命令:
+<code>adb shell dumpsys package &lt;your package name&gt;</code>,
+然后查找标有 <code>userId</code> 的行。</p>
+
+<p>在我们的示例中,假设我们要了解应用“com.example.myapp”的网络使用情况,则可以运行以下命令:</p>
+
+<pre>
+$ adb shell dumpsys package com.example.myapp | grep userId
+
+ userId=10007 gids=[3003, 1028, 1015]
+</pre>
+
+<p>在上面的 dumpsys 命令中,我们查找包含 uid = 10007 的行。符合条件的行有两个,第一个表示移动数据连接,第二个表示 WLAN 连接。在每行的下方,可以看到发送和接收的字节数和数据包数,bucket 为两小时时间窗口。</p>
+
+<p>以下是进一步说明:</p>
+
+<ul>
+ <li> <code>set=DEFAULT</code> 表示前台网络使用情况,<code>set=BACKGROUND</code> 表示后台使用情况,<code>set=ALL</code> 表示上述两类使用情况。
+ </li><li> <code>tag=0x0</code> 表示与流量关联的套接字代码。
+ </li><li> <code>rxBytes</code> 和 <code>rxPackets</code> 表示在相应时间间隔内接收的字节数和数据包数。
+ </li><li> <code>txBytes</code> 和 <code>txPackets</code> 表示在相应时间间隔内发送(传输)的字节数和数据包数。
+</li></ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/strace.html b/zh-cn/devices/tech/debug/strace.html
new file mode 100644
index 00000000..c57d7c4d
--- /dev/null
+++ b/zh-cn/devices/tech/debug/strace.html
@@ -0,0 +1,95 @@
+<html devsite><head>
+ <title>使用 strace</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>通过 <a href="https://strace.io">strace</a>,您可以看到进程执行的系统调用,以及这些系统调用返回的内容。通常情况下,一次进程会执行大量系统调用,因此您需要查看 <a href="http://man7.org/linux/man-pages/man1/strace.1.html">strace 手册页面</a>,了解如何只收集您真正感兴趣的数据。</p>
+
+<h2 id="build-strace">构建 strace</h2>
+
+<p>要构建 strace,请运行以下命令:</p><pre>
+$ mmma -j6 external/strace
+</pre>
+
+<h2 id="attach-strace">附加到正在运行的进程</h2>
+
+<p>对于 strace,最简单和最常见的用例即是附加到正在运行的进程,方法是使用下面这行命令:</p>
+<pre>
+$ adb shell strace -f -p PID
+</pre>
+<p><code>-f</code> 标记表明 strace 会附加到相应进程中的所有现有线程,以及之后会产生的所有新线程。</p>
+
+<h2 id="app-strace">在应用上使用</h2>
+<p>要在应用上使用 strace,请执行以下操作:</p>
+
+<ol>
+<li>为 strace 日志设置一个目录:<pre>
+$ adb shell setenforce 0
+$ adb shell mkdir /data/local/tmp/strace
+$ adb shell chmod 777 /data/local/tmp/strace
+</pre>
+</li>
+
+<li>在启动前选择要跟踪的进程:<pre>
+$ adb shell setprop wrap.com.google.android.browser "logwrapper strace -f -o /data/local/tmp/strace/strace.com.google.android.browser.txt"
+</pre>
+</li>
+<li>正常启动该进程。</li>
+</ol>
+
+<h2 id="zygote-systrace">在 zygote 上使用</h2>
+<p>要在 zygote 上使用 strace,请修复相关的 <code>init.rc</code> zygote 行(需要使用 <code>adb shell setenforce 0</code>):</p>
+
+<pre>
+$ cd system/core/
+$ patch -p1 &lt;&lt;EOF
+--- a/rootdir/init.zygote32.rc
++++ b/rootdir/init.zygote32.rc
+@@ -1,4 +1,4 @@
+-service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
++service zygote /system/xbin/strace -o /data/local/tmp/zygote.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
+ class main
+ socket zygote stream 660 root system
+ onrestart write /sys/android_power/request_state wake
+EOF
+</pre>
+
+<h2 id="get-logs-boot">获取 Android 启动期间的 strace 日志</h2>
+
+<p>要获取 Android 启动期间的 strace 日志,请执行以下更改:</p>
+
+<ul>
+<li>由于进程名称已从 <code>zygote</code> 改为 <code>strace</code>,给定服务可能会因缺少用于 <code>strace</code> 的 SELinux <code>file_context</code> 而无法启动。解决方法:在 <code>system/sepolicy/private/file_contexts</code> 中为 strace 添加一个新行,并将原始文件上下文复制过来。例如:<pre>
+/dev/socket/zygote u:object_r:zygote_socket:s0
++ /system/xbin/strace u:object_r:zygote_socket:s0
+</pre>
+</li>
+
+<li>添加内核命令,然后在 SELinux 宽容模式下启动相应设备。为此,请将 <code>androidboot.selinux=permissive</code> 添加到 <code>BOARD_KERNEL_CMDLINE</code>。(该变量在 <code>build/core/Makefile</code> 中将会变为仅供读取,但在 <code>/device/*/BoardConfig</code> 下则是始终可用。)
+
+<br />
+<br /><code>/device/google/marlin/sailfish/BoardConfig.mk</code> 中 Pixel (sailfish) 设备的示例:<pre>
+- BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ...
++BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... androidboot.selinux=permissive
+</pre>待做出上述更改后,编译并刷写启动映像;这样一来,该设备便会在宽容模式下启动了。
+</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/debug/systrace.html b/zh-cn/devices/tech/debug/systrace.html
new file mode 100644
index 00000000..2cff4c6a
--- /dev/null
+++ b/zh-cn/devices/tech/debug/systrace.html
@@ -0,0 +1,173 @@
+<html devsite><head>
+ <title>了解 Systrace</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 class="caution"><strong>注意</strong>:如果您以前从未使用过 systrace,我们强烈建议您先阅读 <a href="https://developer.android.com/studio/profile/systrace.html">systrace 概览</a>,然后再继续。</p>
+
+<p>systrace 是分析 Android 设备性能的主要工具。不过,它实际上是其他工具的封装容器:它是 atrace 的主机端封装容器,是用于控制用户空间跟踪和设置 ftrace 的设备端可执行文件,也是 Linux 内核中的主要跟踪机制。systrace 使用 atrace 来启用跟踪,然后读取 ftrace 缓冲区并将其全部封装到一个独立的 HTML 查看器中<em></em><em></em>(虽然较新的内核支持 Linux 增强型柏克莱封包过滤器 (eBPF),但以下文档内容仅适用于 3.18 内核(无 eFPF),因为 Pixel/Pixel XL 上使用的是 3.18 内核)。</p>
+
+<p>systrace 归 Google Android 和 Google Chrome 团队所有,且是作为 <a href="https://github.com/catapult-project/catapult">Catapult 项目</a>的一部分在开源环境中开发的。除 systrace 之外,Catapult 还包括其他有用的实用程序。例如,除了可由 systrace 或 atrace 直接启用的功能之外,ftrace 还提供了其他功能,并且包含一些对调试性能问题至关重要的高级功能(这些功能需要 root 访问权限,通常也需要新的内核)。</p>
+
+<h2 id="running_systrace">运行 systrace</h2>
+<p>要在 Pixel/Pixel XL 上调试抖动问题,请从以下命令开始:</p>
+
+<pre>$ ./systrace.py sched freq idle am wm gfx view sync binder_driver irq workq input -b 96000</pre>
+
+<p>当将该命令用于 GPU 活动和显示通道活动所需的附加跟踪点时,您将能够跟踪从用户输入直到屏幕上显示的帧。将缓冲区大小设为较大的值,以避免丢失事件(通常表现为一些 CPU 在跟踪记录中的某个点之后不包含任何事件)。</p>
+
+<p>在使用 systrace 的过程中,请记住,<strong>每个事件都是由 CPU 上的活动触发的</strong>。</p>
+
+<p class="note"><strong>注意</strong>:硬件中断不受 CPU 控制,且会在 ftrace 中触发事件,不过,向跟踪日志的实际提交操作是由中断处理程序完成的,如果您的中断已到达,而(例如)某个其他不良驱动程序已停用中断,则提交可能会延迟。因此,CPU 是关键要素。</p>
+
+<p>因为 systrace 构建于 ftrace 之上,而 ftrace 在 CPU 上运行,所以 CPU 上的活动必须写入用于记录硬件变化情况的 ftrace 缓冲区。这意味着,如果您想知道显示栅栏更改状态的原因,则可以查看在状态转换的确切点 CPU 上运行了哪些活动(在 CPU 上运行的某些活动会触发日志中出现这种更改)。此概念是使用 systrace 分析性能的基础。</p>
+
+<h2 id="example_1">示例:工作帧</h2>
+<p>该示例介绍了用于正常界面通道的 systrace。要按照示例操作,请<a href="perf_traces.zip">下载跟踪记录的 ZIP 文件</a>(包括本节中提及的其他跟踪记录),将文件解压缩,然后在浏览器中打开 systrace_tutorial.html 文件。系统会显示一条警告,提示 systrace 是一个大型文件;除非您在日常工作中使用 systrace,否则这个跟踪记录可能更完整,其中包含的信息比您以前在单个跟踪记录中看到的更多。</p>
+<p>对于一致的周期性工作负载(例如 TouchLatency),界面通道包含以下内容:</p>
+<p></p>
+<ol>
+<li>SurfaceFlinger 中的 EventThread 唤醒应用的界面线程,表明该渲染新帧了。</li>
+<li>应用使用 CPU 和 GPU 资源在界面线程、RenderThread 和 hwuiTasks 中渲染帧。这是界面占用的大部分容量。</li>
+<li>应用通过 Binder 将渲染帧发送到 SurfaceFlinger 并进入休眠状态。</li>
+<li>SurfaceFlinger 中的第二个 EventThread 唤醒 SurfaceFlinger,以触发构图和显示输出。如果 SurfaceFlinger 确定没有任何任务需要执行,它将返回休眠状态。</li>
+<li>SurfaceFlinger 通过 HWC/HWC2 或 GL 处理构图。HWC/HWC2 构图的速度更快且功率更低,但存在限制,具体取决于 SOC。这个步骤通常需要约 4 到 6 毫秒,但是可以与步骤 2 同步进行,因为 Android 应用始终会进行三重缓冲(虽然应用始终会进行三重缓冲,但 SurfaceFlinger 中可能只有一个待处理帧在等待,这样它就看起来与双重缓冲一样)。</li>
+<li>SurfaceFlinger 将通过供应商驱动程序将最终输出调度到显示部分,然后返回休眠状态,等待 EventThread 唤醒。</li>
+</ol>
+
+<p>下面我们详细介绍一下从 15409 毫秒开始的帧:</p>
+
+<p><img src="images/perf_trace_normal_pipeline.png"/></p>
+<p class="img-caption"><strong>图 1. </strong> 正常界面通道(EventThread 正在运行)。</p>
+
+<p>图 1 显示了一个由多个正常帧围绕的正常帧,因此对于理解界面通道的工作原理来说,它是一个很好的切入点。TouchLatency 的界面线程所在行在不同的时间显示为不同的颜色。柱形表示线程的不同状态:</p>
+
+<ul>
+<li><strong>灰色</strong>:正在休眠。</li>
+<li><strong>蓝色</strong>:可运行(它可以运行,但是调度程序尚未选择让它运行)。</li>
+<li><strong>绿色</strong>:正在活跃运行(调度程序认为它正在运行)。
+<p class="note"><strong>注意</strong>:中断处理程序并未在正常的单个 CPU 时间轴中显示,因此您有可能实际上是在线程运行时的某个阶段运行中断处理程序或 softirq。请检查跟踪记录的中断 (irq) 部分(在进程 0 下),以确认中断(而非标准线程)正在运行。</p>
+</li>
+<li><strong>红色</strong>:不可中断休眠(通常在内核中处于休眠锁定状态)。可以指示 I/O 负载,在调试性能问题时非常有用。</li>
+<li><strong>橙色</strong>:由于 I/O 负载而不可中断休眠。</li>
+</ul>
+
+<p>要查看不可中断休眠的原因(可从 <code>sched_blocked_reason</code> 跟踪点获取),请选择红色的不可中断休眠图块。</p>
+<p>当 EventThread 运行时,TouchLatency 的界面线程会变为可运行。要查看是什么唤醒的它,请点击蓝色部分:</p>
+
+<p><img src="images/perf_trace_tl.png"/></p>
+<p class="img-caption"><strong>图 2. </strong> TouchLatency 的界面线程。</p>
+
+<p>图 2 显示了 TouchLatency 的界面线程被与 EventThread 对应的 tid 6843 唤醒。界面线程被唤醒:</p>
+
+<p><img src="images/perf_trace_wake_render_enqueue.png"/></p>
+<p class="img-caption"><strong>图 3. </strong> 界面线程被唤醒、渲染一个帧,并将其加入队列以供 SurfaceFlinger 使用。</p>
+
+<p>如果跟踪记录中的 <code>binder_driver</code> 标记已启用,则您可以选择一个 Binder 事务,并查看该事务涉及的所有进程的相关信息:</p>
+
+<p><img src="images/perf_trace_binder_trans.png"/></p>
+<p class="img-caption"><strong>图 4. </strong> Binder 事务。</p>
+
+<p>图 4 显示了在 15423.65 毫秒,SurfaceFlinger 中的 Binder:6832_1 由于 tid 9579(即 TouchLatency 的 RenderThread)变为可运行。此外,您还可以在 Binder 事务的两侧看到 queueBuffer。</p>
+
+<p>在 SurfaceFlinger 端的 queueBuffer 期间,TouchLatency 中待处理帧的数量从 1 变为 2:</p>
+
+<p><img src="images/perf_trace_pending_frames.png"/></p>
+<p class="img-caption"><strong>图 5. </strong> 待处理帧从 1 个变为 2 个。</p>
+
+<p>图 5 显示了三重缓冲,其中两个帧已完成渲染,应用将很快开始渲染第三个帧。这是因为一些帧已经丢弃,所以应用保留两个待处理的帧而不是一个,以避免以后再丢弃帧。</p>
+
+<p>稍后,SurfaceFlinger 的主线程会被第二个 EventThread 唤醒,以便它可以将较早的待处理帧输出到显示部分:</p>
+
+<p><img src="images/perf_trace_sf_woken_et.png"/></p>
+<p class="img-caption"><strong>图 6. </strong> SurfaceFlinger 的主线程被第二个 EventThread 唤醒。</p>
+
+<p>SurfaceFlinger 首先锁定较早的待处理缓冲区,而这将导致待处理缓冲区的计数从 2 减为 1:</p>
+
+<p><img src="images/perf_trace_sf_latches_pend.png"/></p>
+<p class="img-caption"><strong>图 7. </strong> SurfaceFlinger 首先锁定较早的待处理缓冲区。</p>
+
+<p>锁定缓冲区后,SurfaceFlinger 会设置构图并将最终帧提交给显示部分(其中某些区段作为 <code>mdss</code> 跟踪点的一部分启用,因此它们可能不在您 SOC 的相应位置上)。</p>
+
+<p><img src="images/perf_trace_sf_comp_submit.png"/></p>
+<p class="img-caption"><strong>图 8. </strong> SurfaceFlinger 设置构图并提交最终帧。</p>
+
+<p>接下来,<code>mdss_fb0</code> 在 CPU 0 上被唤醒。<code>mdss_fb0</code> 是显示通道的内核线程,用于将渲染过的帧输出到显示部分。我们可以看到 <code>mdss_fb0</code> 位于跟踪记录中其自己所在行中的情形(向下滚动即可查看)。</p>
+
+<p><img src="images/perf_trace_wake_cpu0.png"/></p>
+<p class="img-caption"><strong>图 9</strong>. <code>mdss_fb0</code> 在 CPU 0 上被唤醒。</p>
+
+<p><code>mdss_fb0</code> 被唤醒,短暂运行,进入不可中断休眠状态,然后再次被唤醒。</p>
+
+<p class="note"><strong>注意</strong>:从此时起,跟踪记录将变得更为复杂,因为最后的工作会在 <code>mdss_fb0</code>、中断和工作队列函数之间划分。如果您需要该级别的详细信息,请参阅您的 SOC 的驱动程序堆栈的确切特性(因为了解 Pixel XL 上发生的活动可能对您并无帮助)。</p>
+
+<h2 id="example_2">示例:非工作帧</h2>
+<p>该示例介绍了用于调试 Pixel/Pixel XL 抖动问题的 systrace。要按照示例操作,请<a href="perf_traces.zip">下载跟踪记录的 ZIP 文件</a>(包括本节中提及的其他跟踪记录),将文件解压缩,然后在浏览器中打开 systrace_tutorial.html 文件。</p>
+
+<p>首次打开 systrace 时,您会看到如下内容:</p>
+
+<p><img src="images/perf_trace_tl_pxl.png"/></p>
+<p class="img-caption"><strong>图 10</strong>. 在 Pixel XL 上运行的 TouchLatency(大多数选项已启用,包括 mdss 和 kgsl 跟踪点)。</p>
+
+<p>查找卡顿时,请检查 SurfaceFlinger 下的 FrameMissed 行。FrameMissed 是一项可提升用户体验的改进,由硬件合成器 2 (HWC2) 提供。自 2016 年 12 月起,HWC2 只能用于 Pixel/Pixel XL;当您查看其他设备的 systrace 时,可能不会看到 FrameMissed 行。在任一情况下,FrameMissed 都会与具有以下特点的 SurfaceFlinger 相关联:缺少一个很常用的运行时,以及在 vsync 时的应用 (<code>com.prefabulated.touchlatency</code>) 存在未更改的待处理缓冲区计数:</p>
+
+<p><img src="images/perf_trace_fm_sf.png"/></p>
+<p class="img-caption"><strong>图 11</strong>. FrameMissed 与 SurfaceFlinger 的关联。</p>
+
+<p>图 11 显示了 15598.29 毫秒处的已丢失帧。SurfaceFlinger 在 vsync 间隔时间被短暂唤醒,并在未执行任何任务的情况下返回休眠状态,这意味着 SurfaceFlinger 确定不值得再次向显示部分发送帧。为什么?</p>
+
+<p>要了解在渲染此帧时通道是如何出现故障的,请先回顾上面的工作帧示例,了解正常界面通道是如何在 systrace 中出现的。准备就绪后,返回到丢失的帧并进行反推。请注意,SurfaceFlinger 被唤醒后立即进入休眠状态。查看来自 TouchLatency 的待处理帧的数量时,可以看到有两个帧(这是一条很好的线索,可帮助弄清楚发生的实际情况)。</p>
+
+<p><img src="images/perf_trace_sf_wake_sleep.png"/></p>
+<p class="img-caption"><strong>图 12. </strong> SurfaceFlinger 被唤醒后立即进入休眠状态。</p>
+
+<p>因为我们在 SurfaceFlinger 中有一些帧,所以这不是一个应用问题。此外,SurfaceFlinger 在正确的时间被唤醒,所以这也不是一个 SurfaceFlinger 问题。如果 SurfaceFlinger 和应用看起来都正常,那么这可能是一个驱动程序问题。</p>
+
+<p>因为启用了 <code>mdss</code> 和 <code>sync</code> 跟踪点,所以我们可以获得有关相应栅栏(在显示驱动程序和 SurfaceFlinger 之间共享,控制帧实际提交到显示部分的时间)的信息。我们关心的栅栏列于 <code>mdss_fb0_retire</code> 下,它指示帧实际在显示部分出现的时间。这些栅栏作为 <code>sync</code> 跟踪类别的一部分提供。哪些栅栏与 SurfaceFlinger 中的特定事件相对应,取决于您的 SOC 和驱动程序堆栈,因此请与您的 SOC 供应商联系,以了解您的跟踪记录中栅栏类别的含义。</p>
+
+<p><img src="images/perf_traces_fences.png"/></p>
+<p class="img-caption"><strong>图 13</strong>. <code>mdss_fb0_retire</code> 栅栏。</p>
+
+<p>图 13 显示的帧显示了 33 毫秒,而不是预期的 16.7 毫秒。图块前进到中途时,该帧应该被新帧替换,但实际上没有。请查看上一帧,看看是否可以找到蛛丝马迹:</p>
+
+<p><img src="images/perf_trace_frame_previous.png"/></p>
+<p class="img-caption"><strong>图 14. </strong> 被损坏帧的上一帧。</p>
+
+<p>图 14 显示了时长为 14.482 毫秒的一个帧。被损坏的两帧片段是 33.6 毫秒,这和我们预期的两帧时长大致接近(我们以 60Hz 渲染,每帧 16.7 毫秒,很接近)。但是 14.482 毫秒与 16.7 毫秒相去甚远,这表明显示通道存在严重错误。</p>
+
+<p>调查栅栏的确切结束位置,以确定是什么在控制它:</p>
+
+<p><img src="images/perf_trace_fence_end.png"/></p>
+<p class="img-caption"><strong>图 15. </strong> 调查栅栏的结束位置。</p>
+
+<p>工作队列包含一个 <code>__vsync_retire_work_handler</code>,它在栅栏发生变化时运行。通过浏览内核源代码,您可以看到它是显示驱动程序的一部分。它显然位于显示通道的关键路径上,所以必须以尽可能快的速度运行。它可运行约 70 微秒(不是很长的调度延迟),但它是一个工作队列,系统可能无法准确地排定其运行时间。</p>
+
+<p>检查上一帧,以确定它是否会导致该问题;有时抖动会随时间而累加,最终导致我们错过最后期限。</p>
+
+<p><img src="images/perf_trace_previous_frame.png"/></p>
+<p class="img-caption"><strong>图 16. </strong> 上一帧。</p>
+
+<p>kworker 上的可运行行不可见,因为当该行被选择时,查看器会将它变为白色,不过,通过统计数据,我们可以了解到问题所在:部分显示通道关键路径的 2.3 毫秒调度程序延迟时间<strong>很不乐观</strong>。在执行任何其他操作之前,我们应该先解决该问题,方法是:将显示通道关键路径的这一部分从工作队列(作为 <code>SCHED_OTHER</code> CFS 线程运行)移动到专用的 <code>SCHED_FIFO</code> kthread。这一功能需要时间保证,而工作队列不能(也不打算)提供这一保证。</p>
+
+<p>这是产生卡顿的原因吗?很难说这就是最终结论。在不易于诊断的情况下(如内核锁争用导致显示关键线程进入休眠状态),您通常无法直接通过跟踪记录了解问题的起因。这种抖动有可能是帧丢弃的原因吗?当然有可能。栅栏时间应该是 16.7 毫秒,但是在最终导致帧丢弃的帧中,栅栏时间与该值相去甚远(有一个 19 毫秒的栅栏,后接一个 14 毫秒的栅栏)。鉴于显示通道的耦合紧密程度,栅栏时间的上下抖动完全有可能导致最终丢弃帧。</p>
+
+<p>在此示例中,解决方案涉及将 <code>__vsync_retire_work_handler</code> 从工作队列转换为专用 kthread。这样一来,弹力球测试中的抖动情况得到显著改善,且卡顿问题也会明显减轻。随后的跟踪记录显示了非常接近 16.7 毫秒的栅栏时间。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/display/dnd.html b/zh-cn/devices/tech/display/dnd.html
new file mode 100644
index 00000000..fd612ef7
--- /dev/null
+++ b/zh-cn/devices/tech/display/dnd.html
@@ -0,0 +1,51 @@
+<html devsite><head>
+ <title>配置 DND</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 7.0 支持以下勿扰 (DND) 配置。</p>
+
+<h2 id="third_party">第三方自动规则</h2>
+<p>第三方应用可以使用 DND Access API 控制 DND 规则:</p>
+<ul>
+<li><strong>应用</strong>可以导出并列出自定义 DND 规则,这些规则在 DND 设置中显示在内置 Android DND 规则的旁边。</li>
+<li><strong>用户</strong>可以访问所有规则(包括自动规则和手动创建的规则)的所有 DND 控件。</li>
+<li>Android <strong>平台</strong>可以实现来自不同来源的 DND 规则,而不会产生意外状态。</li>
+</ul>
+
+<h2 id="control_alarms">控制闹钟</h2>
+<p>启用 DND 模式后,Android 设置界面会向用户显示可配置的选项:</p>
+<ul>
+<li><strong>DND 结束条件作为下次闹钟响铃时间</strong>。允许用户将 DND 结束条件设为闹钟。仅当闹钟设置时间位于从现在起的一周内,并且闹钟属于的星期几与今天属于的星期几不一样时才会出现。<em></em><em></em>(自动规则不支持。)</li>
+<li><strong>闹钟响铃时间可覆盖结束时间</strong>。允许用户将 DND 结束条件设为特定时间或下次闹钟响铃时间(以先发生者为准)。</li>
+</ul>
+
+<h2 id="suppress_vis_distract">抑制视觉干扰</h2>
+<p>Android 设置界面会向用户显示抑制视觉干扰(例如提醒通知、全屏 intent、主动显示和 LED 通知指示灯)的选项。</p>
+
+<h2 id="implementation">自定义 DND 设置</h2>
+<p>自定义设置时,OEM 必须保留系统 API 的 AOSP 行为并维持 DND 设置的行为。具体而言,系统设置中的 DND 设置页面必须包括以下内容:</p>
+<ul>
+<li><strong>应用提供的 DND 规则</strong>。这些自动 DND 规则必须包含“添加规则”菜单中的有效规则实例和规则详情。</li>
+<li><strong>预加载的应用 DND 规则</strong>。OEM 可以提供在最终用户手动创建的规则旁边显示的 DND 规则。</li>
+</ul>
+<p>要详细了解新的 DND API,请参阅 <code><a href="https://developer.android.com/reference/android/service/notification/package-summary.html">android.service.notification</a></code> 参考文档。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/display/index.html b/zh-cn/devices/tech/display/index.html
new file mode 100644
index 00000000..3fac3b27
--- /dev/null
+++ b/zh-cn/devices/tech/display/index.html
@@ -0,0 +1,36 @@
+<html devsite><head>
+ <title>配置显示设置</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 显示设置的 AOSP 实现,其中包括应用快捷方式、圆形启动器图标、勿扰 (DND)、多窗口模式(分屏、自由格式和画中画)、高动态范围 (HDR) 视频、夜间模式和零售演示模式。如需了解详情,请参阅本部分的子页面。</p>
+
+<h2 id="settingshome">“设置主屏幕”增强功能</h2>
+
+<p>在 Android 7.0 及更高版本中,“设置主屏幕”页面因增添了建议的设置和可自定义的状态通知而得到了增强。这些功能可自动实现,并可由设备实现者进行配置。</p>
+
+<p>这些增强功能的源代码位于以下文件中:</p>
+
+<ul>
+<li><code>frameworks/base/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java</code></li>
+<li><code>frameworks/base/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java</code></li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/display/retail-mode.html b/zh-cn/devices/tech/display/retail-mode.html
new file mode 100644
index 00000000..a20cf409
--- /dev/null
+++ b/zh-cn/devices/tech/display/retail-mode.html
@@ -0,0 +1,191 @@
+<html devsite><head>
+ <title>零售演示模式</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 7.1.1 及更高版本可为零售模式提供系统级支持,以便用户可以轻松检测运行中的设备。通过该功能,零售环境中的任何人都可以观看快速、安全、一致的 Android 设备演示,而原始设备制造商 (OEM) 也可以借此大幅降低零售模式的成本和复杂度,实现演示设备的普通化。
+</p>
+
+<h2 id="key-use-cases">关键用例</h2>
+
+<ul>
+<li>任何现成的 Android 设备都可以通过向 build 添加一个演示视频来设置为零售模式。
+</li><li>所有设备上都具有突出设备独特功能的视频。
+</li><li>无论是在线还是离线环境,设备都可以运行。
+</li><li>设备可以进行自我维护,所需的员工互动极少。</li></ul>
+
+<h2 id="lifecycle">生命周期</h2>
+
+<img src="images/retail-demo-flow.png" alt="零售演示模式流程" width="XXX" id="retail-demo-flow"/>
+<p class="img-caption">
+ <strong>图 1.</strong> 语言选择中的零售演示模式选项</p>
+
+<h3 id="setup-wizard-suw">设置向导 (SUW)</h3>
+
+<p>零售员工可以从任何设置向导的首屏直接启用零售模式,具体方法是选择列表底部的语言 <strong>Retail demo</strong>。此选项适用于全新出厂的设备。一旦消费者完成设置,零售模式将不再可用。选择后,设备将完成具有简短流程的 SUW。
+</p>
+
+<img src="images/retail-demo-wizard.png" alt="零售演示模式向导用法" width="XXX" id="retail-demo-wizard"/>
+<p class="img-caption">
+ <strong>图 2.</strong> 语言选择中的零售演示模式选项</p>
+
+<h3 id="guest-session">访客会话</h3>
+
+<p>设备进入零售模式后,会切换到新的演示用户,并自动启动覆盖层资源中指定的自定义启动器(如“实现”部分所述)。默认情况下,此自定义启动器会重复播放演示视频,直至用户触摸屏幕开始访客会话。这时,自定义启动器会在启动系统启动器后退出。原始设备制造商 (OEM) 可以更改自定义启动器,使其在退出时额外启动其他服务或活动。有关详细信息,请参阅“实现”部分。<em></em>
+</p>
+
+<p>为了保持零售模式的完整性,键盘锁会被停用,且某些可能会对零售模式产生不利影响的“快捷设置”操作也会被禁用,其中包括:</p>
+
+<ul>
+ <li>飞行模式切换</li><li>移除或修改 WLAN 接入点(设置)</li><li>更改运营商(设置)</li><li>配置热点(设置)</li><li>用户切换</li></ul>
+
+<p>此外,还对某些会影响零售模式的全局设置进行了停用,以便阻止对这些设置的访问:</p>
+
+<ul>
+ <li>WLAN 设置</li><li>移动网络配置选项,尤其是热点</li><li>蓝牙配置</li><li>备份和重置、日期和时间以及移动网络(这些选项根本不会显示)</li></ul>
+
+<p>如果用户一段时间(默认为 90 秒)没有操作,零售模式会显示系统对话框,提示用户是退出会话还是继续。如果用户选择退出或在 5 秒内没有任何响应,零售模式将终止/擦除当前演示用户,然后切换到新的演示用户,并再次循环播放原始视频。如果有人使用电源按钮关闭屏幕,几秒钟后屏幕又会自动打开。
+</p>
+
+<p>设备退出演示会话后,会自动静音并重置一些全局设置,其中包括:</p>
+
+<ul>
+ <li>亮度</li><li>自动旋转</li><li>手电筒</li><li>语言</li><li>无障碍</li></ul>
+
+<h3 id="exiting-retail-mode">退出零售模式</h3>
+
+<p>要退出零售模式,零售员工必须从引导加载程序将设备恢复出厂设置。
+</p>
+
+<h2 id="examples-and-source">示例和源代码</h2>
+
+<p>从以下位置查找循环播放视频的自定义启动器:<br />
+<code>/packages/apps/RetailDemo</code>
+</p>
+
+<h2 id="implementation">实现</h2>
+
+<h3 id="enabling-retaildemomodeservice">启用 RetailDemoModeService</h3>
+
+<p>设置向导设置全局设置 <code>Global.DEVICE_DEMO_MODE=true</code>,以表示设备已进入零售模式。一遇到此设置,<code>RetailDemoModeService</code> 便会在用户 0 已启动时创建并切换至演示用户,启用覆盖层资源中指定的自定义启动器,并停用 SUW。系统服务器和 SystemUI 也会使用此标记来管理零售模式的各个方面。
+</p>
+
+<h3 id="setting-custom-launcher-or-video-player">设置自定义启动器或视频播放器</h3>
+
+<p>原始设备制造商 (OEM) 可以通过覆盖 <code>/frameworks/base/core/res/res/config.xml</code> 中指定的框架资源 <code>config_demoModeLauncherComponent</code> 来指定自定义启动器
+</p>
+
+<p>例如,使用以下代码:</p>
+
+<pre>
+&lt;!-- Component that is the default launcher when Retail Mode is enabled. --&gt;
+&lt;string name="config_demoModeLauncherComponent"&gt;com.android.retaildemo/.DemoPlayer&lt;/string&gt;
+</pre>
+<p>位于 <code>/packages/apps/RetailDemo</code> 的零售演示 DemoPlayer 应用,是 Android 开放源代码项目 (AOSP) 中的默认自定义启动器。该应用会在 <code>/data/preloads/demo/retail_demo.mp4</code> 中查找视频并进行循环播放。当用户触摸屏幕时,自定义启动器会停用其活动组件,然后默认的系统启动器便会启动。
+</p>
+
+<p>自定义启动器必须将其自定义组件标记为默认停用,从而避免该组件在非演示情境下出现。在演示情境下,系统服务器会在启动新的演示会话时启用指定的 <code>config_demoModeLauncherComponent</code>。
+</p>
+
+<p>设置向导也会查找上述视频作为素材,以提供给零售模式进行播放。如果视频不是演示的一部分,则可以修改 SUW 以查找其他表明支持零售模式的原始设备制造商 (OEM) 特定标志。
+</p>
+
+<p>如果有 A/B 两个系统分区,则 B 系统分区的 <code>/preloads/demo</code> 中必须包含演示视频。在首次启动时,系统会将该视频复制到 <code>/data/preloads/demo</code>。
+</p>
+
+<p>要设置特定于零售模式的设置,请使用:<code>Settings.Global.retail_demo_mode_constants</code>。例如:<code>user_inactivity_timeout_ms=90000,warning_dialog_timeout_ms=10000</code>
+</p>
+
+<p class="note"><strong>注意</strong>:目前的超时默认值为 90000 毫秒,但可对其进行配置。
+</p>
+
+<h3 id="finding-sample-images">查找示例图片</h3>
+
+<p>此功能可将示例照片放在对任何图库应用均可见的特殊文件夹中。这些照片仅在演示模式下可用,并且由于处在受保护的目录中,所以演示用户无法对其进行修改。
+</p>
+
+<h3 id="preventing-google-accounts">阻止 Google 帐号</h3>
+
+<p>访客用户中设置了一些限制,类似于通过托管设备/资料策略防止应用和用户执行某些操作。其中一项限制是 <code>DISALLOW_MODIFY_ACCOUNTS</code>。在此限制之下,AccountManager 和“设置”不允许添加帐号。某些 Google 应用会对此限制做出反应并显示一条错误消息,其他应用则不提示登录帐号(如 YouTube 和 Google 照片)。
+</p>
+
+<p>原始设备制造商 (OEM) 应用也应检查是否已设置 <code>DISALLOW_MODIFY_ACCOUNTS</code>。但这是一个一般问题,并非零售模式所独有。企业用例很可能已解决此问题。
+</p>
+
+<h3 id="customizing-the-system-launcher">自定义系统启动器</h3>
+
+<p>原始设备制造商 (OEM) 可以自由选择布局,但应该在主屏幕和底部区域包含正常运行的应用。
+</p>
+
+<h3 id="Customizing-built-in-apps">针对零售演示模式自定义内置应用</h3>
+
+<p>内置应用可调用 API <code>UserManager.isDemoUser()</code> 来查看应用是否在演示环境中启动,以此针对零售演示模式自定义应用体验。
+</p>
+
+<h3 id="following-demo-video-guidelines">遵循演示视频指南</h3>
+
+<p>演示视频应采用纵向布局(如果是平板电脑,则为设备的自然方向),且时长在 5 秒以上。由于视频将在展示期间全天候播放,因此视频内容不能导致烧机。
+</p>
+
+<h2 id="maintenance">维护</h2>
+
+<h3 id="bringing-the-device-out-of-retail-mode">使设备退出零售模式</h3>
+
+<p>只能通过从引导加载程序恢复出厂设置来实现。
+</p>
+
+<h3 id="auto-ota-of-system-software">系统软件的自动 OTA</h3>
+
+<p>默认情况下,启用零售模式时,设备策略将被自动设置为无线 (OTA) 更新。零售设备将不经过确认,自动下载、重新启动并安装更新(考虑电池阈值),即使更新被标记为可选亦如此。
+</p>
+
+<p class="caution"><strong>注意</strong>:如果针对 OTA 使用 A/B 系统分区,则接收 OTA 更新后,设备将无法在 B 系统分区中找到原始的零售模式资源。因此,之后的任何恢复出厂设置操作都会导致设备无法返回零售模式。
+</p>
+
+<h3 id="updating-demo-video-via-the-web">通过网络更新演示视频</h3>
+
+<p>只要有网络连接,<code>/packages/apps/RetailDemo</code> 中的 RetailDemo 应用便可以更新演示视频。通过在 RetailDemo 应用中替换以下字符串值,可配置下载视频的网址:</p>
+
+<pre>
+&lt;!-- URL where the retail demo video can be downloaded from. --&gt;
+&lt;string name="retail_demo_video_download_url"&gt;&lt;/string&gt;
+</pre>
+
+<p>如果需要在不同的区域使用不同的视频,则可以通过使用特定于语言区域的字符串资源 <code>res/values-*/strings.xml. </code>配置不同的下载网址。例如,如果需要在美国和英国使用不同的视频,则可以将相应的下载网址分别放在 <code>res/values-en-rUS/strings.xml</code> 和 <code>res/values-en-rGB/strings.xml</code> 中。
+</p>
+
+<p>在 <code>res/values-en-rUS/strings.xml</code> 中:</p>
+
+<pre>
+&lt;string name="retail_demo_video_download_url"&gt;download URL for US video goes here&lt;/string&gt;
+</pre>
+
+<p>同样,在 <code>res/values-en-rGB/strings.xml</code> 中:</p>
+
+<pre>
+&lt;string name="retail_demo_video_download_url"&gt;download URL for UK video goes here&lt;/string&gt;
+</pre>
+
+<p>每次设备重新启动时,此视频最多只能下载一次。视频在设备上播放时,RetailDemo 应用会在后台检查是否提供了下载网址以及网址中的视频是否比正在播放的视频新。
+
+</p><p>如果是,RetailDemo 应用就会下载该视频并开始播放。视频下载完成后,下载的视频将用于在之后的演示会话中播放。在下次重新启动之前,将不再执行此类检查。
+</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/index.html b/zh-cn/devices/tech/index.html
new file mode 100644
index 00000000..3ff8a900
--- /dev/null
+++ b/zh-cn/devices/tech/index.html
@@ -0,0 +1,70 @@
+<html devsite><head>
+ <title>Android 核心技术</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 核心技术部分。您可以在这里找到有关常用功能的信息,这些信息可帮助希望修改、移植 Android 软件或向其提供贡献的人员和组织。这是面向工程师的“后台级别”信息。</p>
+
+<h2 id="art-technical-information">ART 和 Dalvik</h2>
+<p>Android Runtime (ART) 是 Android 的核心。它是一个快速的预编译运行时,具有旨在可以灵活扩展的现代垃圾回收机制。Android 应用会被编译成 Dalvik 字节码,并在 ART 下运行。本部分包含 Dalvik 可执行文件格式规范、运行时本身的设计信息等详细信息。</p>
+<p><a href="/devices/tech/dalvik/index.html">» ART 和 Dalvik 信息</a></p>
+
+<h2 id="config">配置</h2>
+<p>要充分利用 Android,需要调整<a href="/devices/tech/config/kernel.html">内核</a>、<a href="/devices/tech/config/renderer.html">OpenGLRenderer</a> 等其它配置。如需了解详情,请参阅本部分的子页面。
+</p><p><a href="/devices/tech/config/index.html">» 配置信息</a></p>
+
+<h2 id="connect">网络连接</h2>
+<p>本部分介绍了 Android 对 NFC 标准(如 Felica)的支持,提供了有关无线界面层 (RIL) 的详细信息,描述了来电通知行为,并提供了面向用户的功能(如流量节省程序和电话号码拦截)的实现指令。</p>
+<p><a href="/devices/tech/connect/index.html">» 网络连接信息</a></p>
+
+<h2 id="data-usage-technical-information">流量使用情况</h2>
+<p>通过 Android 的流量使用情况功能,用户可以了解和控制其设备使用网络流量的方式。本部分旨在向系统集成者和移动运营商说明将 Android 移植到特定设备上时应注意的技术细节。</p>
+<p><a href="/devices/tech/datausage/index.html">» 流量使用情况信息</a></p>
+
+<h2 id="debugging">调试</h2>
+<p>Android 是一个庞大而复杂的系统。本部分包含在平台级别进行调试的提示和技巧。</p>
+<p><a href="/devices/tech/debug/index.html">» 调试信息</a></p>
+
+<h2 id="admin-information">设备管理</h2>
+<p>自 Android 5.0 起,在各个公司信息技术 (IT) 部门的支持下,本平台开始支持在企业环境中使用。</p>
+<p><a href="/devices/tech/admin/index.html">» 设备管理信息</a></p>
+
+<h2 id="display">显示设置</h2>
+<p>本部分将介绍各种 Android 显示设置的 AOSP 实现,其中包括应用快捷方式、圆形启动器图标、勿扰 (DND)、多窗口模式(分屏、自由格式和画中画)、高动态范围 (HDR) 视频、夜间模式和零售演示模式。</p>
+<p><a href="/devices/tech/display/index.html">» 显示设置信息</a></p>
+
+<h2 id="HAL-technical-information">HAL 文件参考</h2>
+<p>Android 的硬件抽象层 (HAL) 在软件 API 和硬件驱动程序之间提供了接口。本部分包含了带注释的 HAL 代码文件。</p>
+<p><a href="/reference/hal/">» HAL 参考</a></p>
+
+<h2 id="ota-technical-information">OTA 更新</h2>
+<p>正常使用的 Android 设备可以接收和安装系统和应用软件的无线 (OTA) 更新。本部分介绍了更新包的结构以及构建更新包时所用的工具,旨在供开发者为新的和已发布的 Android 设备构建 OTA 更新。</p>
+<p><a href="/devices/tech/ota/index.html">» OTA 信息</a>
+</p>
+
+<h2 id="power-technical-information">电源</h2>
+<p>Android 框架通过跟踪不同设备组件在不同状态下花费的时间来提供电池使用情况统计信息。本部分介绍了电源管理功能(如低电耗模式),提供了有关如何准确测量设备和组件电量消耗(以及如何确定电量值)的说明,并详细介绍了 <code>batterystats</code> 命令和输出。</p>
+<p><a href="/devices/tech/power/index.html">» 电源信息</a></p>
+
+<h2 id="tradefed-test-infrastructure">Trade Federation 测试基础架构</h2>
+<p>Trade Federation 是一种连续的测试框架,用于在 Android 设备上运行测试。使用 Trade Federation 的模块化功能可以非常直接地在当前产品的环境中进行测试和基础架构的报告。</p>
+<p><a href="/devices/tech/test_infra/tradefed/index.html">» Trade Federation 测试基础架构概览</a></p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/ota/ab_updates.html b/zh-cn/devices/tech/ota/ab_updates.html
new file mode 100644
index 00000000..5ae2e834
--- /dev/null
+++ b/zh-cn/devices/tech/ota/ab_updates.html
@@ -0,0 +1,422 @@
+<html devsite><head>
+ <title>A/B(无缝)系统更新</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>A/B 系统更新,也称为无缝更新,用于确保可运行的启动系统在<a href="/devices/tech/ota/index.html">无线 (OTA) 更新</a>期间能够保留在磁盘上。这样可以降低更新之后设备无法启动的可能性,也就是说,用户需要将设备送到维修/保修中心进行更换和刷机的情况将有所减少。
+</p>
+
+<p>用户在 OTA 期间可以继续使用设备。在更新过程中,仅当设备重新启动到更新后的磁盘分区时,会发生一次宕机情况。即使 OTA 失败,设备也仍然可以使用,因为它会启动到 OTA 之前的磁盘分区。您可以再次尝试下载 OTA。建议仅针对新设备通过 OTA 实现 A/B 系统更新。
+</p>
+
+<p>A/B 系统更新将影响:</p>
+
+<ul>
+ <li>与引导加载程序的交互</li>
+ <li>分区选项</li>
+ <li>构建流程</li>
+ <li>OTA 更新软件包的生成</li>
+</ul>
+
+<p>现有的 <a href="/security/verifiedboot/dm-verity.html">dm-verity</a> 功能可确保设备会启动未损坏的映像。如果设备因糟糕的 OTA 或 dm-verity 问题而无法启动,则可以重新启动到原来的映像。
+</p>
+
+<p>A/B 系统之所以非常强大,是因为任何错误(如 I/O 错误)都只能影响<strong>未使用的</strong>分区集,并且可以进行重试。由于 I/O 负载被特意控制在较低水平,以免影响用户体验,因此此类错误不太可能会发生。
+</p>
+
+<p>OTA 更新可以在系统运行时进行,而不会打断用户,更新的内容包括重新启动后进行的应用优化。此外,缓存分区不再用于存储 OTA 更新软件包;无需调整缓存分区的大小。
+</p>
+
+<h2 id="overview">概览</h2>
+
+<p>A/B 系统更新使用称为 <code>update_engine</code> 的后台守护进程以及两组分区。这两组分区称为插槽,通常为插槽 A 和插槽 B。系统从其中一个插槽(“当前插槽”)运行,但运行的系统不会访问“未使用的”插槽中的分区(用于正常操作)。<em></em><em></em><em></em>
+</p>
+
+<p>此功能的目标是将未使用的插槽保留为后备插槽,从而使更新具有抗故障性。如果更新期间或更新后立即出现错误,则系统可以回滚至原来的插槽并继续正常运行。为实现这一目标,“当前”插槽所使用的所有分区(包括只有一个副本的分区)都不应作为 OTA 更新的一部分进行更新。<em></em>
+</p>
+
+<p>每个插槽都有“可启动”属性,该属性会声明相应插槽是否包含设备可以从中启动的正确系统。<em></em>系统运行时,当前插槽肯定可以启动,但是另一个插槽中可能包含旧(仍然正确)版本的系统,也可能包含较新版本或无效的数据。无论当前插槽是哪一个,都有一个插槽是活动插槽或首选插槽。<em></em><em></em>下次启动时,引导加载程序将从活动插槽中启动。最后,每个插槽都有由用户空间设置的“成功”属性,该属性只有在相应插槽也可以启动时才具有相关性。<em></em>
+</p>
+
+<p>成功的插槽应该能够自行启动、运行和更新。未标记为成功的可启动插槽(尝试从其启动几次之后)应由引导加载程序标记为不可启动,包括将活动插槽更改为其他可启动插槽(通常更改为在尝试启动到新的活动插槽之前运行的插槽)。界面的具体详细信息在 <code><a class="external-link" target="_blank" href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h">boot_control.h</a></code> 中进行了定义。
+</p>
+
+<h3 id="bootloader-state-examples">引导加载程序状态示例</h3>
+
+<p><code>update_engine</code>(以及其他可能的守护进程)使用 <code>boot_control</code> HAL 指示引导加载程序从何处启动。以下是常见的示例情景及其相关的状态:</p>
+
+<ul>
+ <li>
+ <strong>正常情况</strong>:系统正在从其当前插槽(插槽 A 或插槽 B)运行。目前为止尚未应用任何更新。系统的当前插槽是可启动、成功且活动的插槽。
+ </li>
+ <li>
+ <strong>正在更新</strong>:系统正在从插槽 B 运行,因此,插槽 B 是可启动、成功且活动的插槽。由于插槽 A 中的内容正在更新,但是尚未完成,因此插槽 A 标记为不可启动。在此状态下,应继续从插槽 B 重新启动。</li>
+ <li>
+ <strong>已应用更新,正在等待重新启动</strong>:系统正在从插槽 B 运行,插槽 B 的状态为可启动且成功,但是插槽 A 过去标记为活动(因此现在标记为可启动)。插槽 A 尚未被标记为成功,引导加载程序应该尝试从插槽 A 启动几次。
+ </li>
+ <li>
+ <strong>系统重新启动到新的更新</strong>:系统首次从插槽 A 运行,插槽 B 的状态仍为可启动且成功,而插槽 A 仅可启动,且仍然处于活动但不成功的状态。在进行几次检查之后,用户空间守护进程应将插槽 A 标记为成功。
+ </li>
+</ul>
+
+<h3 id="update-engine-features">更新引擎功能</h3>
+
+<p>守护进程 <code>update_engine</code> 在后台运行,并会使系统做好启动到已更新的新版本的准备。守护进程 <code>update_engine</code> 本身不会参与到启动流程中,且更新期间可以执行的操作会受到限制。守护进程 <code>update_engine</code> 可以执行以下操作:</p>
+
+<ul>
+ <li>根据 OTA 软件包的指示,从当前插槽 A/B 分区读取数据,然后向未使用的插槽 A/B 分区中写入数据</li>
+ <li>在预定义的工作流程中调用 <code>boot_control</code> 界面</li>
+ <li>根据 OTA 软件包的指示,在将数据写入所有未使用的插槽分区之后,从新分区运行安装后的程序<em></em><em></em></li>
+</ul>
+
+<p>下文对安装后的步骤进行了详细介绍。注意,守护进程 <code>update_engine</code> 受 <a href="/security/selinux/">SELinux</a> 策略及当前插槽中的功能限制;在系统启动到新版本之前,这些策略和功能无法更新。<em></em>要实现稳健性目标,更新流程不应执行以下操作:</p>
+
+<ul>
+ <li>修改分区表</li>
+ <li>修改当前插槽中分区的内容</li>
+ <li>修改恢复出厂设置时无法擦除的非 A/B 分区的内容</li>
+</ul>
+
+<h2 id="life-of-an-a-b-update">A/B 更新过程</h2>
+
+<p>当 OTA 软件包(在代码中称为有效负荷)可供下载时,更新流程便开始了。<em></em>设备中的策略可能会基于电池电量、用户活动、是否连接到充电器或其他策略延迟有效负荷的下载和应用。不过,由于更新在后台运行,因此用户可能不知道更新正在进行,而且更新流程可能随时会由于策略或意外重新启动而被中断。
+</p>
+
+<p>有效负荷可用后更新流程中的步骤将如下所示:</p>
+
+<p>
+ <strong>第 1 步</strong>:通过 <code>markBootSuccessful()</code> 将当前插槽(或“源插槽”)标记为成功(如果尚未标记)。
+</p>
+
+<p>
+ <strong>第 2 步</strong>:通过调用函数 <code>setSlotAsUnbootable()</code> 将未使用的插槽(或“目标插槽”)标记为不可启动。
+</p>
+
+<p>在更新开始时,当前插槽会始终标记为成功,以防引导加载程序回退至未使用的插槽(很快将有无效数据)。如果系统已可以开始应用更新,即使其他主要组件已受损(如崩溃循环中的界面),当前插槽也会标记为成功,因为可以通过推送新软件来修复这些主要问题。
+</p>
+
+<p>更新有效负荷是不透明的 Blob,其中包含更新到新版本的相应指令。更新有效负荷主要由两部分组成:元数据以及与指令相关的额外数据。元数据相对较小,其中包含在目标插槽上生成和验证新版本的操作的列表。例如,某个操作可能会解压缩特定 Blob 并将其写入目标分区中的特定块,或者从源分区读取数据、向其应用二进制补丁程序,然后写入目标分区中的特定块。与操作相关联的额外数据并未包含在元数据中,此类数据在更新有效负荷中所占比重较大,其中将包含这些示例中的已压缩 Blob 或二进制补丁程序。
+</p>
+
+<p>
+ <strong>第 3 步</strong>:下载有效负荷元数据。
+</p>
+
+<p>
+ <strong>第 4 步</strong>:对于元数据中定义的每项操作,将按顺序发生以下行为:关联的数据(如果有)下载到内存中、操作得到应用、关联的内存被舍弃。
+</p>
+
+<p>这两个步骤占用了大部分更新时间,因为它们涉及写入和下载大量数据,并且可能会因策略或重新启动等原因而中断。
+</p>
+
+<p>
+ <strong>第 5 步</strong>:针对预期哈希重新读取并验证整个分区。
+</p>
+
+<p>
+ <strong>第 6 步</strong>:运行安装后步骤(如果有)。
+</p>
+
+<p>如果在执行任一步骤的过程中出现错误,则更新失败,系统可能会通过其他有效负荷重新尝试更新。如果上述所有步骤均成功完成,则更新成功,系统会执行最后一个步骤。
+</p>
+
+<p>
+ <strong>第 7 步</strong>:通过调用 <code>setActiveBootSlot()</code> 将未使用的插槽标记为活动。<em></em>
+</p>
+
+<p>将未使用的插槽标记为活动并不意味着它会完成启动。如果它未读取到成功的状态,引导加载程序或系统本身可以将插槽的活动状态切换回来。
+</p>
+
+<h3 id="post-install-step">安装后的步骤</h3>
+
+<p>安装后的步骤包括从“新更新”版本中运行仍在原来版本中运行的程序。如果此步骤已在 OTA 软件包中定义,则为强制性步骤,且程序必须返回退出代码 <code>0</code>,否则更新失败。
+</p>
+
+<p>对于其中已定义安装后步骤的每个分区,<code>update_engine</code> 会将新分区装载到特定位置,并执行与装载的分区对应的 OTA 中指定的程序。例如,如果安装后程序在相应系统分区中定义为 <code>usr/bin/postinstall</code>,则系统会将此来自未使用插槽的分区装载到一个固定位置(如 <code>/postinstall_mount</code> 中),然后执行 <code>/postinstall_mount/usr/bin/postinstall</code> 命令。注意,要使此步骤生效,需要满足以下条件:</p>
+
+<ul>
+ <li>旧内核需要能够装载新的文件系统格式。文件系统类型不能更改,除非旧内核中有为其提供的支持(包括使用 SquashFS 等压缩文件系统时所用的压缩算法等详细信息)。
+ </li>
+ <li>旧内核需要了解新分区的安装后程序格式。如果使用的是 ELF 二进制文件,则该文件应该与旧内核兼容(例如,如果弃用 32 位版本架构,并改为使用 64 位版本架构,则 64 位的新程序应该可以在旧版 32 位内核上运行)。此外,库将会从旧系统映像而非新系统映像加载,除非加载程序 (<code>ld</code>) 收到使用其他路径或构建静态二进制文件的指令。
+ </li>
+ <li>新的安装后程序将受到旧系统中定义的 SELinux 策略的限制。
+ </li>
+</ul>
+
+<p>一种示例情况是,将 Shell 脚本用作安装后程序(由旧系统中顶部带有 <code>#!</code> 标记的 Shell 二进制文件解析), 然后从新环境设置库路径,用于执行更复杂的二进制安装后程序。
+</p>
+
+<p>另一种示例情况是,从专用的较小分区执行安装后步骤,以便主系统分区中的文件系统格式可以得到更新,同时不会产生向后兼容问题或引发 stepping-stone 更新,这样一来,用户便可以从出厂映像直接更新到最新版本。
+</p>
+
+<p>根据 SELinux 策略,安装后步骤适用于在指定设备上执行设计所需的任务或其他需要尽可能完成的任务:更新支持 A/B 的固件或引导加载程序、为新版本准备部分数据库的副本等等。该步骤不适用于重新启动之前的一次性错误修复(此类修复需要无法预见的权限)。
+</p>
+
+<p>所选的安装后程序在 <code>postinstall</code> SELinux 环境中运行。新装载的分区中的所有文件都将使用 <code>postinstall_file</code> 进行标记,无论它们在重新启动到新系统后的属性如何,都是如此。对新系统中 SELinux 属性实施的更改不会影响安装后步骤。如果安装后的程序需要额外的权限,则必须将这些权限添加到安装后的环境中。
+</p>
+
+<h2 id="implementation">实现</h2>
+
+<p>希望实现该功能的 OEM 和 SoC 供应商必须向其引导加载程序中添加以下支持:</p>
+
+<ul>
+ <li>将<a href="#kernel-command-line-arguments">正确参数</a>传递给内核</li>
+ <li>实现 <code>boot_control</code> HAL (<a class="external-link nowrap" target="_blank" href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h">https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h</a>)</li>
+ <li>实现状态机,如图 1 所示:</li>
+</ul>
+
+<img src="images/ab-updates-state-machine.png"/>
+
+<p class="img-caption"><strong>图 1. </strong> 引导加载程序状态机</p>
+
+<p>可使用 <a class="external-link" target="_blank" href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/"><code>bootctl</code></a> 实用工具测试启动控件 HAL。
+</p>
+
+<p>已针对 Brillo 实施了一些测试:</p>
+
+<ul>
+ <li>
+ <a class="external-link nowrap" target="_blank" href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/">https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/</a>
+ </li>
+ <li>
+ <a class="external-link nowrap" target="_blank" href="https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py">https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py</a>
+ </li>
+</ul>
+
+<h3 id="kernel-patches">内核补丁程序</h3>
+
+<ul>
+ <li>
+ <a class="external-link nowrap" target="_blank" href="https://android-review.googlesource.com/#/c/158491/">https://android-review.googlesource.com/#/c/158491/</a>
+ </li>
+ <li>
+ <a class="external-link nowrap" target="_blank" href="https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18">https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18</a>
+ </li>
+</ul>
+
+<h3 id="kernel-command-line-arguments">内核命令行参数</h3>
+
+<p>内核命令行参数<strong>必须</strong>包含以下额外参数:</p>
+
+<pre>skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 \
+ android-verity &lt;public-key-id&gt; &lt;path-to-system-partition&gt;"
+</pre>
+
+<p>值 <code>&lt;public-key-id&gt;</code> 是用于验证 verity 表签名的公钥 ID(请参阅 <a href="/security/verifiedboot/dm-verity.html">dm-verity</a>)。
+</p>
+
+<h4>要将包含相应公钥的 .X509 证书添加到系统密钥环,请执行以下操作:</h4>
+
+<ol>
+ <li>将设置为 <code>.der</code> 格式的 .X509 证书复制到 <code>kernel</code> 的根目录。您可以使用以下 <code>openssl</code> 命令将证书格式从 <code>.pem</code> 转换为 <code>.der</code>(如果 .X509 证书采用 <code>.pem</code> 格式):<pre>openssl x509 -in &lt;x509-pem-certificate&gt; -outform der -out &lt;x509-der-certificate&gt;</pre>
+ </li>
+ <li>复制到内核版本根目录后,构建 <code>zImage</code> 以将该证书添加为系统密钥环的一部分。您可以通过以下 <code>procfs</code> 条目(需要启用 <code>KEYS_CONFIG_DEBUG_PROC_KEYS</code>)验证该步骤:<pre>angler:/# cat /proc/keys
+
+1c8a217e I------ 1 perm 1f010000 0 0 asymmetri
+Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
+2d454e3e I------ 1 perm 1f030000 0 0 keyring
+.system_keyring: 1/4</pre>
+ </li>
+</ol>
+
+<p>如果 .X509 证书添加成功,则表示系统密钥环中存在相应公钥。突出显示部分表示公钥 ID。</p>
+
+<p>下一步是将空格替换为“#”,并将其作为 <code>&lt;public-key-id&gt;</code> 在内核命令行中传递。例如,在上述示例中,以下证书在 <code>&lt;public-key-id&gt;</code> 的位置传递:<code>Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f</code>
+</p>
+
+<h3 id="recovery">恢复</h3>
+
+<p>恢复 RAM 磁盘现已包含在 <code>boot.img</code> 文件中。进入恢复模式时,引导加载程序<strong>无法</strong>在内核命令行中添加 <code>skip_initramfs</code> 选项。
+</p>
+
+<h3 id="build-variables">构建变量</h3>
+
+<h5>必须针对 A/B 目标定义以下变量:</h5>
+
+<ul>
+ <li><code>AB_OTA_UPDATER := true</code></li>
+ <li>
+ <code>AB_OTA_PARTITIONS := \</code><br />
+ <code>  boot \</code><br />
+ <code>  system \</code><br />
+ <code>  vendor</code><br />以及通过 <code>update_engine</code> 更新的其他分区(无线装置、引导加载程序等)。
+ </li>
+ <li>
+ <code>BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</code>
+ </li>
+ <li><code>TARGET_NO_RECOVERY := true</code></li>
+ <li>
+ <code>BOARD_USES_RECOVERY_AS_BOOT := true</code>
+ </li>
+ <li>
+ <code>PRODUCT_PACKAGES += \</code><br />
+ <code>  update_engine \</code><br />
+ <code>  update_verifier</code>
+ </li>
+</ul>
+
+<h5>(可选)针对调试版本定义以下变量:</h5>
+
+<ul>
+ <li>
+ <code>PRODUCT_PACKAGES_DEBUG += update_engine_client</code>
+ </li>
+</ul>
+
+<h5>无法针对 A/B 目标定义以下变量:</h5>
+
+<ul>
+ <li><code>BOARD_RECOVERYIMAGE_PARTITION_SIZE</code></li>
+ <li><code>BOARD_CACHEIMAGE_PARTITION_SIZE</code></li>
+ <li><code>BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE</code></li>
+</ul>
+
+<h3 id="partitions">分区</h3>
+
+<ul>
+ <li>A/B 设备不需要恢复分区或缓存分区,因为 Android 已不再使用这些分区。数据分区现在用于存储下载的 OTA 软件包,而恢复映像代码位于启动分区。
+ </li>
+ <li>A/B 化的所有分区应命名如下(插槽始终被命名为 <code>a</code>、<code>b</code> 等):<code>boot_a</code>、<code>boot_b</code>、<code>system_a</code>、<code>system_b</code>、<code>vendor_a</code>、<code>vendor_b</code>。
+ </li>
+</ul>
+
+<h3 id="fstab">Fstab</h3>
+
+<p>参数 <code>slotselect</code> <strong>必须</strong>位于 A/B 化分区的行中。例如:</p>
+
+<pre>&lt;path-to-block-device&gt;/vendor /vendor ext4 ro
+wait,verify=&lt;path-to-block-device&gt;/metadata,slotselect</pre>
+
+<p>请注意,不应选择名称为 <code>vendor</code> 的分区,而应选择分区 <code>vendor_a</code> 或 <code>vendor_b</code> 并将其装载到 <code>/vendor</code> 装载点上。
+</p>
+
+<h3 id="kernel-slot-arguments">内核插槽参数</h3>
+
+<p>应通过特定的 DT 节点 (<code>/firmware/android/slot_suffix</code>) 或 <code>androidboot.slot_suffix</code> 命令行参数传递当前插槽后缀。
+</p>
+
+<p>或者,如果引导加载程序实现 fastboot,则应支持以下命令和变量:</p>
+
+<h4>命令</h4>
+<ul>
+ <li>
+ <code>set_active &lt;slot&gt;</code> - 将当前活动插槽设置为指定插槽。此外,还必须清除该插槽的不可启动标记,并将重试计数重置为默认值。
+ </li>
+</ul>
+
+<h4>变量</h4>
+<ul>
+ <li>
+ <code>has-slot:&lt;partition-base-name-without-suffix&gt;</code> - 如果指定分区支持插槽,则返回“yes”,否则,返回“no”。
+ </li>
+ <li>
+ <code>current-slot</code> - 返回接下来将从中启动的插槽后缀。
+ </li>
+ <li>
+ <code>slot-count</code> - 返回一个表示可用插槽数量的整数。目前支持两个插槽,因此,该值为 <code>2</code>。
+ </li>
+ <li>
+ <code>slot-successful:&lt;slot-suffix&gt;</code> - 如果指定插槽已标记为成功启动,则返回“yes”,否则,返回“no”。
+ </li>
+ <li>
+ <code>slot-unbootable:&lt;slot-suffix&gt;</code> - 如果指定插槽标记为不可启动,则返回“yes”,否则,返回“no”。
+ </li>
+ <li>
+ <code>slot-retry-count:<slot suffix></slot></code> - 可以尝试启动指定插槽的剩余重试次数。
+ </li>
+ <li>这些变量都应显示在 <code>fastboot getvar all</code> 下
+ </li>
+</ul>
+
+<h3 id="ota-package-generation">生成 OTA 软件包</h3>
+
+<p><a href="/devices/tech/ota/tools.html">OTA 软件包工具</a>遵循与非 A/B 设备一样的命令。<code>target_files.zip</code> 文件必须通过为 A/B 目标定义版本变量生成。OTA 软件包工具会自动识别并生成格式适用于 A/B 更新程序的软件包。
+</p>
+
+<p>例如,使用以下命令生成完整 OTA:</p>
+
+<pre>./build/tools/releasetools/ota_from_target_files \
+ dist_output/tardis-target_files.zip ota_update.zip
+</pre>
+
+<p>或者生成增量 OTA:</p>
+
+<pre>./build/tools/releasetools/ota_from_target_files \
+ -i PREVIOUS-tardis-target_files.zip \
+ dist_output/tardis-target_files.zip incremental_ota_update.zip
+</pre>
+
+<h2 id="configuration">配置</h2>
+
+<h3 id="config-partitions">分区</h3>
+
+<p>更新引擎可以更新同一磁盘中定义的任何一对 A/B 分区。
+</p>
+
+<p>一对分区有一个公共前缀(例如 <code>system</code> 或 <code>boot</code>)及按插槽划分的后缀(例如 <code>_a</code>)。有效负荷生成器为其定义更新的分区列表由 <code>AB_OTA_PARTITIONS</code> make 变量配置。例如,如果磁盘中有一对分区 <code>bootloader_a</code> 和 <code>booloader_b</code>(<code>_a</code> 和 <code>_b</code> 为插槽后缀),则可以通过在产品或单板配置中指定以下变量来更新这些分区:</p>
+
+<pre>AB_OTA_PARTITIONS := \
+ boot \
+ system \
+ bootloader
+</pre>
+
+<p>由更新引擎更新的所有分区不得由系统的其余部分修改。在增量更新期间,来自当前插槽的二进制数据将用于在新插槽中生成数据。<em></em>任何修改都可能导致新插槽数据在更新过程中无法通过验证,从而导致更新失败。
+</p>
+
+<h3 id="post-install">安装后</h3>
+
+<p>对于每个已更新的分区,都可以使用一组键值对配置不同的安装后步骤。
+</p>
+
+<p>要在新映像中运行位于 <code>/system/usr/bin/postinst</code> 的程序,请指定与系统分区中相应文件系统的根目录对应的路径。例如,<code>usr/bin/postinst</code> 的对应路径为 <code>system/usr/bin/postinst</code>(如果未使用 RAM 磁盘)。此外,请指定要传递到 <code>mount(2)</code> 系统调用的文件系统类型。将以下内容添加到产品或设备的 <code>.mk</code> 文件(如果适用):</p>
+
+<pre>AB_OTA_POSTINSTALL_CONFIG += \
+ RUN_POSTINSTALL_system=true \
+ POSTINSTALL_PATH_system=usr/bin/postinst \
+ FILESYSTEM_TYPE_system=ext4
+</pre>
+
+<h3 id="compilation">后台中的应用编译</h3>
+
+<p>要在 A/B 更新的后台编译应用,需要对产品的设备配置(位于产品的 device.mk 中)进行以下两项补充:</p>
+
+<ol>
+ <li>向版本中添加原生组件。这样可以确保编译脚本和二进制文件能够编译并添加到系统映像中。
+ <pre>
+ # A/B OTA dexopt package
+ PRODUCT_PACKAGES += otapreopt_script
+</pre>
+ </li>
+ <li>将编译脚本与 <code>update_engine</code> 相关联,以便它可以作为安装后步骤运行。
+ <pre>
+ # A/B OTA dexopt update_engine hookup
+ AB_OTA_POSTINSTALL_CONFIG += \
+ RUN_POSTINSTALL_system=true \
+ POSTINSTALL_PATH_system=system/bin/otapreopt_script \
+ FILESYSTEM_TYPE_system=ext4 \
+ POSTINSTALL_OPTIONAL_system=true
+ </pre>
+ </li>
+</ol>
+
+<p>请参阅 <a href="/devices/tech/dalvik/configure.html#other_odex">DEX_PREOPT 文件的首次启动安装</a>,以将预选文件安装到未使用的第二个系统分区中。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/ota/block.html b/zh-cn/devices/tech/ota/block.html
new file mode 100644
index 00000000..87015e9a
--- /dev/null
+++ b/zh-cn/devices/tech/ota/block.html
@@ -0,0 +1,83 @@
+<html devsite><head>
+ <title>基于块的 OTA</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 5.0 的新设备启用基于块的无线 (OTA) 更新。OTA 是原始设备制造商 (OEM) 用于远程更新设备系统分区的机制:</p>
+<ul>
+<li><b>Android 5.0</b> 及更高版本使用块 OTA 更新,以确保每个设备使用的分区完全相同。块 OTA 不会比较各个文件,也不会分别计算各个二进制补丁程序,而是将整个分区处理为一个文件并计算单个二进制补丁程序,以确保生成的分区刚好包含预期的位数。这样一来,设备系统映像就能够通过 fastboot 或 OTA 达到相同的状态。</li>
+<li><b>Android 4.4</b> 及更低版本使用文件 OTA 更新,确保设备包含类似的文件内容、权限和模式,但允许时间戳和底部存储的布局等元数据在各设备之间因更新方法而异。</li>
+
+</ul>
+<p>因为块 OTA 可确保每个设备使用相同的分区,所以它能够使用 dm-verity 以加密的方式为系统分区签名。要详细了解 dm-verity,请参阅<a href="/security/verifiedboot/index.html">验证启动</a>。
+</p>
+
+<p class="note"><strong>注意</strong>:您必须拥有正常运行的块 OTA 系统才能使用 dm-verity。</p>
+
+<h2 id="Recommendations">推荐</h2>
+
+<p>对于使用 Android 5.0 或更高版本启动的设备,请在出厂 ROM 中使用块 OTA 更新。要为后续更新生成基于块的 OTA,请将 <code>--block</code> 选项传递到 <code>ota_from_target_files</code>。</p>
+
+<p>对于搭载 Android 4.4 或更低版本的设备,请使用文件 OTA 更新。虽然可以通过发送 Android 5.0 或更高版本的完整块 OTA 来转换设备,但这需要发送一个明显大于增量 OTA 的完整 OTA(因此不建议采用该方法)。
+</p>
+
+<p>由于仅在搭载 Android 5.0 或更高版本的新设备中提供 dm-verity 所需的引导加载程序支持,因此无法为现有设备启用 dm-verity。<i></i></p>
+
+<p>致力于开发 Android OTA 系统(生成 OTA 的恢复映像和脚本)的开发者可以订阅 <a href="https://groups.google.com/forum/#!forum/android-ota">android-ota@googlegroups.com</a> 邮寄名单以及时了解最新动态。</p>
+
+<h2 id="File vs. Block OTAs">文件与块 OTA</h2>
+
+<p>在进行基于文件的 OTA 期间,Android 会尝试在文件系统层更改系统分区的内容(逐个更改)。更新无法保证按照一致的顺序写入文件、具有一致的上次修改时间或超级块、甚至将块放置在块设备上的同一位置。因此,在启用 dm-verity 的设备上执行基于文件的 OTA 将会失败;进行 OTA 尝试后,设备不会启动。</p>
+<p>在执行基于块的 OTA 期间,Android 为设备提供两个块映像(而非两组文件)之间的差异。该更新使用以下方法之一在块级别(位于文件系统下方)针对相应构建服务器来检查设备版本:</p>
+<ul>
+<li><b>完整更新</b>:复制整个系统映像很容易操作且易于生成补丁程序,但同时导致生成的映像较大,因而增加了应用补丁程序的成本。</li>
+<li><b>增量更新</b>:使用二进制文件 differ 工具可生成较小的映像且易于应用补丁程序,但在生成补丁程序本身时却占用大量内存。</li>
+</ul>
+
+<p class="note"><strong>注意</strong>:<code>adb fastboot</code> 在设备上放置与完整 OTA 完全相同的位数,以便刷写设备与块 OTA 兼容。</p>
+
+<h3 id="Unmodified Systems">更新未修改的系统</h3>
+
+<p>对于具有运行 Android 5.0 的未修改系统分区的设备,下载和安装块 OTA 的过程与文件 OTA 相同。不过,OTA 更新本身可能包括以下一个或多个区别:<i></i></p>
+<ul>
+<li><b>下载大小</b>:完整块 OTA 更新的大小接近完整文件 OTA 更新的大小,而增量更新可能只有几兆字节。<p></p>
+
+<img src="../images/ota_size_comparison.png" alt="比较 OTA 大小"/>
+
+<p class="img-caption"><strong>图 1.</strong> 比较 Android 5.0 和 Android 5.1 两个版本之间 Nexus 6 OTA 的大小(不同的目标版本更改)</p>
+
+<p>一般情况下,增量块 OTA 更新大于增量文件 OTA 更新的原因如下:</p>
+<ul>
+<li>数据保存:<i></i>基于块的 OTA 比基于文件的 OTA 保存的数据更多(文件元数据、dm-verity 数据、ext4 布局等)。</li>
+<li>计算算法不同:<i></i>在文件 OTA 更新中,如果两个版本的文件路径完全相同,则 OTA 包不包含该文件的任何数据。在块 OTA 更新中,确定文件中没有发生变化或发生很少变化取决于补丁程序计算算法的质量以及源系统和目标系统中文件数据的布局。</li>
+</ul>
+</li>
+<li><b>对错误 Flash 和 RAM 敏感</b>:如果文件已损坏,只要文件 OTA 没有接触到损坏的文件,则文件 OTA 就会成功;但如果块 OTA 在系统分区上检测到任何损坏,则块 OTA 失败。</li>
+</ul>
+
+<h3 id="Modified Systems">更新已修改的系统</h3>
+<p>对于具有运行 Android 5.0 的已修改系统分区的设备:<i></i></p>
+<ul>
+<li><b>增量块 OTA 更新失败</b>:系统分区可能会在 <code>adb remount</code> 期间或由于恶意软件而被修改。文件 OTA 允许对分区进行一些更改,例如添加不属于源版本或目标版本的文件。但是,块 OTA 不允许向分区添加内容,因此用户需要安装完整 OTA(覆盖所有系统分区修改)或刷写新的系统映像,以启用将来的 OTA。</li>
+<li><b>尝试更改已修改的文件会导致更新失败</b>:对于文件 OTA 和块 OTA 更新,如果 OTA 尝试更改已修改的文件,则 OTA 更新会失败。</li>
+<li><b>尝试访问已修改的文件会生成错误</b>(仅限 dm-verity):<i></i>对于文件 OTA 和块 OTA 更新,如果 dm-verity 已启用且 OTA 尝试访问系统文件系统的已修改部分,则 OTA 会生成错误。</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/ota/reduce_size.html b/zh-cn/devices/tech/ota/reduce_size.html
new file mode 100644
index 00000000..7d1d453e
--- /dev/null
+++ b/zh-cn/devices/tech/ota/reduce_size.html
@@ -0,0 +1,138 @@
+<html devsite><head>
+ <title>减小 OTA 大小</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>本页介绍了为减少不同构建之间的不必要文件变更,而添加到 AOSP 的构建变更。维护自己的构建系统的设备实现人员,可依照此信息减小无线 (OTA) 更新的大小。</p>
+
+<p>有时 Android OTA 包含的变更文件并非对应于代码变更,而是对应于构建系统的软件工件。在不同时间、不同目录或不同机器上构建相同代码时,会产生大量变更文件,这时便会发生上述情况。这些多余的文件不仅会增加 OTA 的大小,而且会导致难以确定 OTA 中发生变更的代码。</p>
+
+<p>为了使 OTA 的内容更加透明,AOSP 加入了构建系统变更,旨在通过消除不同构建之间不必要的文件变更来减小 OTA 的大小。这样做是为了减小 OTA 的大小,使其只包括与 OTA 中包含的补丁程序相关的文件。AOSP 还会加入<a href="#the_build_diff_tool">构建 diff 工具</a>,以过滤出常见的构建相关文件变更并提供更加清晰的构建文件 diff。</p>
+
+<p>构建系统可能会通过多种方式创建不必要的文件 diff。下文讨论了其中一些问题和解决方案,并尽可能提供了 AOSP 中的修复示例。</p>
+
+<h2 id="file_order">文件顺序</h2>
+
+<p><strong>问题</strong>:文件系统在请求目录中的文件列表时,并不保证文件顺序,尽管对于同一查询,文件顺序通常是相同的。诸如 <code>ls</code> 之类的工具在默认情况下会对结果进行排序,但 <code>find</code> 和 <code>make</code> 之类的命令使用的通配符函数却不会对结果进行排序。用户在使用此类工具之前,必须对输出进行排序。</p>
+
+<p><strong>解决方案</strong>:用户在使用带有通配符的 <code>find</code> 和 <code>make</code> 之类的工具之前,必须对这些命令的输出进行排序。要在 Android.mk 文件中使用 <code>$(wildcard )</code> 或 <code>$(shell find )</code>,也应该进行排序。有些工具(例如 Java)确实会对输入进行排序,因此有必要对排序进行验证。</p>
+
+<p><strong>示例</strong>:很多实例使用内建的 <code>all-*-files-under</code> 宏固定在核心构建系统中,其中包括 <code>all-cpp-files-under</code>(一些定义分散在其他 makefile 中)。有关详情,请参阅以下 CL:</p>
+
+<ul>
+ <li><a href="https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f">https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f</a>
+ </li><li><a href="https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410">https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410</a>
+ </li><li><a href="https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653">https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653</a>
+ </li><li><a href="https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c">https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c</a>
+</li></ul>
+
+<h2 id="build_directory">构建目录</h2>
+
+<p><strong>问题</strong>:变更构建内容所在的目录会导致二进制文件有所变化。Android 构建中的大多数路径是相对路径,因此 C/C ++ 中的 <code>__FILE__</code> 不是问题。不过,默认情况下调试符号会对完整的路径名进行编码,而对预剥离二进制文件进行哈希处理会生成 <code>.note.gnu.build-id</code>,因此调试符号变更会使二进制文件发生变化。</p>
+
+<p><strong>解决方案</strong>:AOSP 现在会使调试路径变成相对路径。有关详情,请参阅 CL:
+<a href="https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02">https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02</a>。</p>
+
+<h2 id="timestamps">时间戳</h2>
+
+<p><strong>问题</strong>:构建输出中的时间戳会导致不必要的文件变更。这可能发生在以下位置:</p>
+
+<ul>
+ <li>C 或 C++ 代码中的<code> __DATE__/__TIME__/__TIMESTAMP__ </code>宏。</li>
+ <li>基于 ZIP 的归档中嵌入的时间戳。</li>
+</ul>
+
+<p><strong>解决方案/示例</strong>:要从构建输出中移除时间戳,请遵循下文中的说明操作。</p>
+
+<h3 id="date_time_timestamp_in_c_c">C/C++ 中的 __DATE__/__TIME__/__TIMESTAMP__</h3>
+
+<p>这些宏总是会为不同的构建生成不同的输出,因此不应使用。
+ 您可选择以下方法来消除这些宏:</p>
+
+<ul>
+ <li>直接移除,这些宏通常并非必需。要查看示例,请参阅:
+<a href="https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f">https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f</a></li>
+ <li>要对运行中的二进制文件进行唯一标识,请从 ELF 标头中读取 build-id。</li>
+ <li>要了解操作系统的构建时间,请读取 <code>ro.build.date</code>(应该适合除增量构建之外的所有项目,增量构建可能不会更新此日期)。要查看示例,请参阅:
+<a href="https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84">https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84</a></li>
+</ul>
+
+ <p class="note"><strong>注意</strong>:我们开启了 <code>-Werror=date-time</code>,因此使用时间戳是一种构建错误。</p>
+
+<h3 id="embedded_timestamps_in_zip-based_archives_zip_jar">归档(zip、jar)中的嵌入时间戳</h3>
+
+<p>我们通过将 <code>-X</code> 添加到 <code>zip</code> 命令的所有用例中,解决了嵌入时间戳的问题,因此构建工具的 UID/GID 和扩展的 Unix 时间戳不会嵌入到 ZIP 文件中。</p>
+
+<p>新工具 <code>ziptime</code>(位于 <code>
+ <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/">/platform/build/+/master/tools/ziptime/</a></code>)会重置 zip 标头中的正常时间戳。有关详情,请参阅 <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/README.txt">README 文件</a>。</p>
+
+<p><code>signapk</code> 工具为 APK 文件设置的时间戳可能因服务器所在的时区而异。有关详情,请参阅 CL:
+<a href="https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028">https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028</a>。</p>
+
+<h2 id="version_strings">版本字符串</h2>
+
+<p><strong>问题</strong>:APK 版本字符串通常包含附加到硬编码版本的 BUILD_NUMBER。即使 APK 中并未发生任何其他变更,APK 仍然会有所不同。</p>
+
+<p><strong>解决方案</strong>:从 APK 版本字符串中移除版本号。</p>
+
+<p><strong>示例:</strong></p>
+
+<ul>
+ <li><a href="https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27">https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27</a></li>
+ <li><a href="https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c">https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c</a></li>
+</ul>
+
+<h2 id="consistent_build_tools">一致的构建工具</h2>
+
+<p><strong>问题</strong>:生成安装文件的工具必须一致(相同的输入应始终产生相同的输出)。</p>
+
+<p><strong>解决方案/示例</strong>:以下构建工具需要进行变更:</p>
+
+<ul>
+ <li><strong>NOTICE 文件创建工具</strong>。NOTICE 文件创建工具需要变更。请参阅 CL:
+<a href="https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64">https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64</a></li>
+ <li><strong>Java Android 编译器套件 (Jack)</strong>。Jack 工具链需要更新,才能处理生成的构造函数排序的偶然性变更。请参阅 CL:
+<a href="https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b">https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b</a></li>
+ <li><strong>ART AOT 编译器 (dex2oat)</strong>。ART 编译器二进制文件需要更新才能创建确定性图像。请参阅 CL:
+<a href="https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9">https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9</a></li>
+ <li><strong>libpac.so 文件 (V8)</strong>。每个构建会创建不同的 <code>/system/lib/libpac.so</code> 文件,因为 V8 快照会针对每个构建发生变化。解决方案是移除快照。请参阅 CL:
+<a href="https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29">https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29</a></li>
+ <li><strong>预先经过 dexopt 处理 (.odex) 的应用文件</strong>。预先经过 dexopt 处理 (.odex) 的文件包含 64 位系统上的未初始化填充。请参阅 CL:
+<a href="https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029">https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029</a></li>
+</ul>
+
+<h2 id="the_build_diff_tool">使用构建 diff 工具</h2>
+
+<p>对于无法消除构建相关文件变更的情况,我们提供构建 diff 工具 <code><a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/target_files_diff.py">target_files_diff.py</a></code> 来比较两个文件包。该工具会在两个构建之间执行递归 diff,从而排除常见的构建相关文件变更,例如:</p>
+
+<ul>
+ <li>构建输出中的预期变更(例如,由于版本号变更所导致)。</li>
+ <li>由于当前构建系统中的已知问题所导致的变更。</li>
+</ul>
+
+<p>要使用构建 diff 工具,请运行以下命令:</p>
+
+<pre class="prettyprint">
+$ target_files_diff.py dir1 dir2
+</pre>
+
+<p><code>dir1</code> 和 <code>dir2</code> 是包含每个构建的提取目标文件的基础目录。</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/ota/tools.html b/zh-cn/devices/tech/ota/tools.html
new file mode 100644
index 00000000..5943e417
--- /dev/null
+++ b/zh-cn/devices/tech/ota/tools.html
@@ -0,0 +1,86 @@
+<html devsite><head>
+ <title>OTA 软件包工具</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><code>build/tools/releasetools</code> 中提供的 <a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/ota_from_target_files">ota_from_target_files</a> 工具可以构建两种类型的软件包:完整更新软件包和增量更新软件包。<i></i><i></i>该工具将 Android 构建系统生成的 target_files .zip 文件作为输入文件。<i></i></p>
+
+<h2 id="full-updates">完整更新</h2>
+<p>完整更新是指软件包将对设备的整个最终状态(系统分区、启动分区和恢复分区)进行更新。<i></i>只要设备能够接收软件包并启动恢复系统,软件包就可以安装所需的版本,而不受设备当前状态的影响。</p>
+<p>示例:使用发布工具为假设的 <b>tardis</b> 设备构建完整更新:</p>
+
+<pre>
+# first, build the target-files .zip
+% <b>. build/envsetup.sh &amp;&amp; lunch tardis-eng</b>
+% <b>mkdir dist_output</b>
+% <b>make dist DIST_DIR=dist_output</b>
+ [...]
+% <b>ls -l dist_output/*target_files*</b>
+-rw-r----- 1 user eng 69965275 Sep 29 15:51 tardis-target_files.zip
+</pre>
+
+<p>target_files .zip 包含构建 OTA 软件包所需的所有内容。
+</p>
+
+<pre>
+% <b>./build/tools/releasetools/ota_from_target_files \
+ dist_output/tardis-target_files.zip ota_update.zip</b>
+unzipping target target-files...
+done.
+% <b>ls -l ota_update.zip</b>
+-rw-r----- 1 user eng 62236561 Sep 29 15:58 ota_update.zip
+</pre>
+
+<p>ota_update.zip 现已准备就绪,可以发送到测试设备(所有内容均使用测试密钥进行签名)。对于用户设备,请生成并使用自己的私钥,有关详情,请参阅<a href="/devices/tech/ota/sign_builds.html">签名版本以供发布</a>。
+
+</p><h2 id="incremental-updates">增量更新</h2>
+<p>增量更新包含一组要应用于设备上的已有数据的二进制补丁程序。<i></i>以下原因可能会导致此类更新软件包非常小:</p>
+<ul>
+<li>未更改的文件不需要包含在其中。</li>
+<li>更改的文件通常与之前的版本非常相似,因此软件包中只需包含针对两个文件之间的不同之处进行的编码。</li></ul>
+<p>只有当设备具有构建相应软件包所使用的旧版本或源版本时,您才能在设备上安装增量更新软件包。要构建增量更新,您需要拥有上一个版本(您要更新的版本)中的 target_files .zip 以及新版本中的 target_files .zip。<i></i></p>
+
+<pre>
+% <b>./build/tools/releasetools/ota_from_target_files \
+ -i PREVIOUS-tardis-target_files.zip \ </b># make incremental from this older version<b>
+ dist_output/tardis-target_files.zip incremental_ota_update.zip</b>
+unzipping target target-files...
+unzipping source target-files...
+ [...]
+done.
+% <b>ls -l incremental_ota_update.zip</b>
+-rw-r----- 1 user eng 1175314 Sep 29 16:10 incremental_ota_update.zip
+</pre>
+
+<p>该版本与上一个版本非常类似,而且增量更新软件包(约 1 MB)比对应的完整更新软件包 (60 MB) 小得多。</p>
+<p class="note"><strong>注意</strong>:要为后续更新生成<a href="/devices/tech/ota/block.html">基于块的 OTA</a>,请将 <code>--block</code> 选项传递到 <code>ota_from_target_files</code>。</p>
+<p>仅当设备运行的上一个版本与相应增量更新软件包的起点版本完全一样时,才向其分发该增量更新软件包。如果尝试在运行其他版本的设备上安装该增量包,系统将会显示恢复错误图标。此时用户只要重新启动设备,即可回到旧系统;软件包会先验证它要更新的所有文件是否已回到之前的状态,然后再对其执行操作,因此,如果发生上述情况,设备不应留在半升级状态。</p>
+
+<h2 id="update-packages">更新软件包</h2>
+<p>更新软件包(<code>ota_update.zip</code>、<code>incremental_ota_update.zip</code>)是包含可执行二进制文件 <code>META-INF/com/google/android/update-binary</code> 的 .zip 文件。对软件包上的签名进行验证后,恢复进程会将该二进制文件解压到 <code>/tmp</code> 并运行它,然后传递以下参数:</p>
+<ul>
+<li><b>更新二进制 API 版本号</b>。如果向更新二进制文件传递的参数发生变化,此数字将递增。</li>
+<li><b>命令管道的文件描述符</b>。<i></i>更新程序可以使用此管道将命令发送回恢复二进制文件(主要用于界面变化,例如向用户指示进度)。</li>
+<li><b>更新软件包 .zip 文件的文件名</b>。</li>
+</ul>
+<p>恢复软件包可以使用任何静态链接的二进制文件作为更新二进制文件。OTA 软件包构建工具使用更新程序(<code>bootable/recovery/updater</code> 中的源),该程序提供一种可以执行很多安装任务的简单脚本语言。您可以替换设备上运行的任何其他二进制文件。</p>
+<p>要详细了解更新程序二进制文件、edify 语法和内置函数,请参阅 <a href="/devices/tech/ota/inside_packages.html">OTA 软件包内部</a>。
+
+</p></body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/power/batterystats.html b/zh-cn/devices/tech/power/batterystats.html
new file mode 100644
index 00000000..ed39293d
--- /dev/null
+++ b/zh-cn/devices/tech/power/batterystats.html
@@ -0,0 +1,517 @@
+<html devsite><head>
+ <title>查看电池使用情况数据</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><code>dumpsys batterystats</code> 命令可用来生成关于设备电池使用情况的有趣统计数据,这些数据按唯一用户 ID (UID) 进行整理。统计信息包括以下内容:</p>
+
+ <ul>
+ <li>电池相关事件的历史记录</li>
+
+ <li>设备的全局统计信息</li>
+
+ <li>每个 UID 和系统组件的大致用电量</li>
+
+ <li>单个应用的每个数据包占用的移动网络毫秒数</li>
+
+ <li>系统 UID 汇总统计信息</li>
+
+ <li>应用 UID 汇总统计信息</li>
+ </ul>
+
+ <p>使用 <a href="https://github.com/google/battery-historian">Battery Historian</a> 工具可以针对 dumpsys 命令输出内容中电量相关事件的日志来生成 HTML 可视化内容。这类信息有助于更轻松地了解和诊断电池相关问题。</p>
+
+ <h2 id="command-line_options">命令输入</h2>
+ <p>基本的 <code>batterystats</code> 命令是:</p>
+ <pre class="prettyprint">
+$ adb shell dumpsys batterystats</pre>
+ <p>支持的选项:</p>
+ <ul>
+ <li><code>--help</code> 显示用于定制输出的附加选项。
+ </li>
+ <li><code>--checkin</code> 以机器可读的 csv 格式导出结果。
+ </li>
+ </ul>
+ <p>例如,要以 csv 格式打印所有应用的电池使用情况(自设备上次充电后)统计信息,可以运行以下命令:</p>
+ <pre class="prettyprint">
+$ adb shell dumpsys batterystats --charged --checkin</pre>
+ <p>您还可以指定一个文件包名称来获取单个应用的统计信息。例如,要以 csv 格式打印指定应用包的电池使用情况(自设备上次充电后)统计信息,可以运行以下命令:</p>
+ <pre class="prettyprint">
+$ adb shell dumpsys batterystats --charged &lt;package-name&gt;</pre>
+
+ <h2 id="output">命令输出</h2>
+
+ <p><code>batterystats</code> 命令可用来生成关于设备电池使用情况(自设备上次充电后)的汇总检测信息。检测信息可以基于每个 UID 也可以基于系统级别;选择要包含的数据时,则要考虑到数据在分析电池性能时的实用性。在输出内容中,每项检测信息对应一 (1) 个条目,每个条目均由采用以下格式的逗号分隔值列表组成:int,uid,mode,section,fields(一个或多个)。<em></em><em></em><em></em><em></em><em></em></p>
+
+ <p>前 4 个值对应以下内容:</p>
+
+ <ul>
+ <li>虚拟整数</li>
+
+ <li>UID</li>
+
+ <li>汇总模式<ul>
+ <li>“i”表示不与已充电/未充电状态关联的信息。</li>
+ <li>“l”表示已充电(自上次充电后的使用情况)。</li>
+ <li>“u”表示已拔下电源(自上次拔下电源后的使用情况)。在 Android 5.1.1 中已弃用。</li>
+ </ul>
+ </li>
+
+ <li><a href="#interpreting_the_output">区段标识符</a>,用于确定如何解译行中的后续值。</li>
+ </ul>
+
+<p>示例输出:</p>
+
+ <pre class="no-pretty-print">
+ 9,0,i,vers,11,116,K,L 9,0,i,uid,1000,android
+ 9,0,i,uid,1000,com.android.providers.settings
+ 9,0,i,uid,1000,com.android.inputdevices
+ 9,0,i,uid,1000,com.android.server.telecom
+ 9,0,i,uid,1000,com.android.keychain 9,0,i,uid,1000,com.android.settings
+ 9,0,i,uid,1000,com.android.location.fused
+ 9,0,i,uid,1001,com.android.providers.telephony
+ 9,0,i,uid,1001,com.android.mms.service 9,0,i,uid,1001,com.android.stk
+ 9,0,i,uid,1001,com.android.phone 9,0,i,uid,1027,com.android.nfc
+ 9,0,i,uid,2000,com.android.shell
+ 9,0,i,uid,10002,com.android.providers.calendar
+ 9,0,i,uid,10003,com.android.cellbroadcastreceiver
+ 9,0,i,uid,10004,com.android.providers.userdictionary
+ 9,0,i,uid,10004,com.android.providers.contacts
+ 9,0,i,uid,10005,com.google.android.apps.enterprise.dmagent
+ 9,0,i,uid,10006,com.android.defcontainer
+ 9,0,i,uid,10007,com.android.providers.media
+ 9,0,i,uid,10007,com.android.providers.downloads
+ 9,0,i,uid,10007,com.android.providers.downloads.ui
+ 9,0,i,uid,10008,com.android.externalstorage
+ 9,0,i,uid,10009,com.google.android.syncadapters.contacts
+ 9,0,i,uid,10009,com.google.android.gms
+ 9,0,i,uid,10009,com.google.android.gsf
+ 9,0,i,uid,10009,com.google.android.gsf.login
+ 9,0,i,uid,10009,com.google.android.backuptransport
+ 9,0,i,uid,10011,com.google.android.dialer
+ 9,0,i,uid,10013,com.google.android.onetimeinitializer
+ 9,0,i,uid,10014,com.google.android.partnersetup
+ 9,0,i,uid,10015,com.android.launcher
+ 9,0,i,uid,10016,com.android.managedprovisioning
+ 9,0,i,uid,10017,com.android.mms 9,0,i,uid,10018,com.android.musicfx
+ 9,0,i,uid,10019,com.android.vending
+ 9,0,i,uid,10022,com.android.sharedstoragebackup
+ 9,0,i,uid,10023,com.android.systemui
+ 9,0,i,uid,10025,com.google.android.googlequicksearchbox
+ 9,0,i,uid,10027,com.google.android.apps.walletnfcrel
+ 9,0,i,uid,10029,com.google.android.marvin.talkback
+ 9,0,i,uid,10031,com.google.android.apps.books
+ 9,0,i,uid,10034,com.google.android.calendar
+ 9,0,i,uid,10037,com.android.chrome
+ 9,0,i,uid,10039,com.google.android.configupdater
+ 9,0,i,uid,10040,com.google.android.deskclock
+ 9,0,i,uid,10041,com.android.documentsui
+ 9,0,i,uid,10042,com.google.android.apps.docs
+ 9,0,i,uid,10047,com.google.android.ears
+ 9,0,i,uid,10054,com.google.android.talk
+ 9,0,i,uid,10057,com.google.android.inputmethod.latin
+ 9,0,i,uid,10061,com.google.android.music
+ 9,0,i,uid,10064,com.android.packageinstaller
+ 9,0,i,uid,10068,com.google.android.apps.plus
+ 9,0,i,uid,10069,com.google.android.gm
+ 9,0,i,uid,10070,com.google.android.keep
+ 9,0,i,uid,10071,com.google.android.apps.genie.geniewidget
+ 9,0,i,uid,10072,com.android.printspooler
+ 9,0,i,uid,10076,com.google.android.videos
+ 9,0,i,uid,10079,com.google.android.youtube
+ 9,0,i,uid,10084,com.google.android.apps.magazines
+ 9,0,i,dsd,1820451,97,s-,p- 9,0,i,dsd,3517481,98,s-,p-
+ 9,0,l,bt,0,8548446,1000983,8566645,1019182,1418672206045,8541652,994188
+ 9,0,l,gn,0,0,666932,495312,0,0,2104,1444
+ 9,0,l,m,6794,0,8548446,8548446,0,0,0,666932,495312,0,697728,0,0,0,5797,0,0
+ 9,0,l,br,9,0,6785,0,0 9,0,l,sgt,8548446,0,0,0,0 9,0,l,sst,9000
+ 9,0,l,sgc,0,0,0,0,0 9,0,l,dct,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ 9,0,l,dcc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 9,0,l,wst,0,0,0,0,0,0,0,0
+ 9,0,l,wsc,0,0,0,0,0,0,0,0 9,0,l,wsst,0,0,0,0,0,0,0,52,0,0,8548394,0,0
+ 9,0,l,wssc,0,0,0,0,0,0,0,2,0,0,2,0,0 9,0,l,wsgt,0,0,0,3016,8545430
+ 9,0,l,wsgc,0,0,0,2,1 9,0,l,bst,0,0,0,0 9,0,l,bsc,0,0,0,0 9,0,l,dc,2,3,0,3
+ 9,0,l,kwl,msm_ipc_read00000001:00000001,0,0
+ 9,0,l,kwl,rpm_regulator_tcxo,0,0 9,0,l,kwl,wlan,25423,32
+ 9,0,l,kwl,event4-648,0,0 9,0,l,kwl,qcril,187,2 9,0,l,kwl,ssr(dsps),0,0
+ 9,0,l,kwl,bq51051b_wireless_chip,0,0 9,0,l,kwl,qmi0,0,0
+ 9,0,l,kwl,event5-648,7755,1231
+ 9,0,l,kwl,PowerManagerService.WakeLocks,680435,3908
+ 9,0,l,kwl,msm_hsic_host,66258,35 9,0,l,kwl,qcom_sap_wakelock,0,0
+ 9,0,l,kwl,sns_async_ev_wakelock,91954,1244 9,0,l,kwl,qmuxd_port_wl_12,0,0
+ 9,0,l,kwl,pil-wcnss,0,0 9,0,l,kwl,event0-648,11364,1212
+ 9,0,l,kwl,dofstrim,0,0 9,0,l,kwl,ssr(lpass),0,0
+ 9,0,l,kwl,qmuxd_port_wl_11,0,0 9,0,l,kwl,event2-648,0,0
+ 9,0,l,kwl,pil-vidc,0,0 9,0,l,kwl,mmc0,0,0
+ 9,0,l,kwl,tabla_gpio_irq_resend,0,0 9,0,l,kwl,pil-q6,0,0
+ 9,0,l,kwl,radio-interface,0,0 9,0,l,kwl,msm_ipc_read00000001:00000002,0,0
+ 9,0,l,kwl,event3-648,8143,1231 9,0,l,kwl,ssr(wcnss),0,0
+ 9,0,l,kwl,ssr(gss),0,0 9,0,l,kwl,KeyEvents,98,1263
+ 9,0,l,kwl,unknown_wakeups,0,0 9,0,l,kwl,qmuxd_port_wl_10,0,0
+ 9,0,l,kwl,pil-gss,0,0 9,0,l,kwl,qcom_rx_wakelock,161828,3205
+ 9,0,l,kwl,ssr(external_modem),0,0 9,0,l,kwl,power-supply,228,23
+ 9,0,l,kwl,pil-dsps,0,0 9,0,l,kwl,wcnss,0,0 9,0,l,kwl,msm_otg,0,0
+ 9,0,l,kwl,pm8921_eoc,0,0 9,0,l,kwl,slimport_wake_lock,0,0
+ 9,0,l,kwl,smsm_snapshot,0,0 9,0,l,kwl,suspend_backoff,239760,24
+ 9,0,l,kwl,event1-648,9331,1212 9,0,l,kwl,main,429,0
+ 9,0,l,kwl,alarm,2892,270 9,0,l,kwl,PowerManagerService.Display,432,1
+ 9,0,l,kwl,qmi1,0,0 9,0,l,kwl,kickstart,211,1
+ 9,0,l,kwl,qmuxd_port_wl_9,9,102 9,0,l,kwl,ear_hook,0,0
+ 9,0,l,kwl,mmc0_detect,52,1232 9,0,l,kwl,deleted_wake_locks,0,0
+ 9,0,l,kwl,PowerManagerService.Broadcasts,7331,0 9,0,l,kwl,qmi2,0,0
+ 9,0,l,kwl,smd_sns_dsps,456,1340 9,0,l,kwl,alarm_rtc,36084,122
+ 9,0,l,pws,2100,64.4,42.0,63.0 9,10009,l,pwi,uid,20.6 9,0,l,pwi,cell,18.5
+ 9,0,l,pwi,idle,8.73 9,0,l,pwi,uid,5.46 9,1000,l,pwi,uid,5.11
+ 9,0,l,pwi,wifi,3.28 9,10019,l,pwi,uid,0.847 9,10069,l,pwi,uid,0.408
+ 9,0,l,pwi,scrn,0.385 9,10034,l,pwi,uid,0.322 9,10025,l,pwi,uid,0.185
+ 9,0,l,pwi,blue,0.0273
+ 9,0,l,pwi,cell,14.0
+ 9,10002,l,pwi,uid,0.180 9,10023,l,pwi,uid,0.168 9,1001,l,pwi,uid,0.0297
+ 9,10068,l,pwi,uid,0.0296 9,10057,l,pwi,uid,0.0234 9,1027,l,pwi,uid,0.0157
+ 9,10079,l,pwi,uid,0.00905 9,10054,l,pwi,uid,0.00527
+ 9,10005,l,pwi,uid,0.00341 9,10004,l,pwi,uid,0.00204
+ 9,2000,l,pwi,uid,0.00192 9,10070,l,pwi,uid,0.00144
+ 9,10061,l,pwi,uid,0.000860 9,10014,l,pwi,uid,0.000495
+ 9,10040,l,pwi,uid,0.000286 9,1014,l,pwi,uid,0.00000157 9,0,l,pwi,over,1.36
+ 9,0,l,nt,0,0,127699,11159,0,0,975,163,0,0
+ 9,0,l,pr,file-storage,0,140,0,0,0,0 9,0,l,pr,TX_Thread,0,440,0,0,0,0
+ 9,0,l,pr,flush-179:0,0,850,0,0,0,0 9,0,l,pr,sync_supers,10,0,0,0,0,0
+ 9,0,l,pr,dhcpcd,0,30,0,0,0,0 9,0,l,pr,kauditd,50,10,0,0,0,0
+ 9,0,l,pr,sdcard,20,110,0,0,0,0 9,0,l,pr,flush-0:18,40,100,0,0,0,0
+ 9,0,l,pr,zygote,250,90,0,0,0,0 9,0,l,pr,bdi-default,0,610,0,0,0,0
+ 9,0,l,pr,ueventd,940,2630,0,0,0,0 9,0,l,pr,kswapd0,0,180,0,0,0,0
+ 9,0,l,pr,debuggerd,180,610,0,0,0,0 9,0,l,pr,jbd2/mmcblk0p20,0,50,0,0,0,0
+ 9,0,l,pr,jbd2/mmcblk0p21,0,250,0,0,0,0
+ 9,0,l,pr,jbd2/mmcblk0p22,0,90,0,0,0,0
+ 9,0,l,pr,jbd2/mmcblk0p23,0,1150,0,0,0,0 9,0,l,pr,MC_Thread,0,1270,0,0,0,0
+ 9,0,l,pr,adbd,10,40,0,0,0,0 9,0,l,pr,lmkd,360,990,0,0,0,0
+ 9,0,l,pr,logd,1550,1670,0,0,0,0 9,0,l,pr,netd,80,330,0,0,0,0
+ 9,0,l,pr,rild,160,0,0,0,0,0 9,0,l,pr,vold,50,100,0,0,0,0
+ 9,0,l,pr,/init,0,70,0,0,0,0 9,0,l,pr,mpdecision,1400,7820,0,0,0,0
+ 9,0,l,pr,khubd,0,10,0,0,0,0 9,0,l,pr,kthreadd,0,600,0,0,0,0
+ 9,0,l,pr,kworker/0:0,0,3520,0,0,0,0 9,0,l,pr,sensors.qcom,380,720,0,0,0,0
+ 9,0,l,pr,healthd,20,190,0,0,0,0 9,0,l,pr,thermald,60,360,0,0,0,0
+ 9,0,l,pr,mmcqd/0,0,8700,0,0,0,0 9,0,l,pr,qseecomd,0,90,0,0,0,0
+ 9,0,l,pr,ksoftirqd/0,0,420,0,0,0,0 9,0,l,pr,wpa_supplicant,170,160,0,0,0,0
+ 9,0,l,pr,migration/0,0,1630,0,0,0,0 9,0,l,pr,migration/1,20,0,0,0,0,0
+ 9,0,l,pr,RX_Thread,0,790,0,0,0,0 9,0,l,pr,netmgrd,40,20,0,0,0,0
+ 9,1000,l,nt,0,0,11054,11216,0,0,26,29,0,0 9,1000,l,ua,2,0,0
+ 9,1000,l,sr,5,6813,1 9,1000,l,wl,*alarm*,0,f,0,23856,p,151,0,w,0
+ 9,1000,l,st,8548446,8548446,8548446 9,1000,l,pr,system,83310,35060,0,0,0,0
+ 9,1000,l,pr,surfaceflinger,6620,9330,0,0,0,0 9,1000,l,pr,ks,0,60,0,0,0,0
+ 9,1000,l,pr,qcks,0,90,0,0,0,0 9,1000,l,pr,efsks,0,50,0,0,0,0
+ 9,1000,l,pr,com.android.server.telecom,110,100,0,0,0,0
+ 9,1000,l,pr,servicemanager,40,110,0,0,0,0
+ 9,1001,l,st,8548446,8548446,8548446 9,1001,l,pr,qmuxd,0,30,0,0,0,0
+ 9,1001,l,pr,com.android.phone,450,300,0,0,0,0
+ 9,1014,l,nt,0,0,3410,3370,0,0,10,10,0,0 9,1027,l,st,8548446,8548446,8548446
+ 9,1027,l,pr,com.android.nfc,250,160,0,0,0,0
+ 9,10002,l,apk,15,com.android.providers.calendar,com.android.providers.calendar.CalendarProviderIntentService,2383,15,15
+ 9,10005,l,nt,0,0,1241,2488,0,0,6,10,0,0
+ 9,10009,l,nt,0,0,232255,258511,0,0,472,600,0,0
+ 9,10009,l,wfl,7689000,9814000,0
+ 9,10009,l,jb,com.google.android.gms/.gcm.nts.TaskExecutionService,81,3
+ 9,10009,l,sr,0,43643,46 9,10025,l,nt,0,0,152461,42850,0,0,267,243,0,0
+ 9,10025,l,wfl,1593000,629000,0 9,10034,l,nt,0,0,77657,40093,0,0,172,170,0,0
+ 9,10068,l,nt,0,0,11929,8383,0,0,50,47,0,0
+ 9,10069,l,nt,0,0,41553,22886,0,0,85,91,0,0</pre>
+
+ <h2 id="interpreting_the_output">区段标识符</h2>
+
+ <p><code>batterystats</code> 的命令输出支持以下区段:</p>
+
+ <table id="batterystats-section-ids">
+
+ <tbody><tr>
+ <th width="10%">区段标识符</th>
+ <th width="20%">说明</th>
+ <th width="70%">其余字段</th>
+ </tr>
+
+ <tr>
+ <td><p>vers</p></td>
+ <td><p>版本</p></td>
+ <td><p>签入版本、parcel 版本、启动平台版本、结束平台版本</p></td>
+ </tr>
+
+ <tr>
+ <td><p>uid</p></td>
+ <td><p>UID</p></td>
+ <td><p>uid、软件包名称</p></td>
+ </tr>
+
+ <tr>
+ <td><p>apk</p></td>
+ <td><p>APK</p></td>
+ <td><p>唤醒、APK、服务、开始时间、启动、发布</p></td>
+ </tr>
+
+ <tr>
+ <td><p>pr</p></td>
+ <td><p>进程</p></td>
+ <td><p>进程、用户、系统、前台、启动</p></td>
+ </tr>
+
+ <tr>
+ <td><p>sr</p></td>
+ <td><p>传感器</p></td>
+ <td><p>传感器编号、时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>vib</p></td>
+ <td><p>振动器</p></td>
+ <td><p>时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>fg</p></td>
+ <td><p>前台</p></td>
+ <td><p>时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>st</p></td>
+ <td><p>状态时间</p></td>
+ <td><p>前台、活动、正在运行</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wl</p></td>
+ <td><p>唤醒锁</p></td>
+ <td><p>唤醒锁定、完整时间、“f”、完整计数、部分时间、“p”、部分计数、窗口时间、“w”、窗口计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>sy</p></td>
+ <td><p>同步</p></td>
+ <td><p>同步、时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>jb</p></td>
+ <td><p>作业</p></td>
+ <td><p>作业、时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>kwl</p></td>
+ <td><p>内核唤醒锁定</p></td>
+ <td><p>内核唤醒锁定、时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wr</p></td>
+ <td><p>唤醒原因</p></td>
+ <td><p>唤醒原因、时间、计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>nt</p></td>
+ <td><p>网络</p></td>
+ <td><p>移动字节 RX、移动字节 TX、WLAN 字节 RX、WLAN 字节 TX、移动数据包 RX、移动数据包 TX、WLAN 数据包 RX、WLAN 数据包 TX、移动设备活动时间、移动设备活动计数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>ua</p></td>
+ <td><p>用户活动</p></td>
+ <td><p>其他、按钮、触摸</p></td>
+ </tr>
+
+ <tr>
+ <td><p>bt</p></td>
+ <td><p>电池</p></td>
+ <td><p>开始计数、电池实时、电池正常运行时间、总实时、总正常运行时间、开始时钟时间、电池屏幕关闭实时、电池屏幕关闭正常运行时间</p></td>
+ </tr>
+
+ <tr>
+ <td><p>dc</p></td>
+ <td><p>电池耗电</p></td>
+ <td><p>低、高、屏幕开启、屏幕关闭</p></td>
+ </tr>
+
+ <tr>
+ <td><p>lv</p></td>
+ <td><p>电量</p></td>
+ <td><p>开始电量、当前电量</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wfl</p></td>
+ <td><p>WLAN</p></td>
+ <td><p>完整 WLAN 锁定时间、WLAN 扫描时间、WLAN 运行时间、WLAN 扫描计数、WLAN 闲置时间、WLAN 接收时间、WLAN 传输时间</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><p>gwfl</p></td>
+ <td><p>全局 WLAN</p></td>
+ <td><p>WLAN 开启时间、WLAN 运行时间、WLAN 闲置时间、WLAN 接收时间、WLAN 传输时间、WLAN 功率(毫安时)</p></td>
+ </tr>
+
+ <tr>
+ <td><p>gble</p></td>
+ <td><p>全局蓝牙</p></td>
+ <td><p>BT 闲置时间、BT 接收时间、BT 传输时间、BT 功率(毫安时)</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><p>m</p></td>
+ <td><p>其他</p></td>
+ <td><p>屏幕开启时间、手机开机时间、完整唤醒锁定总时间、部分唤醒锁定总时间、移动无线装置运行时间、移动无线装置运行调整时间、交互时间、节能模式启用时间、连接更改、设备闲置模式启用时间、设备闲置模式启用计数、设备闲置时间、设备闲置计数、移动无线装置活动计数、移动无线装置活动未知时间</p></td>
+ </tr>
+
+ <tr>
+ <td><p>gn</p></td>
+ <td><p>全局网络</p></td>
+ <td><p>移动 RX 总字节数、移动 TX 总字节数、WLAN RX 总字节数、WLAN TX 总字节数、移动 RX 总数据包数、移动 TX 总数据包数、WLAN RX 总数据包数、WLAN TX 总数据包数</p></td>
+ </tr>
+
+ <tr>
+ <td><p>br</p></td>
+ <td><p>屏幕亮度</p></td>
+ <td><p>黑暗、昏暗、中等、柔光、明亮</p></td>
+ </tr>
+
+ <tr>
+ <td><p>sst</p></td>
+ <td><p>信号扫描时间</p></td>
+ <td><p>信号扫描时间</p></td>
+ </tr>
+
+ <tr>
+ <td><p>sgt</p></td>
+ <td><p>信号强度时间</p></td>
+ <td><p>无、差、一般、良好、强</p></td>
+ </tr>
+
+ <tr>
+ <td><p>sgc</p></td>
+ <td><p>信号强度计数</p></td>
+ <td><p>无、差、一般、良好、强</p></td>
+ </tr>
+
+ <tr>
+ <td><p>dct</p></td>
+ <td><p>数据连接时间</p></td>
+ <td><p>无、GPRS、EDGE、UMTS、CDMA、EVDO_0、EVDO_A、1xRTT、HSDPA、HSUPA、HSPA、IDEN、EVDO_B、LTE、EHRPD、HSPAP、其他</p></td>
+ </tr>
+
+ <tr>
+ <td><p>dcc</p></td>
+ <td><p>数据连接计数</p></td>
+ <td><p>无、GPRS、EDGE、UMTS、CDMA、EVDO_0、EVDO_A、1xRTT、HSDPA、HSUPA、HSPA、IDEN、EVDO_B、LTE、EHRPD、HSPAP、其他</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wst</p></td>
+ <td><p>WLAN 状态时间</p></td>
+ <td><p>关闭、关闭扫描、无网络、断开连接、已连接 STA、已连接 P2P、已连接 STA P2P、软 AP</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wsc</p></td>
+ <td><p>WLAN 状态计数</p></td>
+ <td><p>关闭、关闭扫描、无网络、断开连接、已连接 STA、已连接 P2P、已连接 STA P2P、软 AP</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wsst</p></td>
+ <td><p>WLAN 客户端状态时间</p></td>
+ <td><p>无效、已断开连接、接口已停用、不活动、正在扫描、正在进行身份验证、正在关联、已关联、四步握手、组握手、已完成、休眠、未初始化</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wssc</p></td>
+ <td><p>WLAN 客户端状态计数</p></td>
+ <td><p>无效、已断开连接、接口已停用、不活动、正在扫描、正在进行身份验证、正在关联、已关联、四步握手、组握手、已完成、休眠、未初始化</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wsgt</p></td>
+ <td><p>WLAN 信号强度时间</p></td>
+ <td><p>无、差、一般、良好、强</p></td>
+ </tr>
+
+ <tr>
+ <td><p>wsgc</p></td>
+ <td><p>WLAN 信号强度计数</p></td>
+ <td><p>无、差、一般、良好、强</p></td>
+ </tr>
+
+ <tr>
+ <td><p>bst</p></td>
+ <td><p>蓝牙状态时间</p></td>
+ <td><p>不活动、低、中、高</p></td>
+ </tr>
+
+ <tr>
+ <td><p>bsc</p></td>
+ <td><p>蓝牙状态计数</p></td>
+ <td><p>不活动、低、中、高</p></td>
+ </tr>
+
+ <tr>
+ <td><p>pws</p></td>
+ <td><p>耗电量汇总</p></td>
+ <td><p>电池容量、计算的用电量、最低耗电量、最高耗电量</p></td>
+ </tr>
+
+ <tr>
+ <td><p>pwi</p></td>
+ <td><p>耗电项</p></td>
+ <td><p>标签、毫安时</p></td>
+ </tr>
+
+ <tr>
+ <td><p>dsd</p></td>
+ <td><p>耗电步骤</p></td>
+ <td><p>时长、级别、屏幕、节电</p></td>
+ </tr>
+
+ <tr>
+ <td><p>csd</p></td>
+ <td><p>充电步骤</p></td>
+ <td><p>时长、级别、屏幕、节电</p></td>
+ </tr>
+
+ <tr>
+ <td><p>dtr</p></td>
+ <td><p>耗电剩余时间</p></td>
+ <td><p>电池剩余时间</p></td>
+ </tr>
+
+ <tr>
+ <td><p>ctr</p></td>
+ <td><p>充电剩余时间</p></td>
+ <td><p>充电剩余时间</p></td>
+ </tr>
+
+ </tbody></table>
+
+<h2 id="wifi-reqs">蓝牙、移动网络和 WLAN 电池使用情况</h2>
+
+<p>要实现对蓝牙、移动网络和 WLAN 数据网络的电池使用情况数据支持,设备蓝牙、移动网络和 WLAN 芯片组需要实现无线电支持,且芯片组固件需要将使用情况数据传递到框架。原始设备制造商 (OEM) 必须与其芯片组提供商合作,以推动现有芯片组的现场固件更新和新芯片组上的兼容固件更新。</p>
+
+<p>此外,原始设备制造商 (OEM) 必须继续配置并提交其设备的电源配置文件。不过,当平台检测到蓝牙、移动网络(截至 Android 7.0)或 WLAN 无线电源数据可从芯片组获得时,它会使用芯片组数据,而非电源配置文件数据。有关详情,请参阅<a href="/devices/tech/power/values.html#values">电源值</a>。</p>
+
+<p class="note"><strong>注意</strong>:对于 Android 6.0 之前的版本,蓝牙无线电、移动网络无线电以及 WLAN 的耗电量在 m (Misc) 区段类别中进行跟踪。<em></em>在 Android 6.0 及更高版本中,这些组件的耗电量在 pwi(耗电项)区段进行跟踪,其中每个组件均使用单独的标签(wlan、blue、cell)。<em></em><em></em><em></em><em></em></p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/test_infra/tradefed/fundamentals/devices.html b/zh-cn/devices/tech/test_infra/tradefed/fundamentals/devices.html
new file mode 100644
index 00000000..f0680423
--- /dev/null
+++ b/zh-cn/devices/tech/test_infra/tradefed/fundamentals/devices.html
@@ -0,0 +1,44 @@
+<html devsite><head>
+ <title>使用设备</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>Trade Federation 使用名为 <code><a href="/reference/com/android/tradefed/device/ITestDevice.html">ITestDevice</a></code> 的抽象类来运行测试。该抽象类可将最通用的 Android 设备具体化:</p>
+<ul>
+<li>具有序列号</li>
+<li>具有状态:在线、可用、恢复或不可用</li>
+<li>有一些可靠性的概念。例如,如果我们运行某个命令,则可以区分命令尚未完成的情况、设备不支持运行命令的情况以及设备在运行命令时变得无响应的情况。</li>
+</ul>
+
+<h2>不同类别的设备</h2>
+<p><code>ITestDevice</code> 的 3 种主要实现代表 3 种常见的用例。</p>
+
+<h3>物理设备</h3>
+<p>这是一种实际的硬件,通过 USB 或使用 adb 的 TCP 功能连接到 TF 主机。<a href="/reference/com/android/tradefed/device/TestDevice.html">TestDevice</a> 类位于 ddmlib 库的顶部,它是一个面向 adb 的 Java 接口。因此,<code>adb devices</code> 中列出的任何物理设备都可以实例化并用作 <code>TestDevice</code>。
+</p>
+
+<h3>模拟器</h3>
+<p>模拟器位于其他进程中,因此经过 TF 的特殊处理。要与模拟器交互,请为命令指定 <code>--emulator</code> 参数。有关详情,请参阅 <a href="/reference/com/android/tradefed/build/LocalSdkBuildProvider.html">LocalSdkBuildProvider</a> 和 <a href="/reference/com/android/tradefed/targetprep/SdkAvdPreparer.html">SdkAvdPreparer</a>。</p>
+
+<h3>无设备</h3>
+<p>假设您有一个测试根本不与设备交互。例如,它可能只是从某项服务下载文件,并验证文件本身是否有效。<a href="/reference/com/android/tradefed/device/NullDevice.html">NullDevice</a> 是一项 <code>ITestDevice</code>,只是一个存根。它拥有诸如 <code>null-device-N</code> 这样的序列号,并且尝试最多的操作是静默 no-op 或抛出操作。
+</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/test_infra/tradefed/fundamentals/options.html b/zh-cn/devices/tech/test_infra/tradefed/fundamentals/options.html
new file mode 100644
index 00000000..88277ff7
--- /dev/null
+++ b/zh-cn/devices/tech/test_infra/tradefed/fundamentals/options.html
@@ -0,0 +1,73 @@
+<html devsite><head>
+ <title>选项处理</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>选项处理是 Trade Federation 模块化方法的核心。具体而言,选项是一种机制,让开发者、集成者和测试运行者通过该机制可以共同协作,而不会重复相互的工作。简单地说,实现选项处理后,开发者可将 Java 类成员标记为可配置,届时该成员的值可被集成者增强或覆盖,并且随后可被测试运行者增强或覆盖。该机制适用于所有 Java 固有类型,以及固有类型的任何 <code>Map</code> 或 <code>Collection</code>。</p>
+
+<p class="note"><strong>注意</strong>:选项处理机制仅适用于实现<a href="lifecycle.html">测试生命周期</a>内包含的接口之一的类,并且仅当该类由生命周期机制实例化时才适用。<em></em></p>
+
+<h2 id="developer">开发者</h2>
+<p>要开始使用,开发者需要为成员添加 <code><a href="https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/config/Option.java">@Option</a></code> 注释。<!-- note: javadoc for the Option class is broken -->开发者需要至少指定 <code>name</code> 和 <code>description</code> 值,这两个值指定与该选项关联的参数名称和说明(后者在命令使用 <code>--help</code> 或 <code>--help-all</code> 运行时在 TF 控制台中显示)。</p>
+
+<p>举例来说,假设我们要构建一个功能完善的电话测试,我们会在测试中拨打各种电话号码,并预期在每个号码连接后收到一系列 DTMF 音。</p>
+<code><pre>public class PhoneCallFuncTest extends IRemoteTest {
+ @Option(name = "timeout", description = "How long to wait for connection, in millis")
+ private long mWaitTime = 30 * 1000; // 30 seconds
+
+ @Option(name = "call", description = "Key: Phone number to attempt. " +
+ "Value: DTMF to expect. May be repeated.")
+ private Map&lt;String, String&gt; mCalls = new HashMap&lt;String, String&gt;;
+
+ public PhoneCallFuncTest() {
+ mCalls.add("123-456-7890", "01134"); // default
+ }</pre></code>
+
+<p>以上就是开发者为该测试设置两个配置点的所有要求。开发者随后可以正常离开并使用 <code>mWaitTime</code> 和 <code>mCalls</code>,无需特别留意它们可进行配置这一事实。由于 <code>@Option</code> 字段在类实例化之后、<code>run</code> 方法调用之前设置,因此实现人员可以轻松为 <code>Map</code> 和 <code>Collection</code> 字段设置默认值或执行某类筛选操作,否则只能附加这些字段。</p>
+
+<h2 id="integrator">集成者</h2>
+<p>集成者的工作重心是编写 XML 格式的配置。该配置格式允许集成者为任何 <code>@Option</code> 字段设置(或附加)值。例如,假设集成者想要定义调用默认数值的低延迟测试,以及调用各种数值的运行时间较长的测试。集成者可以创建一对配置,可能如下所示:</p>
+
+<code><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;configuration description="low-latency default test; low-latency.xml"&gt;
+ &lt;test class="com.example.PhoneCallFuncTest"&gt;
+ &lt;option name="timeout" value="5000" /&gt;
+ &lt;/test&gt;
+&lt;/configuration&gt;</pre></code>
+
+<code><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;configuration description="call a bunch of numbers; many-numbers.xml"&gt;
+ &lt;test class="com.example.PhoneCallFuncTest"&gt;
+ &lt;option name="call" key="111-111-1111" value="#*#*TEST1*#*#" /&gt;
+ &lt;option name="call" key="222-222-2222" value="#*#*TEST2*#*#" /&gt;
+ &lt;!-- ... --&gt;
+ &lt;/test&gt;
+&lt;/configuration&gt;</pre></code>
+
+<h2 id="testrunner">测试运行者</h2>
+<p>测试运行者也可以通过 Trade Federation 控制台访问这些配置点。首先也是最重要的是,他们要使用 <code>run command &lt;name&gt;</code>(简称 <code>run &lt;name&gt;</code>)指令运行一个命令(即一个配置及其所有参数)。除此之外,他们可以指定任何参数列表作为命令的一部分,这可能替换或附加到各个配置内的生命周期对象指定的字段。</p>
+
+<p>要使用 <code>many-numbers</code> 电话号码运行低延迟测试,测试运行者可以执行:</p>
+<code><pre>tf &gt;run low-latency.xml --call 111-111-1111 #*#*TEST1*#*# --call 222-222-2222 #*#*TEST2*#*#</pre></code>
+
+<p>或者,要从相反方向获得类似的效果,测试运行者可以减少 <code>many-numbers</code> 测试的等待时间:</p>
+<code></code><pre><code>tf &gt;run many-numbers.xml --timeout 5000</code></pre>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/tech/test_infra/tradefed/index.html b/zh-cn/devices/tech/test_infra/tradefed/index.html
new file mode 100644
index 00000000..82c71c93
--- /dev/null
+++ b/zh-cn/devices/tech/test_infra/tradefed/index.html
@@ -0,0 +1,61 @@
+<html devsite><head>
+ <title>Trade Federation 概览</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>Trade Federation(简称 tradefed 或 TF)是一种连续的测试框架,专门用于在 Android 设备上运行测试。这款 Java 应用会在主机上运行,并会使用 ddmlib(DDMS 背后的内容库)通过 adb 与一部或多部 Android 设备进行通信。</p>
+
+<p>我们在下面列出了 TF 的一些主要功能以及几个使用情形示例。也就是说,如果您想直接进入正题并开始使用,则可直接前往<a href="/devices/tech/test_infra/tradefed/fundamentals/index.html">开始使用</a>页面。</p>
+
+<h2 id="features">功能</h2>
+<ul>
+<li>模块化、灵活、可扩展的设计</li>
+<li>已内置对运行很多不同类型 Android 测试的支持:<a href="http://developer.android.com/tools/testing/testing_android.html#Instrumentation">instrumentation</a>、<a href="http://developer.android.com/tools/testing/testing_ui.html">uiautomator</a>、native/gtest、基于主机的 JUnit,等等</li>
+<li>在 adb 的基础之上提供可靠性和恢复机制</li>
+<li>支持同时在多部设备上安排和运行测试</li>
+</ul>
+
+<h2 id="usecases">Trade Federation 使用情形示例</h2>
+<p>使用 Trade Federation 的模块化功能可以轻松进入具有现有构建、测试和报告基础设施的环境。我们在下面列出了几个示范性使用情形,在这些情形中,tradefed 能够实施有效的可扩展测试做法。</p>
+
+<p>首先,从“哪些部分可被修改,哪些部分固定不变?”这个问题来考虑潜在使用情形的格局非常有用。例如,原始设备制造商 (OEM) 可以修改框架、系统和硬件,但对现有应用的影响微乎其微。与此相反,应用开发者可以修改应用,但对系统或框架的大多数方面几乎没有控制权。</p>
+
+<p>因此,每个使用情形中的实体将会具有不同的测试目标,并会具有不同的选项(如果一组测试失败的话)。尽管存在这些差异,Trade Federation 仍有助于确保每个测试流程有效、灵活且可扩展。</p>
+
+<h3 id="oem">原始设备制造商</h3>
+<p>原始设备制造商会构建硬件,且通常会调整 Android 系统和框架以使其在该硬件上运行良好。原始设备制造商可能会努力实现这些目标,同时在硬件和系统级别保持稳定性和性能,并确保框架变更不会破坏与现有应用的兼容性。</p>
+
+<p>原始设备制造商可以实现将在<a href="/devices/tech/test_infra/tradefed/fundamentals/lifecycle.html">生命周期</a>的目标设置阶段执行的设备刷写模块。该模块将在其执行期间完全控制设备,所以它可能会强制设备进入引导加载程序、进行刷写,然后强制设备重新启动回用户空间模式。与模块结合以连接到连续构建系统,这使得原始设备制造商能够在更改系统级固件和 Java 级框架时在其设备上运行测试。</p>
+
+<p>当设备完全启动后,原始设备制造商将能够利用基于 JUnit 的现有测试,或者编写新测试,来验证相关功能。最后,他们可以编写一个或多个结果报告模块,以连接到现有的测试结果存储区,或者直接报告结果(例如<a href="/reference/com/android/tradefed/result/EmailResultReporter.html">通过电子邮件</a>)。</p>
+
+<h3 id="developer">应用开发者</h3>
+<p>应用开发者会构建需能在各种平台版本和各种设备上运行良好的应用。如果某个特定的平台版本和/或设备出现问题,唯一的补救措施就是添加解决方法并继续操作。对于大型开发者而言,测试流程可能会并入连续构建序列。对于小型开发者而言,测试流程可能会定期或手动启动。</p>
+
+<p>大多数应用开发者会使用 TF 中已有的 apk 测试安装模块。其中有一个可<a href="/reference/com/android/tradefed/targetprep/InstallApkSetup.html">从本地文件系统安装</a>的版本,还有一个可<a href="/reference/com/android/tradefed/targetprep/InstallBuildEnvApkSetup.html">安装从构建服务下载的 apk</a> 的版本。请务必注意,无论同一主机上运行着多少个 TF 实例,后一版本都能持续正常运行。</p>
+
+<p>由于 TF 能够游刃有余地处理多部设备,所以按照该测试所用设备的类型对每项测试结果进行分类会很简便。因此,TF 有可能会分别为相应应用的每个版本生成一个二维(或多维)兼容性矩阵。</p>
+
+<h3 id="testing">测试服务</h3>
+<p>举例来说,测试服务让应用开发者既能提交应用,又能在使用电量测量工具以确定应用的耗电量的设备上运行测试。这与之前的两个使用情形不同,因为服务构建工具不会控制设备或所运行的应用。</p>
+
+<p>因为 Trade Federation 可以运行任何能实现简单的 <a href="/reference/com/android/tradefed/testtype/IRemoteTest.html"><code>IRemoteTest</code></a> 接口的 Java 类,所以编写可协调某些外部硬件与在设备上运行的测试情形的驱动程序轻而易举。驱动程序本身可以生成线程、向其他服务器发送请求,或执行它可能需要的其他任何操作。此外,结果报告接口 <a href="/reference/com/android/tradefed/result/ITestInvocationListener.html"><code>ITestInvocationListener</code></a> 的简单性和多功能性意味着,在标准结果报告渠道中呈现任意测试结果(包括数字功率指标等)会同样简便。</p>
+
+</body></html> \ No newline at end of file