Merge "Add ctl.apex_(un)load properties to (un)load apex"
This commit is contained in:
commit
e271146ec8
2 changed files with 50 additions and 1 deletions
|
@ -442,6 +442,19 @@ static Result<void> DoControlRestart(Service* service) {
|
|||
return {};
|
||||
}
|
||||
|
||||
static void DoUnloadApex(const std::string& apex_name) {
|
||||
std::string prop_name = "init.apex." + apex_name;
|
||||
// TODO(b/232114573) remove services and actions read from the apex
|
||||
// TODO(b/232799709) kill services from the apex
|
||||
SetProperty(prop_name, "unloaded");
|
||||
}
|
||||
|
||||
static void DoLoadApex(const std::string& apex_name) {
|
||||
std::string prop_name = "init.apex." + apex_name;
|
||||
// TODO(b/232799709) read .rc files from the apex
|
||||
SetProperty(prop_name, "loaded");
|
||||
}
|
||||
|
||||
enum class ControlTarget {
|
||||
SERVICE, // function gets called for the named service
|
||||
INTERFACE, // action gets called for every service that holds this interface
|
||||
|
@ -465,6 +478,20 @@ static const std::map<std::string, ControlMessageFunction, std::less<>>& GetCont
|
|||
return control_message_functions;
|
||||
}
|
||||
|
||||
static bool HandleApexControlMessage(std::string_view action, const std::string& name,
|
||||
std::string_view message) {
|
||||
if (action == "load") {
|
||||
DoLoadApex(name);
|
||||
return true;
|
||||
} else if (action == "unload") {
|
||||
DoUnloadApex(name);
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "Unknown control msg '" << message << "'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool HandleControlMessage(std::string_view message, const std::string& name,
|
||||
pid_t from_pid) {
|
||||
std::string cmdline_path = StringPrintf("proc/%d/cmdline", from_pid);
|
||||
|
@ -476,8 +503,12 @@ static bool HandleControlMessage(std::string_view message, const std::string& na
|
|||
process_cmdline = "unknown process";
|
||||
}
|
||||
|
||||
Service* service = nullptr;
|
||||
auto action = message;
|
||||
if (ConsumePrefix(&action, "apex_")) {
|
||||
return HandleApexControlMessage(action, name, message);
|
||||
}
|
||||
|
||||
Service* service = nullptr;
|
||||
if (ConsumePrefix(&action, "interface_")) {
|
||||
service = ServiceList::GetInstance().FindInterface(name);
|
||||
} else {
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
#include "util.h"
|
||||
|
||||
using android::base::GetIntProperty;
|
||||
using android::base::GetProperty;
|
||||
using android::base::SetProperty;
|
||||
using android::base::WaitForProperty;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
@ -334,6 +338,20 @@ TEST(init, LazilyLoadedActionsCanBeTriggeredByTheNextTrigger) {
|
|||
EXPECT_EQ(2, num_executed);
|
||||
}
|
||||
|
||||
TEST(init, RespondToCtlApexMessages) {
|
||||
if (getuid() != 0) {
|
||||
GTEST_SKIP() << "Skipping test, must be run as root.";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string apex_name = "com.android.apex.cts.shim";
|
||||
SetProperty("ctl.apex_unload", apex_name);
|
||||
EXPECT_TRUE(WaitForProperty("init.apex." + apex_name, "unloaded", 10s));
|
||||
|
||||
SetProperty("ctl.apex_load", apex_name);
|
||||
EXPECT_TRUE(WaitForProperty("init.apex." + apex_name, "loaded", 10s));
|
||||
}
|
||||
|
||||
TEST(init, RejectsCriticalAndOneshotService) {
|
||||
if (GetIntProperty("ro.product.first_api_level", 10000) < 30) {
|
||||
GTEST_SKIP() << "Test only valid for devices launching with R or later";
|
||||
|
|
Loading…
Reference in a new issue