blob: 3ebab86138270d1fecb1453ebfff90bd1c3b9d8c [file] [log] [blame]
#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
#include <ftw.h>
#include <pdx/client.h>
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/service.h>
#include <pdx/status.h>
namespace android {
namespace pdx {
namespace default_transport {
class ServiceUtility : public ClientBase<ServiceUtility> {
public:
Status<int> ReloadSystemProperties() {
Transaction transaction{*this};
return ReturnStatusOrError(
transaction.Send<int>(opcodes::REPORT_SYSPROP_CHANGE));
}
static std::string GetRootEndpointPath() {
return ClientChannelFactory::GetRootEndpointPath();
}
static std::string GetEndpointPath(const std::string& endpoint_path) {
return ClientChannelFactory::GetEndpointPath(endpoint_path);
}
// Traverses the PDX service path space and sends a message to reload system
// properties to each service endpoint it finds along the way.
// NOTE: This method is used by atrace to poke PDX services. Please avoid
// unnecessary changes to this mechanism to minimize impact on atrace.
static bool PokeServices() {
const int kMaxDepth = 16;
const int result =
nftw(GetRootEndpointPath().c_str(), PokeService, kMaxDepth, FTW_PHYS);
return result == 0 ? true : false;
}
private:
friend BASE;
explicit ServiceUtility(const std::string& endpoint_path,
int* error = nullptr)
: BASE(ClientChannelFactory::Create(endpoint_path), 0) {
if (error)
*error = Client::error();
}
// Sends the sysprop_change message to the service at fpath, so it re-reads
// its system properties. Returns 0 on success or a negated errno code on
// failure.
// NOTE: This method is used by atrace to poke PDX services. Please avoid
// unnecessary changes to this mechanism to minimize impact on atrace.
static int PokeService(const char* fpath, const struct stat* /*sb*/,
int typeflag, struct FTW* /*ftwbuf*/) {
const bool kIgnoreErrors = true;
if (typeflag == FTW_F) {
int error;
auto utility = ServiceUtility::Create(fpath, &error);
if (!utility) {
if (error != -ECONNREFUSED) {
ALOGE("ServiceUtility::PokeService: Failed to open %s: %s.", fpath,
strerror(-error));
}
return kIgnoreErrors ? 0 : error;
}
auto status = utility->ReloadSystemProperties();
if (!status) {
ALOGE(
"ServiceUtility::PokeService: Failed to send sysprop change to %s: "
"%s",
fpath, status.GetErrorMessage().c_str());
return kIgnoreErrors ? 0 : -status.error();
}
}
return 0;
}
ServiceUtility(const ServiceUtility&) = delete;
void operator=(const ServiceUtility&) = delete;
};
} // namespace default_transport
} // namespace pdx
} // namespace android
#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_