1bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
26f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme * Copyright (C) 2016 The Android Open Source Project
3bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
4bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
5bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * you may not use this file except in compliance with the License.
6bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * You may obtain a copy of the License at
7bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
8bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
9bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
10bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Unless required by applicable law or agreed to in writing, software
11bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
12bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * See the License for the specific language governing permissions and
14bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * limitations under the License.
15bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
1647e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme#ifndef ANDROID_OS_DUMPSTATE_UTIL_H_
1747e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme#define ANDROID_OS_DUMPSTATE_UTIL_H_
18bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
19f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme#include <cstdint>
20f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme#include <string>
21f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
226921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair/*
236921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair * Converts seconds to milliseconds.
246921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair */
256921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair#define SEC_TO_MSEC(second) (second * 1000)
266921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair
276921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair/*
286921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair * Converts milliseconds to seconds.
296921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair */
306921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair#define MSEC_TO_SEC(millisecond) (millisecond / 1000)
316921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair
3247e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemenamespace android {
3347e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemenamespace os {
3447e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemenamespace dumpstate {
356f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
36bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
3746b85da716a32f285fe1222e9978beacc8697d09Felipe Leme * Defines the Linux account that should be executing a command.
38bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
3946b85da716a32f285fe1222e9978beacc8697d09Felipe Lemeenum PrivilegeMode {
40bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    /* Explicitly change the `uid` and `gid` to be `shell`.*/
41bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    DROP_ROOT,
42bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    /* Don't change the `uid` and `gid`. */
43bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    DONT_DROP_ROOT,
44bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
45bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    SU_ROOT
46bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme};
47bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
48bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
4946b85da716a32f285fe1222e9978beacc8697d09Felipe Leme * Defines what should happen with the main output stream (`stdout` or fd) of a command.
50bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
5146b85da716a32f285fe1222e9978beacc8697d09Felipe Lemeenum OutputMode {
5246b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    /* Don't change main output. */
5346b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    NORMAL_OUTPUT,
5446b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    /* Redirect main output to `stderr`. */
55bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    REDIRECT_TO_STDERR
56bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme};
57bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
58bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
59bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Value object used to set command options.
60bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
61bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Typically constructed using a builder with chained setters. Examples:
62bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
63bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  CommandOptions::WithTimeout(20).AsRoot().Build();
64bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
65bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
66bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Although the builder could be used to dynamically set values. Example:
67bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
68bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  CommandOptions::CommandOptionsBuilder options =
69bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  CommandOptions::WithTimeout(10);
70bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  if (!is_user_build()) {
71bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *    options.AsRoot();
72bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  }
73bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *  RunCommand("command", {"args"}, options.Build());
74bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
75bda15a00929b836a53bf03473b1ec36285e5944bFelipe Lemeclass CommandOptions {
76bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme  private:
77bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    class CommandOptionsValues {
78bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme      private:
796921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair        CommandOptionsValues(int64_t timeout_ms);
80bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
816921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair        int64_t timeout_ms_;
82bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        bool always_;
8346b85da716a32f285fe1222e9978beacc8697d09Felipe Leme        PrivilegeMode account_mode_;
8446b85da716a32f285fe1222e9978beacc8697d09Felipe Leme        OutputMode output_mode_;
85bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        std::string logging_message_;
86bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
87bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        friend class CommandOptions;
88bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        friend class CommandOptionsBuilder;
89bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    };
90bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
91bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    CommandOptions(const CommandOptionsValues& values);
92bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
93bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    const CommandOptionsValues values;
94bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
95bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme  public:
96bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    class CommandOptionsBuilder {
97bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme      public:
98bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        /* Sets the command to always run, even on `dry-run` mode. */
99bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsBuilder& Always();
10046b85da716a32f285fe1222e9978beacc8697d09Felipe Leme        /* Sets the command's PrivilegeMode as `SU_ROOT` */
101bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsBuilder& AsRoot();
10248e83a152179d5fe45dbef2ec7efc509f5f3adc4Yifan Hong        /* If !IsUserBuild(), sets the command's PrivilegeMode as `SU_ROOT` */
10348e83a152179d5fe45dbef2ec7efc509f5f3adc4Yifan Hong        CommandOptionsBuilder& AsRootIfAvailable();
10446b85da716a32f285fe1222e9978beacc8697d09Felipe Leme        /* Sets the command's PrivilegeMode as `DROP_ROOT` */
105bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsBuilder& DropRoot();
10646b85da716a32f285fe1222e9978beacc8697d09Felipe Leme        /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
107bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsBuilder& RedirectStderr();
108bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        /* When not empty, logs a message before executing the command.
109bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme         * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
110bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsBuilder& Log(const std::string& message);
111bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        /* Builds the command options. */
112bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptions Build();
113bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
114bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme      private:
1156921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair        CommandOptionsBuilder(int64_t timeout_ms);
116bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        CommandOptionsValues values;
117bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme        friend class CommandOptions;
118bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    };
119bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
1206921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    /** Gets the command timeout in seconds. */
121bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    int64_t Timeout() const;
1226921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    /** Gets the command timeout in milliseconds. */
1236921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    int64_t TimeoutInMs() const;
124bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    /* Checks whether the command should always be run, even on dry-run mode. */
125bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    bool Always() const;
12646b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    /** Gets the PrivilegeMode of the command. */
12746b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    PrivilegeMode PrivilegeMode() const;
12846b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    /** Gets the OutputMode of the command. */
12946b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    OutputMode OutputMode() const;
130bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    /** Gets the logging message header, it any. */
131bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    std::string LoggingMessage() const;
132bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
1336921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    /** Creates a builder with the requied timeout in seconds. */
1346921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    static CommandOptionsBuilder WithTimeout(int64_t timeout_sec);
1356921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair
1366921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    /** Creates a builder with the requied timeout in milliseconds. */
1376921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms);
138bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
139bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    // Common options.
140bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme    static CommandOptions DEFAULT;
141f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    static CommandOptions AS_ROOT;
142f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme};
143f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
144f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme/*
145f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme * System properties helper.
146f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme */
147f029297f673ae06d219bd727a318a48b885db6fdFelipe Lemeclass PropertiesHelper {
148f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    friend class DumpstateBaseTest;
149f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
150f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme  public:
151f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    /*
152f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     * Gets whether device is running a `user` build.
153f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     */
154f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    static bool IsUserBuild();
155f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
156f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    /*
157f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     * When running in dry-run mode, skips the real dumps and just print the section headers.
158f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     *
159f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     * Useful when debugging dumpstate or other bugreport-related activities.
160f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     *
161f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
162f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme     */
163f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    static bool IsDryRun();
164f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
165f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme  private:
166f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    static std::string build_type_;
167f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    static int dry_run_;
168bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme};
169bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
170bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
171bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Forks a command, waits for it to finish, and returns its status.
172bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
173bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * |fd| file descriptor that receives the command's 'stdout'.
174f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme * |title| description of the command printed on `stdout` (or empty to skip
175f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme * description).
176bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * |full_command| array containing the command (first entry) and its arguments.
17746b85da716a32f285fe1222e9978beacc8697d09Felipe Leme *                Must contain at least one element.
178bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * |options| optional argument defining the command's behavior.
179bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
180f029297f673ae06d219bd727a318a48b885db6fdFelipe Lemeint RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
18146b85da716a32f285fe1222e9978beacc8697d09Felipe Leme                   const CommandOptions& options = CommandOptions::DEFAULT);
182bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
183bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme/*
184bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * Dumps the contents of a file into a file descriptor.
185bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme *
186bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * |fd| file descriptor where the file is dumped into.
187f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme * |title| description of the command printed on `stdout` (or empty to skip
188f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme * description).
189bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme * |path| location of the file to be dumped.
190bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme */
191f029297f673ae06d219bd727a318a48b885db6fdFelipe Lemeint DumpFileToFd(int fd, const std::string& title, const std::string& path);
192bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme
19361ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park/*
19461ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park * Finds the process id by process name.
19561ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park * |ps_name| the process name we want to search for
19661ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park */
19761ffcf73d50dbed5b52265e79bb73abf1849324dEcco Parkint GetPidByName(const std::string& ps_name);
19861ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park
19947e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme}  // namespace dumpstate
20047e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme}  // namespace os
20147e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme}  // namespace android
20247e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme
20347e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme#endif  // ANDROID_OS_DUMPSTATE_UTIL_H_
204