init: always expand args in subcontext

Currently init expands properties in arguments only when those
commands are run in a subcontext.  This creates a hole where
properties that should not be accessible from a given subcontext of
init can be accessed when running a command in the main init
executable (for example `start`).

This change creates a callback in subcontext init that simply expands
and returns arguments back to the main init process, to ensure that
only those properties that a subcontext can access get expanded.

Bug: 62875318
Test: boot bullhead, new unit tests
Change-Id: I2850009e70da877c08e4cc83350c727b0ea98796
diff --git a/init/subcontext_test.cpp b/init/subcontext_test.cpp
index ca45266..230203a 100644
--- a/init/subcontext_test.cpp
+++ b/init/subcontext_test.cpp
@@ -143,6 +143,34 @@
     });
 }
 
+TEST(subcontext, ExpandArgs) {
+    RunTest([](auto& subcontext, auto& context_string) {
+        auto args = std::vector<std::string>{
+            "first",
+            "${ro.hardware}",
+            "$$third",
+        };
+        auto result = subcontext.ExpandArgs(args);
+        ASSERT_TRUE(result) << result.error();
+        ASSERT_EQ(3U, result->size());
+        EXPECT_EQ(args[0], result->at(0));
+        EXPECT_EQ(GetProperty("ro.hardware", ""), result->at(1));
+        EXPECT_EQ("$third", result->at(2));
+    });
+}
+
+TEST(subcontext, ExpandArgsFailure) {
+    RunTest([](auto& subcontext, auto& context_string) {
+        auto args = std::vector<std::string>{
+            "first",
+            "${",
+        };
+        auto result = subcontext.ExpandArgs(args);
+        ASSERT_FALSE(result);
+        EXPECT_EQ("Failed to expand '" + args[1] + "'", result.error_string());
+    });
+}
+
 TestFunctionMap BuildTestFunctionMap() {
     TestFunctionMap test_function_map;
     // For CheckDifferentPid