Snap for 7110675 from a89f743b5aec1982f5c23a1cb28174b42f347ea6 to sdk-release

Change-Id: I6f2a9ed9e216474f9fec544c69807640329e08ae
diff --git a/Android.bp b/Android.bp
index 2593715..034919e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -69,6 +69,7 @@
     native_bridge_supported: true,
     recovery_available: true,
     vendor_available: true,
+    product_available: true,
     apex_available: [
         // TODO(b/137948090): not fully supported in APEX for certain usecases
         // - large dependency sizes
diff --git a/adapter/Android.bp b/adapter/Android.bp
index 07faa10..3dc382e 100644
--- a/adapter/Android.bp
+++ b/adapter/Android.bp
@@ -16,6 +16,7 @@
     name: "libhidladapter",
     defaults: ["libhidl-defaults"],
     vendor_available: true,
+    product_available: true,
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
     srcs: [
diff --git a/base/include/hidl/HidlInternal.h b/base/include/hidl/HidlInternal.h
index 3cd246a..3d1a444 100644
--- a/base/include/hidl/HidlInternal.h
+++ b/base/include/hidl/HidlInternal.h
@@ -201,7 +201,10 @@
     // A list of registered instrumentation callbacks.
     std::vector<InstrumentationCallback> mInstrumentationCallbacks;
     // Flag whether to enable instrumentation.
-    bool mEnableInstrumentation;
+    union {
+        bool mEnableInstrumentation;
+        void* mReserved0;
+    };
     // Prefix to lookup the instrumentation libraries.
     std::string mInstrumentationLibPackage;
     // Used for dlsym to load the profiling method for given interface.
@@ -209,6 +212,12 @@
 
 };
 
+#ifdef __LP64__
+static_assert(sizeof(HidlInstrumentor) == 88, "HidlInstrumentor size frozen by prebuilts");
+#else
+static_assert(sizeof(HidlInstrumentor) == 44, "HidlInstrumentor size frozen by prebuilts");
+#endif
+
 }  // namespace details
 }  // namespace hardware
 }  // namespace android
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/libhidlmemory/Android.bp b/libhidlmemory/Android.bp
index d3bef74..547be11 100644
--- a/libhidlmemory/Android.bp
+++ b/libhidlmemory/Android.bp
@@ -15,6 +15,7 @@
 cc_library {
     name: "libhidlmemory",
     vendor_available: true,
+    product_available: true,
     // Host support is needed for testing only
     host_supported: true,
     // TODO(b/153609531): remove when no longer needed.
diff --git a/test_main.cpp b/test_main.cpp
index 0a1e97b..ea4dfd1 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -17,7 +17,7 @@
 #define LOG_TAG "LibHidlTest"
 
 #pragma clang diagnostic push
-#pragma clang diagnostic fatal "-Wpadded"
+#pragma clang diagnostic error "-Wpadded"
 #include <hidl/HidlInternal.h>
 #include <hidl/HidlSupport.h>
 #pragma clang diagnostic pop
diff --git a/transport/HidlLazyUtils.cpp b/transport/HidlLazyUtils.cpp
index d00b461..be7470f 100644
--- a/transport/HidlLazyUtils.cpp
+++ b/transport/HidlLazyUtils.cpp
@@ -36,6 +36,12 @@
 
     bool addRegisteredService(const sp<IBase>& service, const std::string& name);
 
+    bool tryUnregister();
+
+    void reRegister();
+
+    void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
+
   protected:
     Return<void> onClients(const sp<IBase>& service, bool clients) override;
 
@@ -44,6 +50,8 @@
         sp<IBase> service;
         std::string name;
         bool clients = false;
+        // Used to keep track of unregistered services to allow re-registry
+        bool registered = true;
     };
 
     /**
@@ -67,6 +75,16 @@
      * Number of services that have been registered.
      */
     std::vector<Service> mRegisteredServices;
+
+    /**
+     * Callback for reporting the number of services with clients.
+     */
+    std::function<bool(bool)> mActiveServicesCallback;
+
+    /**
+     * Previous value passed to the active services callback.
+     */
+    std::optional<bool> mPreviousHasClients;
 };
 
 class LazyServiceRegistrarImpl {
@@ -75,6 +93,9 @@
 
     status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
                              const std::string& name);
