• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 "test/android_test_utils.h"
18 
19 #include <stdlib.h>
20 
21 #include "perfetto/base/logging.h"
22 #include "perfetto/ext/base/android_utils.h"
23 #include "perfetto/ext/base/file_utils.h"
24 
25 namespace perfetto {
26 namespace {
27 
28 // 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 void PollRunState(bool desired_run_state,
30                   base::TestTaskRunner* task_runner,
31                   const std::string& name,
32                   std::function<void()> callback) {
33   bool app_running = IsAppRunning(name);
34   if (app_running == desired_run_state) {
35     callback();
36     return;
37   }
38   task_runner->PostDelayedTask(
39       [desired_run_state, task_runner, name, callback] {
40         PollRunState(desired_run_state, task_runner, name, std::move(callback));
41       },
42       /*delay_ms=*/5);
43 }
44 
45 }  // namespace
46 
IsDebuggableBuild()47 bool IsDebuggableBuild() {
48   std::string debuggable = base::GetAndroidProp("ro.debuggable");
49   return debuggable == "1";
50 }
51 
IsUserBuild()52 bool IsUserBuild() {
53   std::string build_type = base::GetAndroidProp("ro.build.type");
54   return build_type == "user";
55 }
56 
57 // note: cannot use gtest macros due to return type
IsAppRunning(const std::string & name)58 bool IsAppRunning(const std::string& name) {
59   std::string cmd = "pgrep -f ^" + name + "$";
60   int retcode = system(cmd.c_str());
61   PERFETTO_CHECK(retcode >= 0);
62   int exit_status = WEXITSTATUS(retcode);
63   if (exit_status == 0)
64     return true;
65   if (exit_status == 1)
66     return false;
67   PERFETTO_FATAL("unexpected exit status from system(pgrep): %d", exit_status);
68 }
69 
PidForProcessName(const std::string & name)70 int PidForProcessName(const std::string& name) {
71   std::string cmd = "pgrep -f ^" + name + "$";
72   FILE* fp = popen(cmd.c_str(), "re");
73   if (!fp)
74     return -1;
75 
76   std::string out;
77   base::ReadFileStream(fp, &out);
78   pclose(fp);
79 
80   char* endptr = nullptr;
81   int pid = static_cast<int>(strtol(out.c_str(), &endptr, 10));
82   if (*endptr != '\0' && *endptr != '\n')
83     return -1;
84   return pid;
85 }
86 
WaitForProcess(const std::string & process,const std::string & checkpoint_name,base::TestTaskRunner * task_runner,uint32_t delay_ms)87 void WaitForProcess(const std::string& process,
88                     const std::string& checkpoint_name,
89                     base::TestTaskRunner* task_runner,
90                     uint32_t delay_ms) {
91   bool desired_run_state = true;
92   const auto checkpoint = task_runner->CreateCheckpoint(checkpoint_name);
93   task_runner->PostDelayedTask(
94       [desired_run_state, task_runner, process, checkpoint] {
95         PollRunState(desired_run_state, task_runner, process,
96                      std::move(checkpoint));
97       },
98       delay_ms);
99 }
100 
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 void StartAppActivity(const std::string& app_name,
102                       const std::string& activity_name,
103                       const std::string& checkpoint_name,
104                       base::TestTaskRunner* task_runner,
105                       uint32_t delay_ms) {
106   std::string start_cmd = "am start " + app_name + "/." + activity_name;
107   int status = system(start_cmd.c_str());
108   PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
109   WaitForProcess(app_name, checkpoint_name, task_runner, delay_ms);
110 }
111 
StopApp(const std::string & app_name,const std::string & checkpoint_name,base::TestTaskRunner * task_runner)112 void StopApp(const std::string& app_name,
113              const std::string& checkpoint_name,
114              base::TestTaskRunner* task_runner) {
115   std::string stop_cmd = "am force-stop " + app_name;
116   int status = system(stop_cmd.c_str());
117   PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
118 
119   bool desired_run_state = false;
120   auto checkpoint = task_runner->CreateCheckpoint(checkpoint_name);
121   task_runner->PostTask([desired_run_state, task_runner, app_name, checkpoint] {
122     PollRunState(desired_run_state, task_runner, app_name,
123                  std::move(checkpoint));
124   });
125 }
126 
StopApp(const std::string & app_name)127 void StopApp(const std::string& app_name) {
128   std::string stop_cmd = "am force-stop " + app_name;
129   system(stop_cmd.c_str());
130 }
131 
132 }  // namespace perfetto
133