Mark ab/6881855 as merged
Bug: 172690556
Change-Id: Id68ac84043dc8a8ceacb5e54be1d77beff8e16ed
diff --git a/base/include/hidl/MQDescriptor.h b/base/include/hidl/MQDescriptor.h
index 786c1be..0429444 100644
--- a/base/include/hidl/MQDescriptor.h
+++ b/base/include/hidl/MQDescriptor.h
@@ -57,12 +57,6 @@
return mGrantors;
}
- // This should be removed if no one is using it. We shouldn't be returning
- // a mutable reference if it's not necessary. TODO(b/162465295).
- inline ::android::hardware::hidl_vec<GrantorDescriptor> &grantors() {
- return mGrantors;
- }
-
inline const ::native_handle_t *handle() const {
return mHandle;
}
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index cbe7ac6..8122324 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -190,22 +190,50 @@
__attribute__((noinline)) static long getProcessAgeMs() {
constexpr const int PROCFS_STAT_STARTTIME_INDEX = 21;
std::string content;
- android::base::ReadFileToString("/proc/self/stat", &content, false);
- auto stats = android::base::Split(content, " ");
- if (stats.size() <= PROCFS_STAT_STARTTIME_INDEX) {
- LOG(INFO) << "Could not read starttime from /proc/self/stat";
+ if (!android::base::ReadFileToString("/proc/self/stat", &content, false)) {
+ LOG(ERROR) << "Process age: Could not read /proc/self/stat";
return -1;
}
- const std::string& startTimeString = stats[PROCFS_STAT_STARTTIME_INDEX];
- static const int64_t ticksPerSecond = sysconf(_SC_CLK_TCK);
- const int64_t uptime = android::uptimeMillis();
- unsigned long long startTimeInClockTicks = 0;
- if (android::base::ParseUint(startTimeString, &startTimeInClockTicks)) {
- long startTimeMs = 1000ULL * startTimeInClockTicks / ticksPerSecond;
- return uptime - startTimeMs;
+ std::vector<std::string> stats = android::base::Split(content, " ");
+ if (PROCFS_STAT_STARTTIME_INDEX >= stats.size()) {
+ LOG(ERROR) << "Process age: Could not read starttime from /proc/self/stat";
+ return -1;
}
- return -1;
+
+ const std::string& startTimeString = stats.at(PROCFS_STAT_STARTTIME_INDEX);
+ unsigned long long startTimeInClockTicks = 0;
+ if (!android::base::ParseUint(startTimeString, &startTimeInClockTicks)) {
+ LOG(ERROR) << "Process age: Could not parse start time: " << startTimeString;
+ return -1;
+ }
+
+ const int64_t ticksPerSecond = sysconf(_SC_CLK_TCK);
+ if (ticksPerSecond <= 0) {
+ LOG(ERROR) << "Process age: Invalid _SC_CLK_TCK: " << ticksPerSecond;
+ return -1;
+ }
+
+ const int64_t uptime = android::uptimeMillis();
+ if (uptime < 0) {
+ LOG(ERROR) << "Process age: Invalid uptime: " << uptime;
+ return -1;
+ }
+
+ unsigned long long startTimeTicks;
+ if (__builtin_umulll_overflow(1000ULL, startTimeInClockTicks, &startTimeTicks)) {
+ LOG(ERROR) << "Process age: Too many ticks, overflow: " << startTimeInClockTicks;
+ return -1;
+ }
+
+ long startTimeMs = startTimeTicks / ticksPerSecond;
+ if (startTimeMs >= uptime) {
+ LOG(ERROR) << "Process age: process started in future: " << startTimeMs << " after "
+ << uptime;
+ return -1;
+ }
+
+ return uptime - startTimeMs;
}
static void onRegistrationImpl(const std::string& descriptor, const std::string& instanceName) {
diff --git a/vintfdata/Android.mk b/vintfdata/Android.mk
index d873e29..a7721c2 100644
--- a/vintfdata/Android.mk
+++ b/vintfdata/Android.mk
@@ -128,3 +128,5 @@
SYSTEM_EXT_MANIFEST_INPUT_FILES :=
DEVICE_MATRIX_INPUT_FILE :=
PRODUCT_MANIFEST_INPUT_FILES :=
+
+VINTF_FRAMEWORK_MANIFEST_FROZEN_DIR := $(LOCAL_PATH)/frozen
diff --git a/vintfdata/README.md b/vintfdata/README.md
new file mode 100644
index 0000000..cfc1da7
--- /dev/null
+++ b/vintfdata/README.md
@@ -0,0 +1,91 @@
+# Updating the latest framework manifest
+
+## Adding new HALs / Major version update
+
+Add a new `<hal>` entry without a `max-level` attribute. The `<hal>` entry can
+be added to the main manifest under `manifest.xml`, or to the manifest
+fragment for the server module specified in `vintf_fragments`.
+
+Introducing new HALs are backwards compatible.
+
+## Minor version update
+
+When a framework HAL updates its minor version, simply update the `<version>` or
+`<fqname>` field to the latest version. This is the same as any other HALs.
+
+For example, when `IServiceManager` updates to 1.2, change its `<fqname>` field
+to `@1.2::IServiceManager/default`.
+
+Because minor version updates are backwards compatible, all devices that require
+a lower minor version of the HAL are still compatible.
+
+Leave `max-level` attribute empty.
+
+## Deprecating HAL
+
+When a framework HAL is deprecated, set `max-level` field of the HAL from empty
+to the last frozen version.
+For example, if IDisplayService is deprecated in Android S, set `max-level` to
+Android R (5):
+
+```xml
+<manifest version="3.0" type="framework">
+ <hal format="hidl" max-level="5"> <!-- Level::R -->
+ <name>android.frameworks.displayservice</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.0::IDisplayService/default</fqname>
+ </hal>
+</manifest>
+```
+
+Note that the `max-level` of the HAL is set to Android R, meaning that the HAL
+is last available in Android R and disabled in Android S.
+
+Deprecating a HAL doesn’t mean dropping support of the HAL, so no devices will
+break.
+
+When setting `max-level` of a HAL:
+- If `optional="false"` in frozen DCMs, the build system checks that adding the
+ attribute does not break backwards compatibility; that is,
+ `max-level > last_frozen_level`.
+- If `optional="true"`, the check is disabled. Care must be taken to ensure
+ `max-level` is set appropriately.
+
+## Removing HAL
+
+When the framework drops support of a certain HAL, the corresponding HAL entry
+is removed from the framework manifest, and code that serves and registers the
+HAL must be removed simultaneously.
+
+Devices that are lower than the `max-level` attribute of the HAL may start to
+break if they require this HAL. Hence, this must only be done when there is
+enough evidence that the devices are not updateable to the latest Android
+release.
+
+# Freezing framework HAL manifest
+
+First, check `libvintf` or `hardware/interfaces/compatibility_matrices` to
+determine the current level.
+
+Execute the following, replacing the argument with the level to freeze:
+
+```shell script
+lunch cf_x86_phone-userdebug # or any generic target
+LEVEL=5
+./freeze.sh ${LEVEL}
+```
+
+A new file, `frozen/${LEVEL}.xml`, will be created after the command is
+executed. Frozen system manifests are stored in compatibility matrices. Then,
+manually inspect the frozen compatibility matrix. Modify the `optional`
+field for certain HALs. See comments in the compatibility matrix of the previous
+level for details.
+
+These compatibility matrices served as a reference for devices at that
+target FCM version. Devices at the given target FCM version should
+reference DCMs in the `frozen/` dir, with some of the HALs marked
+as `optional="true"` or even omitted if unused by device-specific code.
+
+At build time, compatibiltiy is checked between framework manifest and
+the respective frozen DCM. HALs in the framework manifest with `max-level`
+less than the specified level are omitted.
diff --git a/vintfdata/freeze.sh b/vintfdata/freeze.sh
new file mode 100755
index 0000000..a624ee3
--- /dev/null
+++ b/vintfdata/freeze.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+mydir="$(dirname $0)"
+
+function freeze() {
+ [[ $# == 1 ]] || {
+ echo "usage: freeze.sh <level>"
+ echo "e.g. To freeze framework manifest for Android R, run:"
+ echo " freeze.sh 5"
+ return 1
+ }
+ local level="$1"
+ [[ "${ANDROID_BUILD_TOP}" ]] || {
+ echo "ANDROID_BUILD_TOP is not set; did you run envsetup.sh?"
+ return 1
+ }
+ [[ "${ANDROID_HOST_OUT}" ]] || {
+ echo "ANDROID_HOST_OUT is not set; did you run envsetup.sh?"
+ return 1
+ }
+
+ local modules_to_build=check-vintf-all
+ echo "Building ${modules_to_build}"
+ "${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash" --build-mode --all-modules --dir="$(pwd)" ${modules_to_build} || {
+ echo "${modules_to_build} failed. Backwards compatibility might be broken."
+ echo "Check framework manifest changes. If this is intentional, run "
+ echo " \`vintffm --update\` with appropriate options to update frozen files."
+ return 1
+ }
+
+ echo "Updating level ${level}"
+ "${ANDROID_HOST_OUT}/bin/vintffm" --update --level "${level}" --dirmap "/system:${ANDROID_PRODUCT_OUT}/system" "${mydir}/frozen" || return 1
+
+ local files_to_diff="$(printf "${mydir}/frozen/%s\n" $(ls -1 -t -r ${mydir}/frozen | xargs -I{} basename {} | grep -B1 "${level}.xml"))"
+
+ echo
+ echo "Summary of changes:"
+ echo diff ${files_to_diff}
+ diff ${files_to_diff} || true
+}
+
+freeze $@
diff --git a/vintfdata/frozen/5.xml b/vintfdata/frozen/5.xml
new file mode 100644
index 0000000..525829d
--- /dev/null
+++ b/vintfdata/frozen/5.xml
@@ -0,0 +1,110 @@
+<compatibility-matrix version="3.0" type="device">
+ <!--
+ cameraserver is installed for all phones and tablets, but not
+ auto or TV.
+ -->
+ <hal format="hidl" optional="true">
+ <name>android.frameworks.cameraservice.service</name>
+ <version>2.1</version>
+ <interface>
+ <name>ICameraService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.displayservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>IDisplayService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.schedulerservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISchedulingPolicyService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.sensorservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISensorManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.stats</name>
+ <version>1.0</version>
+ <interface>
+ <name>IStats</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.media.c2</name>
+ <version>1.1</version>
+ <interface>
+ <name>IComponentStore</name>
+ <instance>software</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.allocator</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAllocator</name>
+ <instance>ashmem</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.manager</name>
+ <version>1.2</version>
+ <interface>
+ <name>IServiceManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.memory</name>
+ <version>1.0</version>
+ <interface>
+ <name>IMapper</name>
+ <instance>ashmem</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.token</name>
+ <version>1.0</version>
+ <interface>
+ <name>ITokenManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.net.netd</name>
+ <version>1.1</version>
+ <interface>
+ <name>INetd</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.suspend</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISystemSuspend</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.wifi.keystore</name>
+ <version>1.0</version>
+ <interface>
+ <name>IKeystore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</compatibility-matrix>
diff --git a/vintfdata/manifest.xml b/vintfdata/manifest.xml
index e204671..8fd69b9 100644
--- a/vintfdata/manifest.xml
+++ b/vintfdata/manifest.xml
@@ -35,7 +35,12 @@
<instance>default</instance>
</interface>
</hal>
- <hal>
+ <!--
+ Instead of calling this, prefer to set priority in init .rc files via
+ `ioprio <class> <priority>`. For more information, see
+ system/core/init/README.md
+ -->
+ <hal max-level="5">
<name>android.frameworks.schedulerservice</name>
<transport>hwbinder</transport>
<version>1.0</version>