Home | History | Annotate | Download | only in default_transport
      1 #ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
      2 #define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
      3 
      4 #include <ftw.h>
      5 
      6 #include <pdx/client.h>
      7 #include <pdx/default_transport/client_channel_factory.h>
      8 #include <pdx/service.h>
      9 #include <pdx/status.h>
     10 
     11 namespace android {
     12 namespace pdx {
     13 namespace default_transport {
     14 
     15 class ServiceUtility : public ClientBase<ServiceUtility> {
     16  public:
     17   Status<int> ReloadSystemProperties() {
     18     Transaction transaction{*this};
     19     return ReturnStatusOrError(
     20         transaction.Send<int>(opcodes::REPORT_SYSPROP_CHANGE));
     21   }
     22 
     23   static std::string GetRootEndpointPath() {
     24     return ClientChannelFactory::GetRootEndpointPath();
     25   }
     26   static std::string GetEndpointPath(const std::string& endpoint_path) {
     27     return ClientChannelFactory::GetEndpointPath(endpoint_path);
     28   }
     29 
     30   // Traverses the PDX service path space and sends a message to reload system
     31   // properties to each service endpoint it finds along the way.
     32   // NOTE: This method is used by atrace to poke PDX services. Please avoid
     33   // unnecessary changes to this mechanism to minimize impact on atrace.
     34   static bool PokeServices() {
     35     const int kMaxDepth = 16;
     36     const int result =
     37         nftw(GetRootEndpointPath().c_str(), PokeService, kMaxDepth, FTW_PHYS);
     38     return result == 0 ? true : false;
     39   }
     40 
     41  private:
     42   friend BASE;
     43 
     44   ServiceUtility(const std::string& endpoint_path, int* error = nullptr)
     45       : BASE(ClientChannelFactory::Create(endpoint_path), 0) {
     46     if (error)
     47       *error = Client::error();
     48   }
     49 
     50   // Sends the sysprop_change message to the service at fpath, so it re-reads
     51   // its system properties. Returns 0 on success or a negated errno code on
     52   // failure.
     53   // NOTE: This method is used by atrace to poke PDX services. Please avoid
     54   // unnecessary changes to this mechanism to minimize impact on atrace.
     55   static int PokeService(const char* fpath, const struct stat* /*sb*/,
     56                          int typeflag, struct FTW* /*ftwbuf*/) {
     57     const bool kIgnoreErrors = true;
     58 
     59     if (typeflag == FTW_F) {
     60       int error;
     61       auto utility = ServiceUtility::Create(fpath, &error);
     62       if (!utility) {
     63         if (error != -ECONNREFUSED) {
     64           ALOGE("ServiceUtility::PokeService: Failed to open %s: %s.", fpath,
     65                 strerror(-error));
     66         }
     67         return kIgnoreErrors ? 0 : error;
     68       }
     69 
     70       auto status = utility->ReloadSystemProperties();
     71       if (!status) {
     72         ALOGE(
     73             "ServiceUtility::PokeService: Failed to send sysprop change to %s: "
     74             "%s",
     75             fpath, status.GetErrorMessage().c_str());
     76         return kIgnoreErrors ? 0 : -status.error();
     77       }
     78     }
     79 
     80     return 0;
     81   }
     82 
     83   ServiceUtility(const ServiceUtility&) = delete;
     84   void operator=(const ServiceUtility&) = delete;
     85 };
     86 
     87 }  // namespace default_transport
     88 }  // namespace pdx
     89 }  // namespace android
     90 
     91 #endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
     92