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