1 /*
2  * Copyright (C) 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 
17 #include "wificond/tests/integration/process_utils.h"
18 
19 #include <unistd.h>
20 
21 #include <android-base/logging.h>
22 #include <android-base/stringprintf.h>
23 #include <android-base/strings.h>
24 #include <binder/IBinder.h>
25 #include <binder/IServiceManager.h>
26 #include <utils/String16.h>
27 #include <utils/StrongPointer.h>
28 
29 #include "wificond/ipc_constants.h"
30 #include "wificond/tests/shell_utils.h"
31 
32 using android::String16;
33 using android::base::StringPrintf;
34 using android::base::Trim;
35 using android::net::wifi::IWificond;
36 using android::sp;
37 using android::wificond::ipc_constants::kServiceName;
38 
39 namespace android {
40 namespace wificond {
41 namespace tests {
42 namespace integration {
43 namespace {
44 
IsProcessRunning(const char * process_name)45 bool IsProcessRunning(const char* process_name) {
46   std::string output;
47   RunShellCommand(StringPrintf("pgrep -c ^%s$", process_name), &output);
48   output = Trim(output);
49   if (output == "0") {
50     return false;
51   }
52   return true;
53 }
54 
55 }
56 
57 const uint32_t ScopedDevModeWificond::kSystemServerDeathTimeoutSeconds = 10;
58 const uint32_t ScopedDevModeWificond::kSystemServerStartTimeoutSeconds = 10;
59 const uint32_t ScopedDevModeWificond::kWificondDeathTimeoutSeconds = 10;
60 const uint32_t ScopedDevModeWificond::kWificondStartTimeoutSeconds = 10;
61 
~ScopedDevModeWificond()62 ScopedDevModeWificond::~ScopedDevModeWificond() {
63   if (in_dev_mode_) {
64     ExitDevMode();
65   }
66 }
67 
EnterDevModeOrDie()68 sp<IWificond> ScopedDevModeWificond::EnterDevModeOrDie() {
69   sp<IWificond> service;
70   RunShellCommand("stop wificond");
71   CHECK(WaitForTrue(WificondIsDead, kWificondDeathTimeoutSeconds));
72   RunShellCommand("stop");
73   CHECK(WaitForTrue(SystemServerIsDead, kSystemServerDeathTimeoutSeconds));
74   RunShellCommand("start wificond");
75   auto wificond_restarted = std::bind(IsBinderServiceRegistered, kServiceName);
76   CHECK(WaitForTrue(wificond_restarted, kWificondStartTimeoutSeconds));
77   status_t status = getService(String16(kServiceName), &service);
78   if (status != NO_ERROR || service.get() == nullptr) {
79     LOG(FATAL) << "Failed to restart wificond in dev mode";
80   }
81   in_dev_mode_ = true;
82   return service;
83 }
84 
ExitDevMode()85 void ScopedDevModeWificond::ExitDevMode() {
86   RunShellCommand("stop wificond");
87   CHECK(WaitForTrue(WificondIsDead, kWificondDeathTimeoutSeconds));
88   RunShellCommand("start");
89   CHECK(WaitForTrue(SystemServerIsRunning, kSystemServerStartTimeoutSeconds));
90   RunShellCommand("start wificond");
91   CHECK(WaitForTrue(WificondIsRunning, kWificondStartTimeoutSeconds));
92   in_dev_mode_ = false;
93 }
94 
WaitForTrue(std::function<bool ()> condition,time_t timeout_seconds)95 bool WaitForTrue(std::function<bool()> condition, time_t timeout_seconds) {
96   time_t start_time_seconds = time(nullptr);
97   do {
98     if (condition()) {
99       return true;
100     }
101     usleep(1000);
102   } while ((time(nullptr) - start_time_seconds) < timeout_seconds);
103   return false;
104 }
105 
IsBinderServiceRegistered(const char * service_name)106 bool IsBinderServiceRegistered(const char* service_name) {
107   sp<IBinder> service =
108       defaultServiceManager()->checkService(String16(service_name));
109   return service.get() != nullptr;
110 }
111 
SystemServerIsRunning()112 bool SystemServerIsRunning() {
113   return IsProcessRunning("system_server");
114 }
115 
SystemServerIsDead()116 bool SystemServerIsDead() {
117   return !IsProcessRunning("system_server");
118 }
119 
WificondIsRunning()120 bool WificondIsRunning() {
121   return IsProcessRunning("wificond");
122 }
123 
WificondIsDead()124 bool WificondIsDead() { return !WificondIsRunning(); }
125 
HostapdIsRunning()126 bool HostapdIsRunning() {
127   return IsProcessRunning("hostapd");
128 }
129 
HostapdIsDead()130 bool HostapdIsDead() { return !HostapdIsRunning(); }
131 
SupplicantIsRunning()132 bool SupplicantIsRunning() {
133   return IsProcessRunning("wpa_supplicant");
134 }
135 
SupplicantIsDead()136 bool SupplicantIsDead() { return !SupplicantIsRunning(); }
137 
138 }  // namespace integration
139 }  // namespace tests
140 }  // namespace android
141 }  // namespace wificond
142