xref: /aosp_15_r20/external/perfetto/test/android_test_utils.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "test/android_test_utils.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <stdlib.h>
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/android_utils.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
24*6dbdd20aSAndroid Build Coastguard Worker 
25*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
26*6dbdd20aSAndroid Build Coastguard Worker namespace {
27*6dbdd20aSAndroid Build Coastguard Worker 
28*6dbdd20aSAndroid Build Coastguard Worker // invokes |callback| once the target app is in the desired state
PollRunState(bool desired_run_state,base::TestTaskRunner * task_runner,const std::string & name,std::function<void ()> callback)29*6dbdd20aSAndroid Build Coastguard Worker void PollRunState(bool desired_run_state,
30*6dbdd20aSAndroid Build Coastguard Worker                   base::TestTaskRunner* task_runner,
31*6dbdd20aSAndroid Build Coastguard Worker                   const std::string& name,
32*6dbdd20aSAndroid Build Coastguard Worker                   std::function<void()> callback) {
33*6dbdd20aSAndroid Build Coastguard Worker   bool app_running = IsAppRunning(name);
34*6dbdd20aSAndroid Build Coastguard Worker   if (app_running == desired_run_state) {
35*6dbdd20aSAndroid Build Coastguard Worker     callback();
36*6dbdd20aSAndroid Build Coastguard Worker     return;
37*6dbdd20aSAndroid Build Coastguard Worker   }
38*6dbdd20aSAndroid Build Coastguard Worker   task_runner->PostDelayedTask(
39*6dbdd20aSAndroid Build Coastguard Worker       [desired_run_state, task_runner, name, callback] {
40*6dbdd20aSAndroid Build Coastguard Worker         PollRunState(desired_run_state, task_runner, name, std::move(callback));
41*6dbdd20aSAndroid Build Coastguard Worker       },
42*6dbdd20aSAndroid Build Coastguard Worker       /*delay_ms=*/5);
43*6dbdd20aSAndroid Build Coastguard Worker }
44*6dbdd20aSAndroid Build Coastguard Worker 
45*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
46*6dbdd20aSAndroid Build Coastguard Worker 
IsDebuggableBuild()47*6dbdd20aSAndroid Build Coastguard Worker bool IsDebuggableBuild() {
48*6dbdd20aSAndroid Build Coastguard Worker   std::string debuggable = base::GetAndroidProp("ro.debuggable");
49*6dbdd20aSAndroid Build Coastguard Worker   return debuggable == "1";
50*6dbdd20aSAndroid Build Coastguard Worker }
51*6dbdd20aSAndroid Build Coastguard Worker 
IsUserBuild()52*6dbdd20aSAndroid Build Coastguard Worker bool IsUserBuild() {
53*6dbdd20aSAndroid Build Coastguard Worker   std::string build_type = base::GetAndroidProp("ro.build.type");
54*6dbdd20aSAndroid Build Coastguard Worker   return build_type == "user";
55*6dbdd20aSAndroid Build Coastguard Worker }
56*6dbdd20aSAndroid Build Coastguard Worker 
57*6dbdd20aSAndroid Build Coastguard Worker // note: cannot use gtest macros due to return type
IsAppRunning(const std::string & name)58*6dbdd20aSAndroid Build Coastguard Worker bool IsAppRunning(const std::string& name) {
59*6dbdd20aSAndroid Build Coastguard Worker   std::string cmd = "pgrep -f ^" + name + "$";
60*6dbdd20aSAndroid Build Coastguard Worker   int retcode = system(cmd.c_str());
61*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(retcode >= 0);
62*6dbdd20aSAndroid Build Coastguard Worker   int exit_status = WEXITSTATUS(retcode);
63*6dbdd20aSAndroid Build Coastguard Worker   if (exit_status == 0)
64*6dbdd20aSAndroid Build Coastguard Worker     return true;
65*6dbdd20aSAndroid Build Coastguard Worker   if (exit_status == 1)
66*6dbdd20aSAndroid Build Coastguard Worker     return false;
67*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_FATAL("unexpected exit status from system(pgrep): %d", exit_status);
68*6dbdd20aSAndroid Build Coastguard Worker }
69*6dbdd20aSAndroid Build Coastguard Worker 
PidForProcessName(const std::string & name)70*6dbdd20aSAndroid Build Coastguard Worker int PidForProcessName(const std::string& name) {
71*6dbdd20aSAndroid Build Coastguard Worker   std::string cmd = "pgrep -f ^" + name + "$";
72*6dbdd20aSAndroid Build Coastguard Worker   FILE* fp = popen(cmd.c_str(), "re");
73*6dbdd20aSAndroid Build Coastguard Worker   if (!fp)
74*6dbdd20aSAndroid Build Coastguard Worker     return -1;
75*6dbdd20aSAndroid Build Coastguard Worker 
76*6dbdd20aSAndroid Build Coastguard Worker   std::string out;
77*6dbdd20aSAndroid Build Coastguard Worker   base::ReadFileStream(fp, &out);
78*6dbdd20aSAndroid Build Coastguard Worker   pclose(fp);
79*6dbdd20aSAndroid Build Coastguard Worker 
80*6dbdd20aSAndroid Build Coastguard Worker   char* endptr = nullptr;
81*6dbdd20aSAndroid Build Coastguard Worker   int pid = static_cast<int>(strtol(out.c_str(), &endptr, 10));
82*6dbdd20aSAndroid Build Coastguard Worker   if (*endptr != '\0' && *endptr != '\n')
83*6dbdd20aSAndroid Build Coastguard Worker     return -1;
84*6dbdd20aSAndroid Build Coastguard Worker   return pid;
85*6dbdd20aSAndroid Build Coastguard Worker }
86*6dbdd20aSAndroid Build Coastguard Worker 
WaitForProcess(const std::string & process,const std::string & checkpoint_name,base::TestTaskRunner * task_runner,uint32_t delay_ms)87*6dbdd20aSAndroid Build Coastguard Worker void WaitForProcess(const std::string& process,
88*6dbdd20aSAndroid Build Coastguard Worker                     const std::string& checkpoint_name,
89*6dbdd20aSAndroid Build Coastguard Worker                     base::TestTaskRunner* task_runner,
90*6dbdd20aSAndroid Build Coastguard Worker                     uint32_t delay_ms) {
91*6dbdd20aSAndroid Build Coastguard Worker   bool desired_run_state = true;
92*6dbdd20aSAndroid Build Coastguard Worker   const auto checkpoint = task_runner->CreateCheckpoint(checkpoint_name);
93*6dbdd20aSAndroid Build Coastguard Worker   task_runner->PostDelayedTask(
94*6dbdd20aSAndroid Build Coastguard Worker       [desired_run_state, task_runner, process, checkpoint] {
95*6dbdd20aSAndroid Build Coastguard Worker         PollRunState(desired_run_state, task_runner, process,
96*6dbdd20aSAndroid Build Coastguard Worker                      std::move(checkpoint));
97*6dbdd20aSAndroid Build Coastguard Worker       },
98*6dbdd20aSAndroid Build Coastguard Worker       delay_ms);
99*6dbdd20aSAndroid Build Coastguard Worker }
100*6dbdd20aSAndroid Build Coastguard Worker 
StartAppActivity(const std::string & app_name,const std::string & activity_name,const std::string & checkpoint_name,base::TestTaskRunner * task_runner,uint32_t delay_ms)101*6dbdd20aSAndroid Build Coastguard Worker void StartAppActivity(const std::string& app_name,
102*6dbdd20aSAndroid Build Coastguard Worker                       const std::string& activity_name,
103*6dbdd20aSAndroid Build Coastguard Worker                       const std::string& checkpoint_name,
104*6dbdd20aSAndroid Build Coastguard Worker                       base::TestTaskRunner* task_runner,
105*6dbdd20aSAndroid Build Coastguard Worker                       uint32_t delay_ms) {
106*6dbdd20aSAndroid Build Coastguard Worker   std::string start_cmd = "am start " + app_name + "/." + activity_name;
107*6dbdd20aSAndroid Build Coastguard Worker   int status = system(start_cmd.c_str());
108*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
109*6dbdd20aSAndroid Build Coastguard Worker   WaitForProcess(app_name, checkpoint_name, task_runner, delay_ms);
110*6dbdd20aSAndroid Build Coastguard Worker }
111*6dbdd20aSAndroid Build Coastguard Worker 
StopApp(const std::string & app_name,const std::string & checkpoint_name,base::TestTaskRunner * task_runner)112*6dbdd20aSAndroid Build Coastguard Worker void StopApp(const std::string& app_name,
113*6dbdd20aSAndroid Build Coastguard Worker              const std::string& checkpoint_name,
114*6dbdd20aSAndroid Build Coastguard Worker              base::TestTaskRunner* task_runner) {
115*6dbdd20aSAndroid Build Coastguard Worker   std::string stop_cmd = "am force-stop " + app_name;
116*6dbdd20aSAndroid Build Coastguard Worker   int status = system(stop_cmd.c_str());
117*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
118*6dbdd20aSAndroid Build Coastguard Worker 
119*6dbdd20aSAndroid Build Coastguard Worker   bool desired_run_state = false;
120*6dbdd20aSAndroid Build Coastguard Worker   auto checkpoint = task_runner->CreateCheckpoint(checkpoint_name);
121*6dbdd20aSAndroid Build Coastguard Worker   task_runner->PostTask([desired_run_state, task_runner, app_name, checkpoint] {
122*6dbdd20aSAndroid Build Coastguard Worker     PollRunState(desired_run_state, task_runner, app_name,
123*6dbdd20aSAndroid Build Coastguard Worker                  std::move(checkpoint));
124*6dbdd20aSAndroid Build Coastguard Worker   });
125*6dbdd20aSAndroid Build Coastguard Worker }
126*6dbdd20aSAndroid Build Coastguard Worker 
StopApp(const std::string & app_name)127*6dbdd20aSAndroid Build Coastguard Worker void StopApp(const std::string& app_name) {
128*6dbdd20aSAndroid Build Coastguard Worker   std::string stop_cmd = "am force-stop " + app_name;
129*6dbdd20aSAndroid Build Coastguard Worker   system(stop_cmd.c_str());
130*6dbdd20aSAndroid Build Coastguard Worker }
131*6dbdd20aSAndroid Build Coastguard Worker 
132*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
133