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