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 /*
     23  * Converts seconds to milliseconds.
     24  */
     25 #define SEC_TO_MSEC(second) (second * 1000)
     26 
     27 /*
     28  * Converts milliseconds to seconds.
     29  */
     30 #define MSEC_TO_SEC(millisecond) (millisecond / 1000)
     31 
     32 namespace android {
     33 namespace os {
     34 namespace dumpstate {
     35 
     36 /*
     37  * Defines the Linux account that should be executing a command.
     38  */
     39 enum PrivilegeMode {
     40     /* Explicitly change the `uid` and `gid` to be `shell`.*/
     41     DROP_ROOT,
     42     /* Don't change the `uid` and `gid`. */
     43     DONT_DROP_ROOT,
     44     /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
     45     SU_ROOT
     46 };
     47 
     48 /*
     49  * Defines what should happen with the main output stream (`stdout` or fd) of a command.
     50  */
     51 enum OutputMode {
     52     /* Don't change main output. */
     53     NORMAL_OUTPUT,
     54     /* Redirect main output to `stderr`. */
     55     REDIRECT_TO_STDERR
     56 };
     57 
     58 /*
     59  * Value object used to set command options.
     60  *
     61  * Typically constructed using a builder with chained setters. Examples:
     62  *
     63  *  CommandOptions::WithTimeout(20).AsRoot().Build();
     64  *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
     65  *
     66  * Although the builder could be used to dynamically set values. Example:
     67  *
     68  *  CommandOptions::CommandOptionsBuilder options =
     69  *  CommandOptions::WithTimeout(10);
     70  *  if (!is_user_build()) {
     71  *    options.AsRoot();
     72  *  }
     73  *  RunCommand("command", {"args"}, options.Build());
     74  */
     75 class CommandOptions {
     76   private:
     77     class CommandOptionsValues {
     78       private:
     79         CommandOptionsValues(int64_t timeout_ms);
     80 
     81         int64_t timeout_ms_;
     82         bool always_;
     83         PrivilegeMode account_mode_;
     84         OutputMode output_mode_;
     85         std::string logging_message_;
     86 
     87         friend class CommandOptions;
     88         friend class CommandOptionsBuilder;
     89     };
     90 
     91     CommandOptions(const CommandOptionsValues& values);
     92 
     93     const CommandOptionsValues values;
     94 
     95   public:
     96     class CommandOptionsBuilder {
     97       public:
     98         /* Sets the command to always run, even on `dry-run` mode. */
     99         CommandOptionsBuilder& Always();
    100         /* Sets the command's PrivilegeMode as `SU_ROOT` */
    101         CommandOptionsBuilder& AsRoot();
    102         /* If !IsUserBuild(), sets the command's PrivilegeMode as `SU_ROOT` */
    103         CommandOptionsBuilder& AsRootIfAvailable();
    104         /* Sets the command's PrivilegeMode as `DROP_ROOT` */
    105         CommandOptionsBuilder& DropRoot();
    106         /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
    107         CommandOptionsBuilder& RedirectStderr();
    108         /* When not empty, logs a message before executing the command.
    109          * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
    110         CommandOptionsBuilder& Log(const std::string& message);
    111         /* Builds the command options. */
    112         CommandOptions Build();
    113 
    114       private:
    115         CommandOptionsBuilder(int64_t timeout_ms);
    116         CommandOptionsValues values;
    117         friend class CommandOptions;
    118     };
    119 
    120     /** Gets the command timeout in seconds. */
    121     int64_t Timeout() const;
    122     /** Gets the command timeout in milliseconds. */
    123     int64_t TimeoutInMs() const;
    124     /* Checks whether the command should always be run, even on dry-run mode. */
    125     bool Always() const;
    126     /** Gets the PrivilegeMode of the command. */
    127     PrivilegeMode PrivilegeMode() const;
    128     /** Gets the OutputMode of the command. */
    129     OutputMode OutputMode() const;
    130     /** Gets the logging message header, it any. */
    131     std::string LoggingMessage() const;
    132 
    133     /** Creates a builder with the requied timeout in seconds. */
    134     static CommandOptionsBuilder WithTimeout(int64_t timeout_sec);
    135 
    136     /** Creates a builder with the requied timeout in milliseconds. */
    137     static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms);
    138 
    139     // Common options.
    140     static CommandOptions DEFAULT;
    141     static CommandOptions AS_ROOT;
    142 };
    143 
    144 /*
    145  * System properties helper.
    146  */
    147 class PropertiesHelper {
    148     friend class DumpstateBaseTest;
    149 
    150   public:
    151     /*
    152      * Gets whether device is running a `user` build.
    153      */
    154     static bool IsUserBuild();
    155 
    156     /*
    157      * When running in dry-run mode, skips the real dumps and just print the section headers.
    158      *
    159      * Useful when debugging dumpstate or other bugreport-related activities.
    160      *
    161      * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
    162      */
    163     static bool IsDryRun();
    164 
    165   private:
    166     static std::string build_type_;
    167     static int dry_run_;
    168 };
    169 
    170 /*
    171  * Forks a command, waits for it to finish, and returns its status.
    172  *
    173  * |fd| file descriptor that receives the command's 'stdout'.
    174  * |title| description of the command printed on `stdout` (or empty to skip
    175  * description).
    176  * |full_command| array containing the command (first entry) and its arguments.
    177  *                Must contain at least one element.
    178  * |options| optional argument defining the command's behavior.
    179  */
    180 int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
    181                    const CommandOptions& options = CommandOptions::DEFAULT);
    182 
    183 /*
    184  * Dumps the contents of a file into a file descriptor.
    185  *
    186  * |fd| file descriptor where the file is dumped into.
    187  * |title| description of the command printed on `stdout` (or empty to skip
    188  * description).
    189  * |path| location of the file to be dumped.
    190  */
    191 int DumpFileToFd(int fd, const std::string& title, const std::string& path);
    192 
    193 /*
    194  * Finds the process id by process name.
    195  * |ps_name| the process name we want to search for
    196  */
    197 int GetPidByName(const std::string& ps_name);
    198 
    199 }  // namespace dumpstate
    200 }  // namespace os
    201 }  // namespace android
    202 
    203 #endif  // ANDROID_OS_DUMPSTATE_UTIL_H_
    204