Merge "Added fastboot_fuzzer"
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 84ed58e..83042ad 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -100,6 +100,7 @@
 constexpr auto LEGACY_ID_PROP = "ro.build.legacy.id";
 constexpr auto VBMETA_DIGEST_PROP = "ro.boot.vbmeta.digest";
 constexpr auto DIGEST_SIZE_USED = 8;
+constexpr auto API_LEVEL_CURRENT = 10000;
 
 static bool persistent_properties_loaded = false;
 
@@ -1017,29 +1018,37 @@
     }
 }
 
+static int read_api_level_props(const std::vector<std::string>& api_level_props) {
+    int api_level = API_LEVEL_CURRENT;
+    for (const auto& api_level_prop : api_level_props) {
+        api_level = android::base::GetIntProperty(api_level_prop, API_LEVEL_CURRENT);
+        if (api_level != API_LEVEL_CURRENT) {
+            break;
+        }
+    }
+    return api_level;
+}
+
 static void property_initialize_ro_vendor_api_level() {
     // ro.vendor.api_level shows the api_level that the vendor images (vendor, odm, ...) are
     // required to support.
     constexpr auto VENDOR_API_LEVEL_PROP = "ro.vendor.api_level";
-    // Candidate api levels. The order of the properties must be kept.
-    const char* VENDOR_API_LEVEL_PROPS[] = {
-            "ro.board.api_level", "ro.board.first_api_level",    "ro.product.first_api_level",
-            "ro.vndk.version",    "ro.vendor.build.version.sdk", "ro.build.version.sdk"};
 
-    for (const auto& api_level_prop : VENDOR_API_LEVEL_PROPS) {
-        int api_level = android::base::GetIntProperty(api_level_prop, 0);
-        if (api_level != 0) {
-            std::string error;
-            uint32_t res = PropertySet(VENDOR_API_LEVEL_PROP, std::to_string(api_level), &error);
-            if (res != PROP_SUCCESS) {
-                LOG(ERROR) << "Failed to set " << VENDOR_API_LEVEL_PROP << " with " << api_level
-                           << ": " << error;
-            }
-            return;
-        }
+    // Api level properties of the board. The order of the properties must be kept.
+    std::vector<std::string> BOARD_API_LEVEL_PROPS = {
+            "ro.board.api_level", "ro.board.first_api_level", "ro.vendor.build.version.sdk"};
+    // Api level properties of the device. The order of the properties must be kept.
+    std::vector<std::string> DEVICE_API_LEVEL_PROPS = {"ro.product.first_api_level",
+                                                       "ro.build.version.sdk"};
+
+    int api_level = std::min(read_api_level_props(BOARD_API_LEVEL_PROPS),
+                             read_api_level_props(DEVICE_API_LEVEL_PROPS));
+    std::string error;
+    uint32_t res = PropertySet(VENDOR_API_LEVEL_PROP, std::to_string(api_level), &error);
+    if (res != PROP_SUCCESS) {
+        LOG(ERROR) << "Failed to set " << VENDOR_API_LEVEL_PROP << " with " << api_level << ": "
+                   << error << "(" << res << ")";
     }
-    // If no api integers are found from the vendor api level properties, ro.vendor.api_level
-    // will not be set.
 }
 
 void PropertyLoadBootDefaults() {
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index c471fa0..e65fe92 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -130,6 +130,7 @@
 #define AID_VIRTUALIZATIONSERVICE 1081 /* VirtualizationService daemon */
 #define AID_ARTD 1082             /* ART Service daemon */
 #define AID_UWB 1083              /* UWB subsystem */
+#define AID_THREAD_NETWORK 1084   /* Thread Network subsystem */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 7bd1d10..99d9e56 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -117,6 +117,7 @@
         "libkeymint",
         "liblog",
         "libtrusty",
+        "libutils",
     ],
     required: [
         "android.hardware.hardware_keystore.xml",
@@ -142,6 +143,7 @@
         "libtrusty",
         "libhardware",
         "libkeymaster_messages",
+        "libutils",
         "libxml2",
     ],
     export_include_dirs: ["include"],
@@ -169,6 +171,7 @@
         "libtrusty",
         "libhardware",
         "libkeymaster_messages",
+        "libutils",
         "libxml2",
     ],
     cflags: [
diff --git a/trusty/keymaster/ipc/trusty_keymaster_ipc.cpp b/trusty/keymaster/ipc/trusty_keymaster_ipc.cpp
index 2d44009..db1a9f4 100644
--- a/trusty/keymaster/ipc/trusty_keymaster_ipc.cpp
+++ b/trusty/keymaster/ipc/trusty_keymaster_ipc.cpp
@@ -19,6 +19,7 @@
 // TODO: make this generic in libtrusty
 
 #include <errno.h>
+#include <poll.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/uio.h>
@@ -33,11 +34,15 @@
 
 #include <trusty_keymaster/ipc/keymaster_ipc.h>
 #include <trusty_keymaster/ipc/trusty_keymaster_ipc.h>
+#include <utils/Timers.h>
 
 #define TRUSTY_DEVICE_NAME "/dev/trusty-ipc-dev0"
 
 static int handle_ = -1;
 
+static const int timeout_ms = 10 * 1000;
+static const int max_timeout_ms = 60 * 1000;
+
 int trusty_keymaster_connect() {
     int rc = tipc_connect(TRUSTY_DEVICE_NAME, KEYMASTER_PORT);
     if (rc < 0) {
@@ -84,7 +89,38 @@
     msg->cmd = cmd;
     memcpy(msg->payload, in, in_size);
 
+    nsecs_t start_time_ns = systemTime(SYSTEM_TIME_MONOTONIC);
+    bool timed_out = false;
+    int poll_timeout_ms = timeout_ms;
+    while (true) {
+        struct pollfd pfd;
+        pfd.fd = handle_;
+        pfd.events = POLLOUT;
+        pfd.revents = 0;
+
+        int p = poll(&pfd, 1, poll_timeout_ms);
+        if (p == 0) {
+            ALOGW("write for cmd %d is taking more than %lld nsecs", cmd,
+                  (long long)(systemTime(SYSTEM_TIME_MONOTONIC) - start_time_ns));
+            timed_out = true;
+            poll_timeout_ms *= 2;
+            if (poll_timeout_ms > max_timeout_ms) {
+                poll_timeout_ms = max_timeout_ms;
+            }
+            continue;
+        } else if (p < 0) {
+            ALOGE("write poll error: %d", errno);
+        } else if (pfd.revents != POLLOUT) {
+            ALOGW("unexpected poll() result: %d", pfd.revents);
+        }
+        break;
+    }
+
     ssize_t rc = write(handle_, msg, msg_size);
+    if (timed_out) {
+        ALOGW("write for cmd %d finished after %lld nsecs", cmd,
+              (long long)(systemTime(SYSTEM_TIME_MONOTONIC) - start_time_ns));
+    }
     free(msg);
 
     if (rc < 0) {
@@ -122,8 +158,37 @@
             return -EOVERFLOW;
         }
         iov[1] = {.iov_base = write_pos, .iov_len = buffer_size};
+        start_time_ns = systemTime(SYSTEM_TIME_MONOTONIC);
+        timed_out = false;
+        poll_timeout_ms = timeout_ms;
+        while (true) {
+            struct pollfd pfd;
+            pfd.fd = handle_;
+            pfd.events = POLLIN;
+            pfd.revents = 0;
 
+            int p = poll(&pfd, 1, poll_timeout_ms);
+            if (p == 0) {
+                ALOGW("readv for cmd %d is taking more than %lld nsecs", cmd,
+                      (long long)(systemTime(SYSTEM_TIME_MONOTONIC) - start_time_ns));
+                timed_out = true;
+                poll_timeout_ms *= 2;
+                if (poll_timeout_ms > max_timeout_ms) {
+                    poll_timeout_ms = max_timeout_ms;
+                }
+                continue;
+            } else if (p < 0) {
+                ALOGE("read poll error: %d", errno);
+            } else if (pfd.revents != POLLIN) {
+                ALOGW("unexpected poll() result: %d", pfd.revents);
+            }
+            break;
+        }
         rc = readv(handle_, iov, 2);
+        if (timed_out) {
+            ALOGW("readv for cmd %d finished after %lld nsecs", cmd,
+                  (long long)(systemTime(SYSTEM_TIME_MONOTONIC) - start_time_ns));
+        }
         if (rc < 0) {
             ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT,
                   strerror(errno));