1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 416f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka#include <ftw.h> 516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/client_channel_factory.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/status.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace default_transport { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ServiceUtility : public ClientBase<ServiceUtility> { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> ReloadSystemProperties() { 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction transaction{*this}; 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError( 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko transaction.Send<int>(opcodes::REPORT_SYSPROP_CHANGE)); 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::string GetRootEndpointPath() { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ClientChannelFactory::GetRootEndpointPath(); 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::string GetEndpointPath(const std::string& endpoint_path) { 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ClientChannelFactory::GetEndpointPath(endpoint_path); 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // Traverses the PDX service path space and sends a message to reload system 3116f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // properties to each service endpoint it finds along the way. 3216f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // NOTE: This method is used by atrace to poke PDX services. Please avoid 3316f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // unnecessary changes to this mechanism to minimize impact on atrace. 3416f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka static bool PokeServices() { 3516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka const int kMaxDepth = 16; 3616f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka const int result = 3716f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka nftw(GetRootEndpointPath().c_str(), PokeService, kMaxDepth, FTW_PHYS); 3816f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka return result == 0 ? true : false; 3916f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 4016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ServiceUtility(const std::string& endpoint_path, int* error = nullptr) 4516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka : BASE(ClientChannelFactory::Create(endpoint_path), 0) { 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (error) 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *error = Client::error(); 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // Sends the sysprop_change message to the service at fpath, so it re-reads 5116f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // its system properties. Returns 0 on success or a negated errno code on 5216f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // failure. 5316f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // NOTE: This method is used by atrace to poke PDX services. Please avoid 5416f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka // unnecessary changes to this mechanism to minimize impact on atrace. 5516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka static int PokeService(const char* fpath, const struct stat* /*sb*/, 5616f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka int typeflag, struct FTW* /*ftwbuf*/) { 5716f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka const bool kIgnoreErrors = true; 5816f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 5916f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka if (typeflag == FTW_F) { 6016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka int error; 6116f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka auto utility = ServiceUtility::Create(fpath, &error); 6216f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka if (!utility) { 6316f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka if (error != -ECONNREFUSED) { 6416f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka ALOGE("ServiceUtility::PokeService: Failed to open %s: %s.", fpath, 6516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka strerror(-error)); 6616f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 6716f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka return kIgnoreErrors ? 0 : error; 6816f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 6916f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 7016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka auto status = utility->ReloadSystemProperties(); 7116f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka if (!status) { 7216f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka ALOGE( 7316f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka "ServiceUtility::PokeService: Failed to send sysprop change to %s: " 7416f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka "%s", 7516f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka fpath, status.GetErrorMessage().c_str()); 7616f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka return kIgnoreErrors ? 0 : -status.error(); 7716f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 7816f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 7916f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 8016f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka return 0; 8116f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka } 8216f1c1a30abafb346f4b03643d0fcbf799fdc308Corey Tabaka 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ServiceUtility(const ServiceUtility&) = delete; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const ServiceUtility&) = delete; 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace default_transport 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_ 92