Reland^2: "init: run property service in a thread"

It's been a long standing issue that init cannot respond to property
set messages when it is running a builtin command.  This is
particularly problematic when the commands involve IPC to vold or
other daemons, as it prevents them from being able to set properties.

This change has init run property service in a thread, which
eliminates the above issue.

This change may also serve as a starting block to running property
service in an entirely different process to better isolate init from
handling property requests.

Reland: during reboot, init stops processing property_changed messages
from property service, since it will not act on these anyway.  This
had an unexpected effect of causing future property_set calls to block
indefinitely, since the buffer between init and property_service was
filling up and the send() call from property_service would then
block.  This change has init tell property_service to stop sending it
property_changed messages once reboot begins.

Test: CF boots, walleye boots, properties are set appropriately
Change-Id: I26902708e8be788caa6dbcf4b6d2968d90962785
diff --git a/init/builtins.cpp b/init/builtins.cpp
index d2c73cb..21db8dc 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -80,6 +80,7 @@
 using namespace std::literals::string_literals;
 
 using android::base::Basename;
+using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::unique_fd;
 using android::fs_mgr::Fstab;
@@ -701,6 +702,15 @@
 }
 
 static Result<void> do_setprop(const BuiltinArguments& args) {
+    if (StartsWith(args[1], "ctl.")) {
+        return Error()
+               << "Cannot set ctl. properties from init; call the Service functions directly";
+    }
+    if (args[1] == kRestoreconProperty) {
+        return Error() << "Cannot set '" << kRestoreconProperty
+                       << "' from init; use the restorecon builtin directly";
+    }
+
     property_set(args[1], args[2]);
     return {};
 }
@@ -1016,7 +1026,20 @@
 }
 
 static Result<void> do_load_persist_props(const BuiltinArguments& args) {
-    load_persist_props();
+    // Devices with FDE have load_persist_props called twice; the first time when the temporary
+    // /data partition is mounted and then again once /data is truly mounted.  We do not want to
+    // read persistent properties from the temporary /data partition or mark persistent properties
+    // as having been loaded during the first call, so we return in that case.
+    std::string crypto_state = android::base::GetProperty("ro.crypto.state", "");
+    std::string crypto_type = android::base::GetProperty("ro.crypto.type", "");
+    if (crypto_state == "encrypted" && crypto_type == "block") {
+        static size_t num_calls = 0;
+        if (++num_calls == 1) return {};
+    }
+
+    SendLoadPersistentPropertiesMessage();
+
+    start_waiting_for_property("ro.persistent_properties.ready", "true");
     return {};
 }