Home | History | Annotate | Download | only in dumpstate
      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