Merge "init: Allow restricted use of binder."
diff --git a/init/Android.bp b/init/Android.bp
index a2c49d0..c793971 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -68,6 +68,7 @@
     ],
     shared_libs: [
         "libbase",
+        "libbinder",
         "libbootloader_message",
         "libcutils",
         "libdl",
@@ -78,6 +79,7 @@
         "liblog",
         "liblogwrap",
         "libselinux",
+        "libutils",
     ],
 }
 
@@ -127,6 +129,13 @@
         type: "lite",
         export_proto_headers: true,
     },
+
+    target: {
+        recovery: {
+            cflags: ["-DRECOVERY"],
+            exclude_shared_libs: ["libbinder", "libutils"],
+        },
+    },
 }
 
 cc_binary {
@@ -143,6 +152,12 @@
     ],
     srcs: ["main.cpp"],
     symlinks: ["ueventd"],
+    target: {
+        recovery: {
+            cflags: ["-DRECOVERY"],
+            exclude_shared_libs: ["libbinder", "libutils"],
+        },
+    },
 }
 
 // Tests
diff --git a/init/init.cpp b/init/init.cpp
index 16564f4..3ab0a52 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -41,6 +41,10 @@
 #include <keyutils.h>
 #include <libavb/libavb.h>
 
+#ifndef RECOVERY
+#include <binder/ProcessState.h>
+#endif
+
 #include "action_parser.h"
 #include "epoll.h"
 #include "first_stage_mount.h"
@@ -413,6 +417,22 @@
     return Success();
 }
 
+static Result<Success> InitBinder(const BuiltinArguments& args) {
+    // init's use of binder is very limited. init cannot:
+    //   - have any binder threads
+    //   - receive incoming binder calls
+    //   - pass local binder services to remote processes
+    //   - use death recipients
+    // The main supported usecases are:
+    //   - notifying other daemons (oneway calls only)
+    //   - retrieving data that is necessary to boot
+    // Also, binder can't be used by recovery.
+#ifndef RECOVERY
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
+#endif
+    return Success();
+}
+
 // Set the UDC controller for the ConfigFS USB Gadgets.
 // Read the UDC controller in use from "/sys/class/udc".
 // In case of multiple UDC controllers select the first one.
@@ -673,6 +693,9 @@
     // wasn't ready immediately after wait_for_coldboot_done
     am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
 
+    // Initialize binder before bringing up other system services
+    am.QueueBuiltinAction(InitBinder, "InitBinder");
+
     // Don't mount filesystems or start core system services in charger mode.
     std::string bootmode = GetProperty("ro.bootmode", "");
     if (bootmode == "charger") {