• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #ifndef ANDROID_OS_DUMPSTATE_UTIL_H_
17 #define ANDROID_OS_DUMPSTATE_UTIL_H_
18 
19 #include <cstdint>
20 #include <string>
21 
22 namespace android {
23 namespace os {
24 namespace dumpstate {
25 
26 /*
27  * Defines the Linux account that should be executing a command.
28  */
29 enum PrivilegeMode {
30     /* 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 /*
39  * Defines what should happen with the main output stream (`stdout` or fd) of a command.
40  */
41 enum OutputMode {
42     /* Don't change main output. */
43     NORMAL_OUTPUT,
44     /* Redirect main output to `stderr`. */
45     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  */
65 class CommandOptions {
66   private:
67     class CommandOptionsValues {
68       private:
69         CommandOptionsValues(int64_t timeout);
70 
71         int64_t timeout_;
72         bool always_;
73         PrivilegeMode account_mode_;
74         OutputMode output_mode_;
75         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();
90         /* Sets the command's PrivilegeMode as `SU_ROOT` */
91         CommandOptionsBuilder& AsRoot();
92         /* Sets the command's PrivilegeMode as `DROP_ROOT` */
93         CommandOptionsBuilder& DropRoot();
94         /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
95         CommandOptionsBuilder& RedirectStderr();
96         /* When not empty, logs a message before executing the command.
97          * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
98         CommandOptionsBuilder& Log(const std::string& message);
99         /* Builds the command options. */
100         CommandOptions Build();
101 
102       private:
103         CommandOptionsBuilder(int64_t timeout);
104         CommandOptionsValues values;
105         friend class CommandOptions;
106     };
107 
108     /** Gets the command timeout, in seconds. */
109     int64_t Timeout() const;
110     /* Checks whether the command should always be run, even on dry-run mode. */
111     bool Always() const;
112     /** Gets the PrivilegeMode of the command. */
113     PrivilegeMode PrivilegeMode() const;
114     /** Gets the OutputMode of the command. */
115     OutputMode OutputMode() const;
116     /** Gets the logging message header, it any. */
117     std::string LoggingMessage() const;
118 
119     /** Creates a builder with the requied timeout. */
120     static CommandOptionsBuilder WithTimeout(int64_t timeout);
121 
122     // Common options.
123     static CommandOptions DEFAULT;
124     static CommandOptions AS_ROOT;
125 };
126 
127 /*
128  * System properties helper.
129  */
130 class PropertiesHelper {
131     friend class DumpstateBaseTest;
132 
133   public:
134     /*
135      * Gets whether device is running a `user` build.
136      */
137     static bool IsUserBuild();
138 
139     /*
140      * When running in dry-run mode, skips the real dumps and just print the section headers.
141      *
142      * Useful when debugging dumpstate or other bugreport-related activities.
143      *
144      * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
145      */
146     static bool IsDryRun();
147 
148   private:
149     static std::string build_type_;
150     static int dry_run_;
151 };
152 
153 /*
154  * Forks a command, waits for it to finish, and returns its status.
155  *
156  * |fd| file descriptor that receives the command's 'stdout'.
157  * |title| description of the command printed on `stdout` (or empty to skip
158  * description).
159  * |full_command| array containing the command (first entry) and its arguments.
160  *                Must contain at least one element.
161  * |options| optional argument defining the command's behavior.
162  */
163 int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
164                    const CommandOptions& options = CommandOptions::DEFAULT);
165 
166 /*
167  * Dumps the contents of a file into a file descriptor.
168  *
169  * |fd| file descriptor where the file is dumped into.
170  * |title| description of the command printed on `stdout` (or empty to skip
171  * description).
172  * |path| location of the file to be dumped.
173  */
174 int DumpFileToFd(int fd, const std::string& title, const std::string& path);
175 
176 /*
177  * Finds the process id by process name.
178  * |ps_name| the process name we want to search for
179  */
180 int GetPidByName(const std::string& ps_name);
181 
182 }  // namespace dumpstate
183 }  // namespace os
184 }  // namespace android
185 
186 #endif  // ANDROID_OS_DUMPSTATE_UTIL_H_
187