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 #include "test/vts/proto/VtsResourceControllerMessage.pb.h"
33 
34 using namespace std;
35 using namespace google::protobuf;
36 
37 namespace android {
38 namespace vts {
39 
ListHals(const RepeatedPtrField<string> & base_paths)40 bool AgentRequestHandler::ListHals(const RepeatedPtrField<string>& base_paths) {
41   AndroidSystemControlResponseMessage response_msg;
42   ResponseCode result = FAIL;
43 
44   for (const string& path : base_paths) {
45     LOG(DEBUG) << "open a dir " << path;
46     DIR* dp;
47     if (!(dp = opendir(path.c_str()))) {
48       LOG(ERROR) << "Error(" << errno << ") opening " << path;
49       continue;
50     }
51 
52     struct dirent* dirp;
53     int len;
54     while ((dirp = readdir(dp)) != NULL) {
55       len = strlen(dirp->d_name);
56       if (len > 3 && !strcmp(&dirp->d_name[len - 3], ".so")) {
57         string found_path = path + "/" + string(dirp->d_name);
58         LOG(INFO) << "found " << found_path;
59         response_msg.add_file_names(found_path);
60         result = SUCCESS;
61       }
62     }
63     closedir(dp);
64   }
65   response_msg.set_response_code(result);
66   return VtsSocketSendMessage(response_msg);
67 }
68 
SetHostInfo(const int callback_port)69 bool AgentRequestHandler::SetHostInfo(const int callback_port) {
70   callback_port_ = callback_port;
71   AndroidSystemControlResponseMessage response_msg;
72   response_msg.set_response_code(SUCCESS);
73   return VtsSocketSendMessage(response_msg);
74 }
75 
CheckDriverService(const string & service_name,bool * live)76 bool AgentRequestHandler::CheckDriverService(const string& service_name,
77                                              bool* live) {
78   AndroidSystemControlResponseMessage response_msg;
79 
80 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
81   if (IsDriverRunning(service_name, 10)) {
82 #else  // binder
83   sp<IVtsFuzzer> binder = GetBinderClient(service_name);
84   if (binder.get()) {
85 #endif
86     if (live) *live = true;
87     response_msg.set_response_code(SUCCESS);
88     response_msg.set_reason("found the service");
89     LOG(DEBUG) << "set service_name " << service_name;
90     service_name_ = service_name;
91   } else {
92     if (live) *live = false;
93     response_msg.set_response_code(FAIL);
94     response_msg.set_reason("service not found");
95   }
96   return VtsSocketSendMessage(response_msg);
97 }
98 
99 static const char kUnixSocketNamePrefixForCallbackServer[] =
100     "/data/local/tmp/vts_agent_callback";
101 
102 bool AgentRequestHandler::LaunchDriverService(
103     const AndroidSystemControlCommandMessage& command_msg) {
104   int driver_type = command_msg.driver_type();
105   const string& service_name = command_msg.service_name();
106   const string& file_path = command_msg.file_path();
107   int target_class = command_msg.target_class();
108   int target_type = command_msg.target_type();
109   int target_version_major = command_msg.target_version_major();
110   int target_version_minor = command_msg.target_version_minor();
111   const string& target_package = command_msg.target_package();
112   const string& target_component_name = command_msg.target_component_name();
113   const string& module_name = command_msg.module_name();
114   const string& hw_binder_service_name = command_msg.hw_binder_service_name();
115   int bits = command_msg.bits();
116   const string& test_hal_flag =
117       command_msg.is_test_hal() ? "TREBLE_TESTING_OVERRIDE=true " : "";
118 
119   LOG(DEBUG) << "file_path=" << file_path;
120   ResponseCode result = FAIL;
121 
122   // TODO: shall check whether there's a service with the same name and return
123   // success immediately if exists.
124   AndroidSystemControlResponseMessage response_msg;
125 
126   // deletes the service file if exists before starting to launch a driver.
127   string socket_port_flie_path = GetSocketPortFilePath(service_name);
128   struct stat file_stat;
129   if (stat(socket_port_flie_path.c_str(), &file_stat) == 0  // file exists
130       && remove(socket_port_flie_path.c_str()) == -1) {
131     LOG(ERROR) << socket_port_flie_path << " delete error";
132     response_msg.set_reason("service file already exists.");
133   } else {
134     pid_t pid = fork();
135     if (pid == 0) {  // child
136       Close();
137 
138       string driver_binary_path;
139       char* cmd = NULL;
140       if (driver_type == VTS_DRIVER_TYPE_HAL_CONVENTIONAL ||
141           driver_type == VTS_DRIVER_TYPE_HAL_LEGACY ||
142           driver_type == VTS_DRIVER_TYPE_HAL_HIDL) {
143         // TODO: check whether the port is available and handle if fails.
144         static int port = 0;
145         string callback_socket_name(kUnixSocketNamePrefixForCallbackServer);
146         callback_socket_name += to_string(port++);
147         LOG(INFO) << "callback_socket_name: " << callback_socket_name;
148         StartSocketServerForDriver(callback_socket_name, -1);
149 
150         if (bits == 32) {
151           driver_binary_path = driver_hal_binary32_;
152         } else {
153           driver_binary_path = driver_hal_binary64_;
154         }
155         size_t offset = driver_binary_path.find_last_of("/");
156         string ld_dir_path = driver_binary_path.substr(0, offset);
157 
158         if (driver_hal_spec_dir_path_.length() < 1) {
159 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
160           asprintf(&cmd,
161                    "%sLD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
162                    "--server_socket_path=%s "
163                    "--callback_socket_name=%s",
164                    test_hal_flag.c_str(), ld_dir_path.c_str(),
165                    driver_binary_path.c_str(), socket_port_flie_path.c_str(),
166                    callback_socket_name.c_str());
167 #else  // binder
168           asprintf(&cmd,
169                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
170                    "--service_name=%s "
171                    "--callback_socket_name=%s",
172                    ld_dir_path.c_str(), driver_binary_path.c_str(),
173                    service_name.c_str(), callback_socket_name.c_str());
174 #endif
175         } else {
176 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
177           asprintf(&cmd,
178                    "%sLD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
179                    "--server_socket_path=%s "
180                    "--spec_dir_path=%s --callback_socket_name=%s",
181                    test_hal_flag.c_str(), ld_dir_path.c_str(),
182                    driver_binary_path.c_str(), socket_port_flie_path.c_str(),
183                    driver_hal_spec_dir_path_.c_str(),
184                    callback_socket_name.c_str());
185 #else  // binder
186           asprintf(&cmd,
187                    "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s "
188                    "--service_name=%s "
189                    "--spec_dir_path=%s --callback_socket_name=%s",
190                    ld_dir_path.c_str(), driver_binary_path.c_str(),
191                    service_name.c_str(), driver_hal_spec_dir_path_.c_str(),
192                    callback_socket_name.c_str());
193 #endif
194         }
195       } else if (driver_type == VTS_DRIVER_TYPE_SHELL) {
196         if (bits == 32) {
197           driver_binary_path = driver_shell_binary32_;
198         } else {
199           driver_binary_path = driver_shell_binary64_;
200         }
201         size_t offset = driver_binary_path.find_last_of("/");
202         string ld_dir_path = driver_binary_path.substr(0, offset);
203 
204 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
205         asprintf(
206             &cmd,
207             "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s --server_socket_path=%s",
208             ld_dir_path.c_str(), driver_binary_path.c_str(),
209             socket_port_flie_path.c_str());
210 #else  // binder
211         LOG(ERROR) << "No binder implementation available.";
212         exit(-1);
213 #endif
214       } else {
215         LOG(ERROR) << "Unsupported driver type.";
216       }
217 
218       if (cmd) {
219         LOG(INFO) << "Launch a driver - " << cmd;
220         system(cmd);
221         LOG(INFO) << "driver exits";
222         free(cmd);
223       }
224       exit(0);
225     } else if (pid > 0) {
226       for (int attempt = 0; attempt < 10; attempt++) {
227         sleep(1);
228         if (IsDriverRunning(service_name, 10)) {
229           result = SUCCESS;
230           break;
231         }
232       }
233       if (result) {
234 // TODO: use an attribute (client) of a newly defined class.
235 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
236         VtsDriverSocketClient* client =
237             android::vts::GetDriverSocketClient(service_name);
238         if (!client) {
239 #else  // binder
240         android::sp<android::vts::IVtsFuzzer> client =
241             android::vts::GetBinderClient(service_name);
242         if (!client.get()) {
243 #endif
244           response_msg.set_response_code(FAIL);
245           response_msg.set_reason("Failed to start a driver.");
246           // TODO: kill the driver?
247           return VtsSocketSendMessage(response_msg);
248         }
249 
250         if (driver_type == VTS_DRIVER_TYPE_HAL_CONVENTIONAL ||
251             driver_type == VTS_DRIVER_TYPE_HAL_LEGACY ||
252             driver_type == VTS_DRIVER_TYPE_HAL_HIDL) {
253           LOG(DEBUG) << "LoadHal " << module_name;
254           int32_t driver_id = client->LoadHal(
255               file_path, target_class, target_type, target_version_major,
256               target_version_minor, target_package, target_component_name,
257               hw_binder_service_name, module_name);
258           if (driver_id == -1) {
259             response_msg.set_response_code(FAIL);
260             response_msg.set_reason("Failed to load the selected HAL.");
261           } else {
262             response_msg.set_response_code(SUCCESS);
263             response_msg.set_result(to_string(driver_id));
264             response_msg.set_reason("Loaded the selected HAL.");
265             LOG(DEBUG) << "set service_name " << service_name;
266             service_name_ = service_name;
267           }
268         } else if (driver_type == VTS_DRIVER_TYPE_SHELL) {
269           response_msg.set_response_code(SUCCESS);
270           response_msg.set_reason("Loaded the shell driver.");
271           LOG(DEBUG) << "set service_name " << service_name;
272           service_name_ = service_name;
273         }
274 
275 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
276         driver_client_ = client;
277 #endif
278         return VtsSocketSendMessage(response_msg);
279       }
280     }
281     response_msg.set_reason(
282         "Failed to fork a child process to start a driver.");
283   }
284   response_msg.set_response_code(FAIL);
285   LOG(ERROR) << "Can't fork a child process to run the vts_hal_driver.";
286   return VtsSocketSendMessage(response_msg);
287 }
288 
289 bool AgentRequestHandler::ReadSpecification(
290     const AndroidSystemControlCommandMessage& command_message) {
291 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
292   VtsDriverSocketClient* client = driver_client_;
293   if (!client) {
294 #else  // binder
295   android::sp<android::vts::IVtsFuzzer> client =
296       android::vts::GetBinderClient(service_name_);
297   if (!client.get()) {
298 #endif
299     return false;
300   }
301 
302   const string& result = client->ReadSpecification(
303       command_message.service_name(), command_message.target_class(),
304       command_message.target_type(), command_message.target_version_major(),
305       command_message.target_version_minor(), command_message.target_package());
306 
307   return SendApiResult("ReadSpecification", result);
308 }
309 
310 bool AgentRequestHandler::ListApis() {
311 // TODO: use an attribute (client) of a newly defined class.
312 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
313   VtsDriverSocketClient* client = driver_client_;
314   if (!client) {
315 #else  // binder
316   android::sp<android::vts::IVtsFuzzer> client =
317       android::vts::GetBinderClient(service_name_);
318   if (!client.get()) {
319 #endif
320     return false;
321   }
322   return SendApiResult("GetAttribute", "", client->GetFunctions());
323 }
324 
325 bool AgentRequestHandler::CallApi(const string& call_payload,
326                                   const string& uid) {
327 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
328   VtsDriverSocketClient* client = driver_client_;
329   if (!client) {
330 #else  // binder
331   // TODO: use an attribute (client) of a newly defined class.
332   android::sp<android::vts::IVtsFuzzer> client =
333       android::vts::GetBinderClient(service_name_);
334   if (!client.get()) {
335 #endif
336     return false;
337   }
338 
339   return SendApiResult("Call", client->Call(call_payload, uid));
340 }
341 
342 bool AgentRequestHandler::GetAttribute(const string& payload) {
343 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
344   VtsDriverSocketClient* client = driver_client_;
345   if (!client) {
346 #else  // binder
347   // TODO: use an attribute (client) of a newly defined class.
348   android::sp<android::vts::IVtsFuzzer> client =
349       android::vts::GetBinderClient(service_name_);
350   if (!client.get()) {
351 #endif
352     return false;
353   }
354 
355   return SendApiResult("GetAttribute", client->GetAttribute(payload));
356 }
357 
358 bool AgentRequestHandler::SendApiResult(const string& func_name,
359                                         const string& result,
360                                         const string& spec) {
361   AndroidSystemControlResponseMessage response_msg;
362   if (result.size() > 0 || spec.size() > 0) {
363     LOG(DEBUG) << "Call: success";
364     response_msg.set_response_code(SUCCESS);
365     if (result.size() > 0) {
366       response_msg.set_result(result);
367     }
368     if (spec.size() > 0) {
369       response_msg.set_spec(spec);
370     }
371   } else {
372     LOG(ERROR) << "Call: fail";
373     response_msg.set_response_code(FAIL);
374     response_msg.set_reason("Failed to call api function: " + func_name);
375   }
376   return VtsSocketSendMessage(response_msg);
377 }
378 
379 bool AgentRequestHandler::DefaultResponse() {
380   AndroidSystemControlResponseMessage response_msg;
381   response_msg.set_response_code(SUCCESS);
382   response_msg.set_reason("an example reason here");
383   return VtsSocketSendMessage(response_msg);
384 }
385 
386 bool AgentRequestHandler::ExecuteShellCommand(
387     const AndroidSystemControlCommandMessage& command_message) {
388 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
389   VtsDriverSocketClient* client = driver_client_;
390   if (!client) {
391 #else  // binder
392   LOG(ERROR) << " binder not supported.";
393   {
394 #endif
395     return false;
396   }
397 
398   auto result_message =
399       client->ExecuteShellCommand(command_message.shell_command());
400 
401   AndroidSystemControlResponseMessage response_msg;
402 
403   if (result_message) {
404     CreateSystemControlResponseFromDriverControlResponse(*result_message,
405                                                          &response_msg);
406   } else {
407     LOG(ERROR) << "ExecuteShellCommand: failed to call the api";
408     response_msg.set_response_code(FAIL);
409     response_msg.set_reason("Failed to call the api.");
410   }
411 
412   return VtsSocketSendMessage(response_msg);
413 }
414 
415 void AgentRequestHandler::CreateSystemControlResponseFromDriverControlResponse(
416     const VtsDriverControlResponseMessage& driver_control_response_message,
417     AndroidSystemControlResponseMessage* system_control_response_message) {
418 
419   if (driver_control_response_message.response_code() ==
420       VTS_DRIVER_RESPONSE_SUCCESS) {
421     LOG(DEBUG) << "ExecuteShellCommand: shell driver reported success";
422     system_control_response_message->set_response_code(SUCCESS);
423   } else if (driver_control_response_message.response_code() ==
424       VTS_DRIVER_RESPONSE_FAIL) {
425     LOG(ERROR) << "ExecuteShellCommand: shell driver reported fail";
426     system_control_response_message->set_response_code(FAIL);
427   } else if (driver_control_response_message.response_code() ==
428       UNKNOWN_VTS_DRIVER_RESPONSE_CODE) {
429     LOG(ERROR) << "ExecuteShellCommand: shell driver reported unknown";
430     system_control_response_message->set_response_code(UNKNOWN_RESPONSE_CODE);
431   }
432 
433   for (const auto& log_stdout : driver_control_response_message.stdout()) {
434     system_control_response_message->add_stdout(log_stdout);
435   }
436 
437   for (const auto& log_stderr : driver_control_response_message.stderr()) {
438     system_control_response_message->add_stderr(log_stderr);
439   }
440 
441   for (const auto& exit_code : driver_control_response_message.exit_code()) {
442     system_control_response_message->add_exit_code(exit_code);
443   }
444 }
445 
446 bool AgentRequestHandler::ProcessFmqCommand(
447     const AndroidSystemControlCommandMessage& command_msg) {
448 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
449   VtsDriverSocketClient* client = driver_client_;
450   if (!client) {
451 #else  // binder
452   android::sp<android::vts::IVtsFuzzer> client =
453       android::vts::GetBinderClient(service_name_);
454   if (!client.get()) {
455 #endif
456     LOG(ERROR) << "Driver socket client is uninitialized.";
457     return false;
458   }
459 
460   AndroidSystemControlResponseMessage response_msg;
461   FmqResponseMessage* fmq_response = response_msg.mutable_fmq_response();
462   FmqRequestMessage fmq_request = command_msg.fmq_request();
463   // send the request message
464   bool success = client->ProcessFmqCommand(fmq_request, fmq_response);
465 
466   // prepare for response back to host
467   if (success) {
468     response_msg.set_response_code(SUCCESS);
469   } else {
470     response_msg.set_response_code(FAIL);
471     response_msg.set_reason("Failed to call api to process FMQ command.");
472   }
473 
474   return VtsSocketSendMessage(response_msg);
475 }
476 
477 bool AgentRequestHandler::ProcessHidlMemoryCommand(
478     const AndroidSystemControlCommandMessage& command_msg) {
479 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
480   VtsDriverSocketClient* client = driver_client_;
481   if (!client) {
482 #else  // binder
483   android::sp<android::vts::IVtsFuzzer> client =
484       android::vts::GetBinderClient(service_name_);
485   if (!client.get()) {
486 #endif
487     LOG(ERROR) << "Driver socket client is uninitialized.";
488     return false;
489   }
490 
491   AndroidSystemControlResponseMessage response_msg;
492   HidlMemoryResponseMessage* hidl_memory_response =
493       response_msg.mutable_hidl_memory_response();
494   HidlMemoryRequestMessage hidl_memory_request =
495       command_msg.hidl_memory_request();
496   // send the request message
497   bool success = client->ProcessHidlMemoryCommand(hidl_memory_request,
498                                                   hidl_memory_response);
499 
500   // prepare for response back to host
501   if (success) {
502     response_msg.set_response_code(SUCCESS);
503   } else {
504     response_msg.set_response_code(FAIL);
505     response_msg.set_reason(
506         "Failed to call api to process hidl_memory command.");
507   }
508 
509   return VtsSocketSendMessage(response_msg);
510 }
511 
512 bool AgentRequestHandler::ProcessHidlHandleCommand(
513     const AndroidSystemControlCommandMessage& command_msg) {
514 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
515   VtsDriverSocketClient* client = driver_client_;
516   if (!client) {
517 #else  // binder
518   android::sp<android::vts::IVtsFuzzer> client =
519       android::vts::GetBinderClient(service_name_);
520   if (!client.get()) {
521 #endif
522     LOG(ERROR) << "Driver socket client is uninitialized.";
523     return false;
524   }
525 
526   AndroidSystemControlResponseMessage response_msg;
527   HidlHandleResponseMessage* hidl_handle_response =
528       response_msg.mutable_hidl_handle_response();
529   HidlHandleRequestMessage hidl_handle_request =
530       command_msg.hidl_handle_request();
531   // send the request message
532   bool success = client->ProcessHidlHandleCommand(hidl_handle_request,
533                                                   hidl_handle_response);
534 
535   // prepare for response back to host
536   if (success) {
537     response_msg.set_response_code(SUCCESS);
538   } else {
539     response_msg.set_response_code(FAIL);
540     response_msg.set_reason(
541         "Failed to call api to process hidl_handle command.");
542   }
543 
544   return VtsSocketSendMessage(response_msg);
545 }
546 
547 bool AgentRequestHandler::ProcessOneCommand() {
548   AndroidSystemControlCommandMessage command_msg;
549   if (!VtsSocketRecvMessage(&command_msg)) return false;
550 
551   LOG(DEBUG) << "command_type = " << command_msg.command_type();
552   switch (command_msg.command_type()) {
553     case LIST_HALS:
554       return ListHals(command_msg.paths());
555     case SET_HOST_INFO:
556       return SetHostInfo(command_msg.callback_port());
557     case CHECK_DRIVER_SERVICE:
558       return CheckDriverService(command_msg.service_name(), NULL);
559     case LAUNCH_DRIVER_SERVICE:
560       return LaunchDriverService(command_msg);
561     case VTS_AGENT_COMMAND_READ_SPECIFICATION:
562       return ReadSpecification(command_msg);
563     case LIST_APIS:
564       return ListApis();
565     case CALL_API:
566       return CallApi(command_msg.arg(), command_msg.driver_caller_uid());
567     case VTS_AGENT_COMMAND_GET_ATTRIBUTE:
568       return GetAttribute(command_msg.arg());
569     // for shell driver
570     case VTS_AGENT_COMMAND_EXECUTE_SHELL_COMMAND:
571       ExecuteShellCommand(command_msg);
572       return true;
573     case VTS_FMQ_COMMAND:
574       return ProcessFmqCommand(command_msg);
575     case VTS_HIDL_MEMORY_COMMAND:
576       return ProcessHidlMemoryCommand(command_msg);
577     case VTS_HIDL_HANDLE_COMMAND:
578       return ProcessHidlHandleCommand(command_msg);
579     default:
580       LOG(ERROR) << " ERROR unknown command " << command_msg.command_type();
581       return DefaultResponse();
582   }
583 }
584 
585 }  // namespace vts
586 }  // namespace android
587