blob: bfb1e1c3301bd85f2151c4c7300fe6e56126bece [file] [log] [blame]
Florian Mayere8599d42019-10-14 14:58:15 +01001/*
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
Primiano Tuccid6dc0c02020-12-01 16:15:28 +010017#include "test/android_test_utils.h"
Florian Mayere8599d42019-10-14 14:58:15 +010018
19#include <stdlib.h>
Florian Mayere8599d42019-10-14 14:58:15 +010020
21#include "perfetto/base/logging.h"
Daniele Di Proietto5ce0d142021-11-01 18:30:44 +000022#include "perfetto/ext/base/android_utils.h"
Ryan Savitski9fa72002020-02-19 14:31:20 +000023#include "perfetto/ext/base/file_utils.h"
Florian Mayere8599d42019-10-14 14:58:15 +010024
25namespace perfetto {
26namespace {
27
28// invokes |callback| once the target app is in the desired state
29void 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
47bool IsDebuggableBuild() {
Daniele Di Proietto5ce0d142021-11-01 18:30:44 +000048 std::string debuggable = base::GetAndroidProp("ro.debuggable");
49 return debuggable == "1";
Florian Mayere8599d42019-10-14 14:58:15 +010050}
51
Florian Mayer79c86842020-03-31 11:52:55 +020052bool IsUserBuild() {
Daniele Di Proietto5ce0d142021-11-01 18:30:44 +000053 std::string build_type = base::GetAndroidProp("ro.build.type");
54 return build_type == "user";
Florian Mayer79c86842020-03-31 11:52:55 +020055}
56
Florian Mayere8599d42019-10-14 14:58:15 +010057// note: cannot use gtest macros due to return type
58bool IsAppRunning(const std::string& name) {
Ryan Savitski86bd0e92020-02-24 16:42:33 +000059 std::string cmd = "pgrep -f ^" + name + "$";
Florian Mayere8599d42019-10-14 14:58:15 +010060 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
Ryan Savitski9fa72002020-02-19 14:31:20 +000070int PidForProcessName(const std::string& name) {
Ryan Savitski86bd0e92020-02-24 16:42:33 +000071 std::string cmd = "pgrep -f ^" + name + "$";
Ryan Savitski9fa72002020-02-19 14:31:20 +000072 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
Hector Dearmanec1de7d2020-02-07 16:17:40 +000087void WaitForProcess(const std::string& process,
88 const std::string& checkpoint_name,
89 base::TestTaskRunner* task_runner,
90 uint32_t delay_ms) {
Florian Mayere8599d42019-10-14 14:58:15 +010091 bool desired_run_state = true;
92 const auto checkpoint = task_runner->CreateCheckpoint(checkpoint_name);
93 task_runner->PostDelayedTask(
Hector Dearmanec1de7d2020-02-07 16:17:40 +000094 [desired_run_state, task_runner, process, checkpoint] {
95 PollRunState(desired_run_state, task_runner, process,
Florian Mayere8599d42019-10-14 14:58:15 +010096 std::move(checkpoint));
97 },
Hector Dearmanec1de7d2020-02-07 16:17:40 +000098 delay_ms);
99}
100
101void 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());
Primiano Tuccid6dc0c02020-12-01 16:15:28 +0100108 PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
Hector Dearmanec1de7d2020-02-07 16:17:40 +0000109 WaitForProcess(app_name, checkpoint_name, task_runner, delay_ms);
Florian Mayere8599d42019-10-14 14:58:15 +0100110}
111
112void 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());
Primiano Tuccid6dc0c02020-12-01 16:15:28 +0100117 PERFETTO_CHECK(status >= 0 && WEXITSTATUS(status) == 0);
Florian Mayere8599d42019-10-14 14:58:15 +0100118
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
Florian Mayerbdc48df2020-02-20 17:25:03 +0000127void StopApp(const std::string& app_name) {
Florian Mayere8599d42019-10-14 14:58:15 +0100128 std::string stop_cmd = "am force-stop " + app_name;
129 system(stop_cmd.c_str());
130}
131
132} // namespace perfetto