diff options
author | Tom Cherry <tomcherry@google.com> | 2018-02-13 16:24:51 -0800 |
---|---|---|
committer | Tom Cherry <tomcherry@google.com> | 2018-02-14 16:37:17 -0800 |
commit | 9cbf57048cf0057f499bf1911e4ac3eba795becb (patch) | |
tree | d35ece56762c71f178792237b1441f0592042233 /init/action_parser.cpp | |
parent | 7fd3bc27eccdcb11de4886bdda05cd26a8d8af5c (diff) | |
download | system_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.cpp | 93 |
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(); } |