DumpstateUtil.h revision 47e9be2d71c5eca9002e289c98e8bbc20dffc073
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
22namespace android {
23namespace os {
24namespace dumpstate {
25
26/*
27 * Defines the Linux account that should be executing a command.
28 */
29enum 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 */
41enum 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 */
65class 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 */
130class 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 */
163int 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 */
174int 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 */
180int 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