Home | History | Annotate | Download | only in hal
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #define LOG_TAG "VtsAgentRequestHandler"
     17 
     18 #include "AgentRequestHandler.h"
     19 
     20 #include <dirent.h>
     21 #include <errno.h>
     22 #include <sys/stat.h>
     23 #include <string>
     24 
     25 #include <android-base/logging.h>
     26 
     27 #include "BinderClientToDriver.h"
     28 #include "SocketClientToDriver.h"
     29 #include "SocketServerForDriver.h"
     30 #include "test/vts/proto/AndroidSystemControlMessage.pb.h"
     31 #include "test/vts/proto/VtsDriverControlMessage.pb.h"
     32 
     33 using namespace std;
     34 using namespace google::protobuf;
     35 
     36 namespace android {
     37 namespace vts {
     38 
     39 bool AgentRequestHandler::ListHals(const RepeatedPtrField<string>& base_paths) {
     40   AndroidSystemControlResponseMessage response_msg;
     41   ResponseCode result = FAIL;
     42 
     43   for (const string& path : base_paths) {
     44     LOG(DEBUG) << "open a dir " << path;
     45     DIR* dp;
     46     if (!(dp = opendir(path.c_str()))) {
     47       LOG(ERROR) << "Error(" << errno << ") opening " << path;
     48       continue;
     49     }
     50 
     51     struct dirent* dirp;
     52     int len;
     53     while ((dirp = readdir(dp)) != NULL) {
     54       len = strlen(dirp->d_name);
     55       if (len > 3 && !strcmp(&dirp->d_name[len - 3], ".so")) {
     56         string found_path = path + "/" + string(dirp->d_name);
     57         LOG(INFO) << "found " << found_path;
     58         response_msg.add_file_names(found_path);
     59         result = SUCCESS;
     60       }
     61     }
     62     closedir(dp);
     63   }
     64   response_msg.set_response_code(result);
     65   return VtsSocketSendMessage(response_msg);
     66 }
     67 
     68 bool AgentRequestHandler::SetHostInfo(const int callback_port) {
     69   callback_port_ = callback_port;
     70   AndroidSystemControlResponseMessage response_msg;
     71   response_msg.set_response_code(SUCCESS);
     72   return VtsSocketSendMessage(response_msg);
     73 }
     74 
     75 bool AgentRequestHandler::CheckDriverService(const string& service_name,
     76                                              bool* live) {
     77   AndroidSystemControlResponseMessage response_msg;
     78 
     79 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
     80   if (IsDriverRunning(service_name, 10)) {
     81 #else  // binder
     82   sp<IVtsFuzzer> binder = GetBinderClient(service_name);
     83   if (binder.get()) {
     84 #endif
     85     if (live) *live = true;
     86     response_msg.set_response_code(SUCCESS);
     87     response_msg.set_reason("found the service");
     88     LOG(DEBUG) << "set service_name " << service_name;
     89     service_name_ = service_name;
     90   } else {
     91     if (live) *live = false;
     92     response_msg.set_response_code(FAIL);
     93     response_msg.set_reason("service not found");
     94   }
     95   return VtsSocketSendMessage(response_msg);
     96 }
     97 
     98 static const char kUnixSocketNamePrefixForCallbackServer[] =
     99     "/data/local/tmp/vts_agent_callback";
    100 
    101 bool AgentRequestHandler::LaunchDriverService(
    102     const AndroidSystemControlCommandMessage& command_msg) {
    103   int driver_type = command_msg.driver_type();
    104   const string& service_name = command_msg.service_name();
    105   const string& file_path = command_msg.file_path();
    106   int target_class = command_msg.target_class();
    107   int target_type = command_msg.target_type();
    108   float target_version = command_msg.target_version() / 100.0;
    109   const string& target_package = command_msg.target_package();
    110   const string& target_component_name = command_msg.target_component_name();
    111   const string& module_name = command_msg.module_name();
    112   const string& hw_binder_service_name = command_msg.hw_binder_service_name();
    113   int bits = command_msg.bits();
    114 
    115   LOG(DEBUG) << "file_path=" << file_path;
    116   ResponseCode result = FAIL;
    117 
    118   // TODO: shall check whether there's a service with the same name and return
    119   // success immediately if exists.
    120   AndroidSystemControlResponseMessage response_msg;
    121 
    122   // deletes the service file if exists before starting to launch a driver.
    123   string socket_port_flie_path = GetSocketPortFilePath(service_name);
    124   struct stat file_stat;
    125   if (stat(socket_port_flie_path.c_str(), &file_stat) == 0  // file exists
    126       && remove(socket_port_flie_path.c_str()) == -1) {
    127     LOG(ERROR) << socket_port_flie_path << " delete error";
    128     response_msg.set_reason("service file already exists.");
    129   } else {
    130     pid_t pid = fork();
    131     if (pid == 0) {  // child
    132       Close();
    133 
    134       string driver_binary_path;
    135       char* cmd = NULL;
    136       if (driver_type == VTS_DRIVER_TYPE_HAL_CONVENTIONAL ||
    137           driver_type == VTS_DRIVER_TYPE_HAL_LEGACY ||
    138           driver_type == VTS_DRIVER_TYPE_HAL_HIDL) {
    139         // TODO: check whether the port is available and handle if fails.
    140         static int port = 0;
    141         string callback_socket_name(kUnixSocketNamePrefixForCallbackServer);
    142         callback_socket_name += to_string(port++);
    143         LOG(INFO) << "callback_socket_name: " << callback_socket_name;
    144         StartSocketServerForDriver(callback_socket_name, -1);
    145 
    146         if (bits == 32) {
    147           driver_binary_path = driver_hal_binary32_;
    148         } else {
    149           driver_binary_path = driver_hal_binary64_;
    150         }
    151         size_t offset = driver_binary_path.find_last_of("/");
    152         string ld_dir_path = driver_binary_path.substr(0, offset);
    153 
    154         if (driver_hal_spec_dir_path_.length() < 1) {
    155 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    156           asprintf(&cmd,
    157                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
    158                    "--server_socket_path=%s "
    159                    "--callback_socket_name=%s",
    160                    ld_dir_path.c_str(), driver_binary_path.c_str(),
    161                    socket_port_flie_path.c_str(), callback_socket_name.c_str());
    162 #else  // binder
    163           asprintf(&cmd,
    164                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
    165                    "--service_name=%s "
    166                    "--callback_socket_name=%s",
    167                    ld_dir_path.c_str(), driver_binary_path.c_str(),
    168                    service_name.c_str(), callback_socket_name.c_str());
    169 #endif
    170         } else {
    171 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    172           asprintf(&cmd,
    173                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
    174                    "--server_socket_path=%s "
    175                    "--spec_dir_path=%s --callback_socket_name=%s",
    176                    ld_dir_path.c_str(), driver_binary_path.c_str(),
    177                    socket_port_flie_path.c_str(),
    178                    driver_hal_spec_dir_path_.c_str(),
    179                    callback_socket_name.c_str());
    180 #else  // binder
    181           asprintf(&cmd,
    182                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
    183                    "--service_name=%s "
    184                    "--spec_dir_path=%s --callback_socket_name=%s",
    185                    ld_dir_path.c_str(), driver_binary_path.c_str(),
    186                    service_name.c_str(), driver_hal_spec_dir_path_.c_str(),
    187                    callback_socket_name.c_str());
    188 #endif
    189         }
    190       } else if (driver_type == VTS_DRIVER_TYPE_SHELL) {
    191         if (bits == 32) {
    192           driver_binary_path = driver_shell_binary32_;
    193         } else {
    194           driver_binary_path = driver_shell_binary64_;
    195         }
    196         size_t offset = driver_binary_path.find_last_of("/");
    197         string ld_dir_path = driver_binary_path.substr(0, offset);
    198 
    199 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    200         asprintf(
    201             &cmd,
    202             "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s --server_socket_path=%s",
    203             ld_dir_path.c_str(), driver_binary_path.c_str(),
    204             socket_port_flie_path.c_str());
    205 #else  // binder
    206         LOG(ERROR) << "No binder implementation available.";
    207         exit(-1);
    208 #endif
    209       } else {
    210         LOG(ERROR) << "Unsupported driver type.";
    211       }
    212 
    213       if (cmd) {
    214         LOG(INFO) << "Launch a driver - " << cmd;
    215         system(cmd);
    216         LOG(INFO) << "driver exits";
    217         free(cmd);
    218       }
    219       exit(0);
    220     } else if (pid > 0) {
    221       for (int attempt = 0; attempt < 10; attempt++) {
    222         sleep(1);
    223         if (IsDriverRunning(service_name, 10)) {
    224           result = SUCCESS;
    225           break;
    226         }
    227       }
    228       if (result) {
    229 // TODO: use an attribute (client) of a newly defined class.
    230 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    231         VtsDriverSocketClient* client =
    232             android::vts::GetDriverSocketClient(service_name);
    233         if (!client) {
    234 #else  // binder
    235         android::sp<android::vts::IVtsFuzzer> client =
    236             android::vts::GetBinderClient(service_name);
    237         if (!client.get()) {
    238 #endif
    239           response_msg.set_response_code(FAIL);
    240           response_msg.set_reason("Failed to start a driver.");
    241           // TODO: kill the driver?
    242           return VtsSocketSendMessage(response_msg);
    243         }
    244 
    245         if (driver_type == VTS_DRIVER_TYPE_HAL_CONVENTIONAL ||
    246             driver_type == VTS_DRIVER_TYPE_HAL_LEGACY ||
    247             driver_type == VTS_DRIVER_TYPE_HAL_HIDL) {
    248           LOG(DEBUG) << "LoadHal " << module_name;
    249           int32_t driver_id = client->LoadHal(
    250               file_path, target_class, target_type, target_version,
    251               target_package, target_component_name, hw_binder_service_name,
    252               module_name);
    253           if (driver_id == -1) {
    254             response_msg.set_response_code(FAIL);
    255             response_msg.set_reason("Failed to load the selected HAL.");
    256           } else {
    257             response_msg.set_response_code(SUCCESS);
    258             response_msg.set_result(to_string(driver_id));
    259             response_msg.set_reason("Loaded the selected HAL.");
    260             LOG(DEBUG) << "set service_name " << service_name;
    261             service_name_ = service_name;
    262           }
    263         } else if (driver_type == VTS_DRIVER_TYPE_SHELL) {
    264           response_msg.set_response_code(SUCCESS);
    265           response_msg.set_reason("Loaded the shell driver.");
    266           LOG(DEBUG) << "set service_name " << service_name;
    267           service_name_ = service_name;
    268         }
    269 
    270 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    271         driver_client_ = client;
    272 #endif
    273         return VtsSocketSendMessage(response_msg);
    274       }
    275     }
    276     response_msg.set_reason(
    277         "Failed to fork a child process to start a driver.");
    278   }
    279   response_msg.set_response_code(FAIL);
    280   LOG(ERROR) << "Can't fork a child process to run the vts_hal_driver.";
    281   return VtsSocketSendMessage(response_msg);
    282 }
    283 
    284 bool AgentRequestHandler::ReadSpecification(
    285     const AndroidSystemControlCommandMessage& command_message) {
    286 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    287   VtsDriverSocketClient* client = driver_client_;
    288   if (!client) {
    289 #else  // binder
    290   android::sp<android::vts::IVtsFuzzer> client =
    291       android::vts::GetBinderClient(service_name_);
    292   if (!client.get()) {
    293 #endif
    294     return false;
    295   }
    296 
    297   const string& result = client->ReadSpecification(
    298       command_message.service_name(), command_message.target_class(),
    299       command_message.target_type(), command_message.target_version() / 100.0f,
    300       command_message.target_package());
    301 
    302   return SendApiResult("ReadSpecification", result);
    303 }
    304 
    305 bool AgentRequestHandler::ListApis() {
    306 // TODO: use an attribute (client) of a newly defined class.
    307 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    308   VtsDriverSocketClient* client = driver_client_;
    309   if (!client) {
    310 #else  // binder
    311   android::sp<android::vts::IVtsFuzzer> client =
    312       android::vts::GetBinderClient(service_name_);
    313   if (!client.get()) {
    314 #endif
    315     return false;
    316   }
    317   return SendApiResult("GetAttribute", "", client->GetFunctions());
    318 }
    319 
    320 bool AgentRequestHandler::CallApi(const string& call_payload,
    321                                   const string& uid) {
    322 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    323   VtsDriverSocketClient* client = driver_client_;
    324   if (!client) {
    325 #else  // binder
    326   // TODO: use an attribute (client) of a newly defined class.
    327   android::sp<android::vts::IVtsFuzzer> client =
    328       android::vts::GetBinderClient(service_name_);
    329   if (!client.get()) {
    330 #endif
    331     return false;
    332   }
    333 
    334   return SendApiResult("Call", client->Call(call_payload, uid));
    335 }
    336 
    337 bool AgentRequestHandler::GetAttribute(const string& payload) {
    338 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    339   VtsDriverSocketClient* client = driver_client_;
    340   if (!client) {
    341 #else  // binder
    342   // TODO: use an attribute (client) of a newly defined class.
    343   android::sp<android::vts::IVtsFuzzer> client =
    344       android::vts::GetBinderClient(service_name_);
    345   if (!client.get()) {
    346 #endif
    347     return false;
    348   }
    349 
    350   return SendApiResult("GetAttribute", client->GetAttribute(payload));
    351 }
    352 
    353 bool AgentRequestHandler::SendApiResult(const string& func_name,
    354                                         const string& result,
    355                                         const string& spec) {
    356   AndroidSystemControlResponseMessage response_msg;
    357   if (result.size() > 0 || spec.size() > 0) {
    358     LOG(DEBUG) << "Call: success";
    359     response_msg.set_response_code(SUCCESS);
    360     if (result.size() > 0) {
    361       response_msg.set_result(result);
    362     }
    363     if (spec.size() > 0) {
    364       response_msg.set_spec(spec);
    365     }
    366   } else {
    367     LOG(ERROR) << "Call: fail";
    368     response_msg.set_response_code(FAIL);
    369     response_msg.set_reason("Failed to call api function: " + func_name);
    370   }
    371   return VtsSocketSendMessage(response_msg);
    372 }
    373 
    374 bool AgentRequestHandler::DefaultResponse() {
    375   AndroidSystemControlResponseMessage response_msg;
    376   response_msg.set_response_code(SUCCESS);
    377   response_msg.set_reason("an example reason here");
    378   return VtsSocketSendMessage(response_msg);
    379 }
    380 
    381 bool AgentRequestHandler::ExecuteShellCommand(
    382     const AndroidSystemControlCommandMessage& command_message) {
    383 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
    384   VtsDriverSocketClient* client = driver_client_;
    385   if (!client) {
    386 #else  // binder
    387   LOG(ERROR) << " binder not supported.";
    388   {
    389 #endif
    390     return false;
    391   }
    392 
    393   auto result_message =
    394       client->ExecuteShellCommand(command_message.shell_command());
    395 
    396   AndroidSystemControlResponseMessage response_msg;
    397 
    398   if (result_message) {
    399     CreateSystemControlResponseFromDriverControlResponse(*result_message,
    400                                                          &response_msg);
    401   } else {
    402     LOG(ERROR) << "ExecuteShellCommand: failed to call the api";
    403     response_msg.set_response_code(FAIL);
    404     response_msg.set_reason("Failed to call the api.");
    405   }
    406 
    407   return VtsSocketSendMessage(response_msg);
    408 }
    409 
    410 void AgentRequestHandler::CreateSystemControlResponseFromDriverControlResponse(
    411     const VtsDriverControlResponseMessage& driver_control_response_message,
    412     AndroidSystemControlResponseMessage* system_control_response_message) {
    413 
    414   if (driver_control_response_message.response_code() ==
    415       VTS_DRIVER_RESPONSE_SUCCESS) {
    416     LOG(DEBUG) << "ExecuteShellCommand: shell driver reported success";
    417     system_control_response_message->set_response_code(SUCCESS);
    418   } else if (driver_control_response_message.response_code() ==
    419       VTS_DRIVER_RESPONSE_FAIL) {
    420     LOG(ERROR) << "ExecuteShellCommand: shell driver reported fail";
    421     system_control_response_message->set_response_code(FAIL);
    422   } else if (driver_control_response_message.response_code() ==
    423       UNKNOWN_VTS_DRIVER_RESPONSE_CODE) {
    424     LOG(ERROR) << "ExecuteShellCommand: shell driver reported unknown";
    425     system_control_response_message->set_response_code(UNKNOWN_RESPONSE_CODE);
    426   }
    427 
    428   for (const auto& log_stdout : driver_control_response_message.stdout()) {
    429     system_control_response_message->add_stdout(log_stdout);
    430   }
    431 
    432   for (const auto& log_stderr : driver_control_response_message.stderr()) {
    433     system_control_response_message->add_stderr(log_stderr);
    434   }
    435 
    436   for (const auto& exit_code : driver_control_response_message.exit_code()) {
    437     system_control_response_message->add_exit_code(exit_code);
    438   }
    439 }
    440 
    441 bool AgentRequestHandler::ProcessOneCommand() {
    442   AndroidSystemControlCommandMessage command_msg;
    443   if (!VtsSocketRecvMessage(&command_msg)) return false;
    444 
    445   LOG(DEBUG) << "command_type = " << command_msg.command_type();
    446   switch (command_msg.command_type()) {
    447     case LIST_HALS:
    448       return ListHals(command_msg.paths());
    449     case SET_HOST_INFO:
    450       return SetHostInfo(command_msg.callback_port());
    451     case CHECK_DRIVER_SERVICE:
    452       return CheckDriverService(command_msg.service_name(), NULL);
    453     case LAUNCH_DRIVER_SERVICE:
    454       return LaunchDriverService(command_msg);
    455     case VTS_AGENT_COMMAND_READ_SPECIFICATION:
    456       return ReadSpecification(command_msg);
    457     case LIST_APIS:
    458       return ListApis();
    459     case CALL_API:
    460       return CallApi(command_msg.arg(), command_msg.driver_caller_uid());
    461     case VTS_AGENT_COMMAND_GET_ATTRIBUTE:
    462       return GetAttribute(command_msg.arg());
    463     // for shell driver
    464     case VTS_AGENT_COMMAND_EXECUTE_SHELL_COMMAND:
    465       ExecuteShellCommand(command_msg);
    466       return true;
    467     default:
    468       LOG(ERROR) << " ERROR unknown command " << command_msg.command_type();
    469       return DefaultResponse();
    470   }
    471 }
    472 
    473 }  // namespace vts
    474 }  // namespace android
    475