summaryrefslogtreecommitdiffstats
path: root/init/action_parser.cpp
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2018-02-13 16:24:51 -0800
committerTom Cherry <tomcherry@google.com>2018-02-14 16:37:17 -0800
commit9cbf57048cf0057f499bf1911e4ac3eba795becb (patch)
treed35ece56762c71f178792237b1441f0592042233 /init/action_parser.cpp
parent7fd3bc27eccdcb11de4886bdda05cd26a8d8af5c (diff)
downloadsystem_core-9cbf57048cf0057f499bf1911e4ac3eba795becb.tar.gz
system_core-9cbf57048cf0057f499bf1911e4ac3eba795becb.tar.bz2
system_core-9cbf57048cf0057f499bf1911e4ac3eba795becb.zip
Move all Action parsing into ActionParser
Bug: 36970783 Test: Build Change-Id: Iea2d97fb45c3e88bc83fb72d6fa67049be42cfa9
Diffstat (limited to 'init/action_parser.cpp')
-rw-r--r--init/action_parser.cpp93
1 files changed, 90 insertions, 3 deletions
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index fd085b82d..8a4b518f5 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -16,13 +16,95 @@
#include "action_parser.h"
+#include <android-base/properties.h>
#include <android-base/strings.h>
+#include "stable_properties.h"
+
+using android::base::GetBoolProperty;
using android::base::StartsWith;
namespace android {
namespace init {
+namespace {
+
+bool IsActionableProperty(Subcontext* subcontext, const std::string& prop_name) {
+ static bool enabled = GetBoolProperty("ro.actionable_compatible_property.enabled", false);
+
+ if (subcontext == nullptr || !enabled) {
+ return true;
+ }
+
+ if (kExportedActionableProperties.count(prop_name) == 1) {
+ return true;
+ }
+ for (const auto& prefix : kPartnerPrefixes) {
+ if (android::base::StartsWith(prop_name, prefix)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+Result<Success> ParsePropertyTrigger(const std::string& trigger, Subcontext* subcontext,
+ std::map<std::string, std::string>* property_triggers) {
+ const static std::string prop_str("property:");
+ std::string prop_name(trigger.substr(prop_str.length()));
+ size_t equal_pos = prop_name.find('=');
+ if (equal_pos == std::string::npos) {
+ return Error() << "property trigger found without matching '='";
+ }
+
+ std::string prop_value(prop_name.substr(equal_pos + 1));
+ prop_name.erase(equal_pos);
+
+ if (!IsActionableProperty(subcontext, prop_name)) {
+ return Error() << "unexported property tigger found: " << prop_name;
+ }
+
+ if (auto [it, inserted] = property_triggers->emplace(prop_name, prop_value); !inserted) {
+ return Error() << "multiple property triggers found for same property";
+ }
+ return Success();
+}
+
+Result<Success> ParseTriggers(const std::vector<std::string>& args, Subcontext* subcontext,
+ std::string* event_trigger,
+ std::map<std::string, std::string>* property_triggers) {
+ const static std::string prop_str("property:");
+ for (std::size_t i = 0; i < args.size(); ++i) {
+ if (args[i].empty()) {
+ return Error() << "empty trigger is not valid";
+ }
+
+ if (i % 2) {
+ if (args[i] != "&&") {
+ return Error() << "&& is the only symbol allowed to concatenate actions";
+ } else {
+ continue;
+ }
+ }
+
+ if (!args[i].compare(0, prop_str.length(), prop_str)) {
+ if (auto result = ParsePropertyTrigger(args[i], subcontext, property_triggers);
+ !result) {
+ return result;
+ }
+ } else {
+ if (!event_trigger->empty()) {
+ return Error() << "multiple event triggers are not allowed";
+ }
+
+ *event_trigger = args[i];
+ }
+ }
+
+ return Success();
+}
+
+} // namespace
+
Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
std::vector<std::string> triggers(args.begin() + 1, args.end());
@@ -40,12 +122,17 @@ Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args,
}
}
- auto action = std::make_unique<Action>(false, action_subcontext, filename, line);
+ std::string event_trigger;
+ std::map<std::string, std::string> property_triggers;
- if (auto result = action->InitTriggers(triggers); !result) {
- return Error() << "InitTriggers() failed: " << result.error();
+ if (auto result = ParseTriggers(triggers, action_subcontext, &event_trigger, &property_triggers);
+ !result) {
+ return Error() << "ParseTriggers() failed: " << result.error();
}
+ auto action = std::make_unique<Action>(false, action_subcontext, filename, line, event_trigger,
+ property_triggers);
+
action_ = std::move(action);
return Success();
}