+    bool tryUnregister();
+    void reRegister();
+    void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
 
   private:
     sp<ClientCounterCallback> mClientCallback;
@@ -147,48 +168,79 @@
               << " available) client(s) in use after notification " << getDescriptor(service.get())
               << "/" << registered.name << " has clients: " << clients;
 
-    if (numWithClients == 0) {
+    bool handledInCallback = false;
+    if (mActiveServicesCallback != nullptr) {
+        bool hasClients = numWithClients != 0;
+        if (hasClients != mPreviousHasClients) {
+            handledInCallback = mActiveServicesCallback(hasClients);
+            mPreviousHasClients = hasClients;
+        }
+    }
+
+    // If there is no callback defined or the callback did not handle this
+    // client count change event, try to shutdown the process if its services
+    // have no clients.
+    if (!handledInCallback && numWithClients == 0) {
         tryShutdown();
     }
 
     return Status::ok();
 }
 
-void ClientCounterCallback::tryShutdown() {
-    LOG(INFO) << "Trying to exit HAL. No clients in use for any service in process.";
-
+bool ClientCounterCallback::tryUnregister() {
     auto manager = hardware::defaultServiceManager1_2();
 
-    auto unRegisterIt = mRegisteredServices.begin();
-    for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) {
-        auto& entry = (*unRegisterIt);
-
+    for (Service& entry : mRegisteredServices) {
         const std::string descriptor = getDescriptor(entry.service.get());
         bool success = manager->tryUnregister(descriptor, entry.name, entry.service);
 
         if (!success) {
             LOG(INFO) << "Failed to unregister HAL " << descriptor << "/" << entry.name;
-            break;
+            return false;
         }
+
+        // Mark the entry unregistered, but do not remove it (may still be re-registered)
+        entry.registered = false;
     }
 
-    if (unRegisterIt == mRegisteredServices.end()) {
-        LOG(INFO) << "Unregistered all clients and exiting";
-        exit(EXIT_SUCCESS);
-    }
+    return true;
+}
 
-    for (auto reRegisterIt = mRegisteredServices.begin(); reRegisterIt != unRegisterIt;
-         reRegisterIt++) {
-        auto& entry = (*reRegisterIt);
+void ClientCounterCallback::reRegister() {
+    for (Service& entry : mRegisteredServices) {
+        // re-register entry if not already registered
+        if (entry.registered) {
+            continue;
+        }
 
-        // re-register entry
         if (!registerService(entry.service, entry.name)) {
             // Must restart. Otherwise, clients will never be able to get ahold of this service.
             LOG(FATAL) << "Bad state: could not re-register " << getDescriptor(entry.service.get());
         }
+
+        entry.registered = true;
     }
 }
 
+void ClientCounterCallback::tryShutdown() {
+    LOG(INFO) << "Trying to exit HAL. No clients in use for any service in process.";
+
+    if (tryUnregister()) {
+        LOG(INFO) << "Unregistered all clients and exiting";
+        exit(EXIT_SUCCESS);
+    }
+
+    // At this point, we failed to unregister some of the services, leaving the
+    // server in an inconsistent state. Re-register all services that were
+    // unregistered by tryUnregister().
+    reRegister();
+}
+
+void ClientCounterCallback::setActiveServicesCallback(
+        const std::function<bool(bool)>& activeServicesCallback) {
+    mActiveServicesCallback = activeServicesCallback;
+}
+
 status_t LazyServiceRegistrarImpl::registerService(
     const sp<::android::hidl::base::V1_0::IBase>& service, const std::string& name) {
     if (!mClientCallback->addRegisteredService(service, name)) {
@@ -198,6 +250,19 @@
     return ::android::OK;
 }
 
+bool LazyServiceRegistrarImpl::tryUnregister() {
+    return mClientCallback->tryUnregister();
+}
+
+void LazyServiceRegistrarImpl::reRegister() {
+    mClientCallback->reRegister();
+}
+
+void LazyServiceRegistrarImpl::setActiveServicesCallback(
+        const std::function<bool(bool)>& activeServicesCallback) {
+    mClientCallback->setActiveServicesCallback(activeServicesCallback);
+}
+
 }  // namespace details
 
 LazyServiceRegistrar::LazyServiceRegistrar() {
@@ -214,5 +279,18 @@
     return mImpl->registerService(service, name);
 }
 
+bool LazyServiceRegistrar::tryUnregister() {
+    return mImpl->tryUnregister();
+}
+
+void LazyServiceRegistrar::reRegister() {
+    mImpl->reRegister();
+}
+
+void LazyServiceRegistrar::setActiveServicesCallback(
+        const std::function<bool(bool)>& activeServicesCallback) {
+    mImpl->setActiveServicesCallback(activeServicesCallback);
+}
+
 }  // namespace hardware
 }  // namespace android
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index cbe7ac6..b51c600 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -183,42 +183,8 @@
     return *getTrebleTestingOverridePtr();
 }
 
