blob: 698ceffcc40e9ae28069d66a8c48705bbc461b31 [file] [log] [blame]
Felipe Lemebda15a02016-11-16 17:48:25 -08001/*
Felipe Leme6f674ae2016-11-18 17:10:33 -08002 * Copyright (C) 2016 The Android Open Source Project
Felipe Lemebda15a02016-11-16 17:48:25 -08003 *
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 */
Felipe Leme47e9be22016-12-21 15:37:07 -080016#ifndef ANDROID_OS_DUMPSTATE_UTIL_H_
17#define ANDROID_OS_DUMPSTATE_UTIL_H_
Felipe Lemebda15a02016-11-16 17:48:25 -080018
Felipe Lemef0292972016-11-22 13:57:05 -080019#include <cstdint>
20#include <string>
21
Felipe Leme47e9be22016-12-21 15:37:07 -080022namespace android {
23namespace os {
24namespace dumpstate {
Felipe Leme6f674ae2016-11-18 17:10:33 -080025
Felipe Lemebda15a02016-11-16 17:48:25 -080026/*
Felipe Leme46b85da2016-11-21 17:40:45 -080027 * Defines the Linux account that should be executing a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080028 */
Felipe Leme46b85da2016-11-21 17:40:45 -080029enum PrivilegeMode {
Felipe Lemebda15a02016-11-16 17:48:25 -080030 /* Explicitly change the `uid` and `gid` to be `shell`.*/
31 DROP_ROOT,
32 /* Don't change the `uid` and `gid`. */
33 DONT_DROP_ROOT,
34 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
35 SU_ROOT
36};
37
38/*
Felipe Leme46b85da2016-11-21 17:40:45 -080039 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080040 */
Felipe Leme46b85da2016-11-21 17:40:45 -080041enum OutputMode {
42 /* Don't change main output. */
43 NORMAL_OUTPUT,
44 /* Redirect main output to `stderr`. */
Felipe Lemebda15a02016-11-16 17:48:25 -080045 REDIRECT_TO_STDERR
46};
47
48/*
49 * Value object used to set command options.
50 *
51 * Typically constructed using a builder with chained setters. Examples:
52 *
53 * CommandOptions::WithTimeout(20).AsRoot().Build();
54 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
55 *
56 * Although the builder could be used to dynamically set values. Example:
57 *
58 * CommandOptions::CommandOptionsBuilder options =
59 * CommandOptions::WithTimeout(10);
60 * if (!is_user_build()) {
61 * options.AsRoot();
62 * }
63 * RunCommand("command", {"args"}, options.Build());
64 */
65class CommandOptions {
66 private:
67 class CommandOptionsValues {
68 private:
69 CommandOptionsValues(int64_t timeout);
70
71 int64_t timeout_;
72 bool always_;
Felipe Leme46b85da2016-11-21 17:40:45 -080073 PrivilegeMode account_mode_;
74 OutputMode output_mode_;
Felipe Lemebda15a02016-11-16 17:48:25 -080075 std::string logging_message_;
76
77 friend class CommandOptions;
78 friend class CommandOptionsBuilder;
79 };
80
81 CommandOptions(const CommandOptionsValues& values);
82
83 const CommandOptionsValues values;
84
85 public:
86 class CommandOptionsBuilder {
87 public:
88 /* Sets the command to always run, even on `dry-run` mode. */
89 CommandOptionsBuilder& Always();
Felipe Leme46b85da2016-11-21 17:40:45 -080090 /* Sets the command's PrivilegeMode as `SU_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080091 CommandOptionsBuilder& AsRoot();
Yifan Hong48e83a12017-10-03 14:10:07 -070092 /* If !IsUserBuild(), sets the command's PrivilegeMode as `SU_ROOT` */
93 CommandOptionsBuilder& AsRootIfAvailable();
Felipe Leme46b85da2016-11-21 17:40:45 -080094 /* Sets the command's PrivilegeMode as `DROP_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080095 CommandOptionsBuilder& DropRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -080096 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
Felipe Lemebda15a02016-11-16 17:48:25 -080097 CommandOptionsBuilder& RedirectStderr();
98 /* When not empty, logs a message before executing the command.
99 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
100 CommandOptionsBuilder& Log(const std::string& message);
101 /* Builds the command options. */
102 CommandOptions Build();
103
104 private:
105 CommandOptionsBuilder(int64_t timeout);
106 CommandOptionsValues values;
107 friend class CommandOptions;
108 };
109
110 /** Gets the command timeout, in seconds. */
111 int64_t Timeout() const;
112 /* Checks whether the command should always be run, even on dry-run mode. */
113 bool Always() const;
Felipe Leme46b85da2016-11-21 17:40:45 -0800114 /** Gets the PrivilegeMode of the command. */
115 PrivilegeMode PrivilegeMode() const;
116 /** Gets the OutputMode of the command. */
117 OutputMode OutputMode() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800118 /** Gets the logging message header, it any. */
119 std::string LoggingMessage() const;
120
121 /** Creates a builder with the requied timeout. */
122 static CommandOptionsBuilder WithTimeout(int64_t timeout);
123
124 // Common options.
125 static CommandOptions DEFAULT;
Felipe Lemef0292972016-11-22 13:57:05 -0800126 static CommandOptions AS_ROOT;
Felipe Lemef0292972016-11-22 13:57:05 -0800127};
128
129/*
130 * System properties helper.
131 */
132class PropertiesHelper {
133 friend class DumpstateBaseTest;
134
135 public:
136 /*
137 * Gets whether device is running a `user` build.
138 */
139 static bool IsUserBuild();
140
141 /*
142 * When running in dry-run mode, skips the real dumps and just print the section headers.
143 *
144 * Useful when debugging dumpstate or other bugreport-related activities.
145 *
146 * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
147 */
148 static bool IsDryRun();
149
150 private:
151 static std::string build_type_;
152 static int dry_run_;
Felipe Lemebda15a02016-11-16 17:48:25 -0800153};
154
155/*
156 * Forks a command, waits for it to finish, and returns its status.
157 *
158 * |fd| file descriptor that receives the command's 'stdout'.
Felipe Lemef0292972016-11-22 13:57:05 -0800159 * |title| description of the command printed on `stdout` (or empty to skip
160 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800161 * |full_command| array containing the command (first entry) and its arguments.
Felipe Leme46b85da2016-11-21 17:40:45 -0800162 * Must contain at least one element.
Felipe Lemebda15a02016-11-16 17:48:25 -0800163 * |options| optional argument defining the command's behavior.
Felipe Lemebda15a02016-11-16 17:48:25 -0800164 */
Felipe Lemef0292972016-11-22 13:57:05 -0800165int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -0800166 const CommandOptions& options = CommandOptions::DEFAULT);
Felipe Lemebda15a02016-11-16 17:48:25 -0800167
168/*
169 * Dumps the contents of a file into a file descriptor.
170 *
171 * |fd| file descriptor where the file is dumped into.
Felipe Lemef0292972016-11-22 13:57:05 -0800172 * |title| description of the command printed on `stdout` (or empty to skip
173 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800174 * |path| location of the file to be dumped.
175 */
Felipe Lemef0292972016-11-22 13:57:05 -0800176int DumpFileToFd(int fd, const std::string& title, const std::string& path);
Felipe Lemebda15a02016-11-16 17:48:25 -0800177
Ecco Park61ffcf72016-10-27 15:46:26 -0700178/*
179 * Finds the process id by process name.
180 * |ps_name| the process name we want to search for
181 */
182int GetPidByName(const std::string& ps_name);
183
Felipe Leme47e9be22016-12-21 15:37:07 -0800184} // namespace dumpstate
185} // namespace os
186} // namespace android
187
188#endif // ANDROID_OS_DUMPSTATE_UTIL_H_