-/*
- * Returns the age of the current process by reading /proc/self/stat and comparing starttime to the
- * current time. This is useful for measuring how long it took a HAL to register itself.
- */
-__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";
-        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;
-    }
-    return -1;
-}
-
 static void onRegistrationImpl(const std::string& descriptor, const std::string& instanceName) {
-    long halStartDelay = getProcessAgeMs();
-    if (halStartDelay >= 0) {
-        // The "start delay" printed here is an estimate of how long it took the HAL to go from
-        // process creation to registering itself as a HAL.  Actual start time could be longer
-        // because the process might not have joined the threadpool yet, so it might not be ready to
-        // process transactions.
-        LOG(INFO) << "Registered " << descriptor << "/" << instanceName << " (start delay of "
-                  << halStartDelay << "ms)";
-    }
-
+    LOG(INFO) << "Registered " << descriptor << "/" << instanceName;
     tryShortenProcessName(descriptor);
 }
 
@@ -873,7 +839,13 @@
 
     if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
         using Transport = IServiceManager1_0::Transport;
-        Transport transport = sm->getTransport(descriptor, name);
+        Return<Transport> transport = sm->getTransport(descriptor, name);
+
+        if (!transport.isOk()) {
+            LOG(ERROR) << "Could not get transport for " << descriptor << "/" << name << ": "
+                       << transport.description();
+            return UNKNOWN_ERROR;
+        }
 
         if (transport != Transport::HWBINDER) {
             LOG(ERROR) << "Service " << descriptor << "/" << name
diff --git a/transport/include/hidl/HidlLazyUtils.h b/transport/include/hidl/HidlLazyUtils.h
index 97fe20e..427611b 100644
--- a/transport/include/hidl/HidlLazyUtils.h
+++ b/transport/include/hidl/HidlLazyUtils.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <functional>
+
 #include <android/hidl/base/1.0/IBase.h>
 #include <utils/RefBase.h>
 #include <utils/StrongPointer.h>
@@ -41,6 +43,38 @@
      static LazyServiceRegistrar& getInstance();
      status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
                               const std::string& name = "default");
+     /**
+      * Set a callback that is invoked when the active HAL count (i.e. HALs with clients)
+      * registered with this process drops to zero (or becomes nonzero).
+      * The callback takes a boolean argument, which is 'true' if there is
+      * at least one HAL with clients.
+      *
+      * Callback return value:
+      * - false: Default behavior for lazy HALs (shut down the process if there
+      *          are no clients).
+      * - true:  Don't shut down the process even if there are no clients.
+      *
+      * This callback gives a chance to:
+      * 1 - Perform some additional operations before exiting;
+      * 2 - Prevent the process from exiting by returning "true" from the
+      *     callback.
+      *
+      * This method should be called before 'registerService' to avoid races.
+      */
+     void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
+
+     /**
+      * Try to unregister all services previously registered with 'registerService'.
+      * Returns 'true' if successful.
+      */
+     bool tryUnregister();
+
+     /**
+      * Re-register services that were unregistered by 'tryUnregister'.
+      * This method should be called in the case 'tryUnregister' fails
+      * (and should be called on the same thread).
+      */
+     void reRegister();
 
    private:
      std::shared_ptr<details::LazyServiceRegistrarImpl> mImpl;
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>