/*
 ** Copyright 2016, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

#include <algorithm>
#include <inttypes.h>
#include <limits>
#include <random>
#include <regex>
#include <selinux/android.h>
#include <selinux/avc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/fs.h>
#include <cutils/properties.h>
#include <dex2oat_return_codes.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>

#include "dexopt.h"
#include "file_parsing.h"
#include "globals.h"
#include "installd_constants.h"
#include "installd_deps.h"  // Need to fill in requirements of commands.
#include "otapreopt_utils.h"
#include "system_properties.h"
#include "utils.h"

#ifndef LOG_TAG
#define LOG_TAG "otapreopt"
#endif

#define BUFFER_MAX    1024  /* input buffer for commands */
#define TOKEN_MAX     16    /* max number of arguments in buffer */
#define REPLY_MAX     256   /* largest reply allowed */

using android::base::EndsWith;
using android::base::Join;
using android::base::Split;
using android::base::StartsWith;
using android::base::StringPrintf;

namespace android {
namespace installd {

// Check expected values for dexopt flags. If you need to change this:
//
//   RUN AN A/B OTA TO MAKE SURE THINGS STILL WORK!
//
// You most likely need to increase the protocol version and all that entails!

static_assert(DEXOPT_PUBLIC         == 1 << 1, "DEXOPT_PUBLIC unexpected.");
static_assert(DEXOPT_DEBUGGABLE     == 1 << 2, "DEXOPT_DEBUGGABLE unexpected.");
static_assert(DEXOPT_BOOTCOMPLETE   == 1 << 3, "DEXOPT_BOOTCOMPLETE unexpected.");
static_assert(DEXOPT_PROFILE_GUIDED == 1 << 4, "DEXOPT_PROFILE_GUIDED unexpected.");
static_assert(DEXOPT_SECONDARY_DEX  == 1 << 5, "DEXOPT_SECONDARY_DEX unexpected.");
static_assert(DEXOPT_FORCE          == 1 << 6, "DEXOPT_FORCE unexpected.");
static_assert(DEXOPT_STORAGE_CE     == 1 << 7, "DEXOPT_STORAGE_CE unexpected.");
static_assert(DEXOPT_STORAGE_DE     == 1 << 8, "DEXOPT_STORAGE_DE unexpected.");

static_assert(DEXOPT_MASK           == 0x1fe, "DEXOPT_MASK unexpected.");



template<typename T>
static constexpr T RoundDown(T x, typename std::decay<T>::type n) {
    return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n);
}

template<typename T>
static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
    return RoundDown(x + n - 1, n);
}

class OTAPreoptService {
 public:
    // Main driver. Performs the following steps.
    //
    // 1) Parse options (read system properties etc from B partition).
    //
    // 2) Read in package data.
    //
    // 3) Prepare environment variables.
    //
    // 4) Prepare(compile) boot image, if necessary.
    //
    // 5) Run update.
    int Main(int argc, char** argv) {
        if (!ReadArguments(argc, argv)) {
            LOG(ERROR) << "Failed reading command line.";
            return 1;
        }

        if (!ReadSystemProperties()) {
            LOG(ERROR)<< "Failed reading system properties.";
            return 2;
        }

        if (!ReadEnvironment()) {
            LOG(ERROR) << "Failed reading environment properties.";
            return 3;
        }

        if (!CheckAndInitializeInstalldGlobals()) {
            LOG(ERROR) << "Failed initializing globals.";
            return 4;
        }

        PrepareEnvironment();

        if (!PrepareBootImage(/* force */ false)) {
            LOG(ERROR) << "Failed preparing boot image.";
            return 5;
        }

        int dexopt_retcode = RunPreopt();

        return dexopt_retcode;
    }

    int GetProperty(const char* key, char* value, const char* default_value) const {
        const std::string* prop_value = system_properties_.GetProperty(key);
        if (prop_value == nullptr) {
            if (default_value == nullptr) {
                return 0;
            }
            // Copy in the default value.
            strncpy(value, default_value, kPropertyValueMax - 1);
            value[kPropertyValueMax - 1] = 0;
            return strlen(default_value);// TODO: Need to truncate?
        }
        size_t size = std::min(kPropertyValueMax - 1, prop_value->length());
        strncpy(value, prop_value->data(), size);
        value[size] = 0;
        return static_cast<int>(size);
    }

    std::string GetOTADataDirectory() const {
        return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str());
    }

    const std::string& GetTargetSlot() const {
        return target_slot_;
    }

private:

    struct Parameters {
        const char *apk_path;
        uid_t uid;
        const char *pkgName;
        const char *instruction_set;
        int dexopt_needed;
        const char* oat_dir;
        int dexopt_flags;
        const char* compiler_filter;
        const char* volume_uuid;
        const char* shared_libraries;
        const char* se_info;
        bool downgrade;
    };

    bool ReadSystemProperties() {
        static constexpr const char* kPropertyFiles[] = {
                "/default.prop", "/system/build.prop"
        };

        for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) {
            if (!system_properties_.Load(kPropertyFiles[i])) {
                return false;
            }
        }

        return true;
    }

    bool ReadEnvironment() {
        // Parse the environment variables from init.environ.rc, which have the form
        //   export NAME VALUE
        // For simplicity, don't respect string quotation. The values we are interested in can be
        // encoded without them.
        std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)");
        bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) {
            std::smatch export_match;
            if (!std::regex_match(line, export_match, export_regex)) {
                return true;
            }

            if (export_match.size() != 3) {
                return true;
            }

            std::string name = export_match[1].str();
            std::string value = export_match[2].str();

            system_properties_.SetProperty(name, value);

            return true;
        });
        if (!parse_result) {
            return false;
        }

        if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) {
            return false;
        }
        android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName);

        if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) {
            return false;
        }
        android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName);

        if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) {
            return false;
        }
        boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName);

        if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) {
            return false;
        }
        asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME);

        return true;
    }

    const std::string& GetAndroidData() const {
        return android_data_;
    }

    const std::string& GetAndroidRoot() const {
        return android_root_;
    }

    const std::string GetOtaDirectoryPrefix() const {
        return GetAndroidData() + "/ota";
    }

    bool CheckAndInitializeInstalldGlobals() {
        // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We
        // do not use any datapath that includes this, but we'll still have to set it.
        CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr);
        int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0);
        if (result != 0) {
            LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable";
            return false;
        }

        if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) {
            LOG(ERROR) << "Could not initialize globals; exiting.";
            return false;
        }

        // This is different from the normal installd. We only do the base
        // directory, the rest will be created on demand when each app is compiled.
        if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) {
            LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix();
            return false;
        }

        return true;
    }

    bool ParseBool(const char* in) {
        if (strcmp(in, "true") == 0) {
            return true;
        }
        return false;
    }

    bool ParseUInt(const char* in, uint32_t* out) {
        char* end;
        long long int result = strtoll(in, &end, 0);
        if (in == end || *end != '\0') {
            return false;
        }
        if (result < std::numeric_limits<uint32_t>::min() ||
                std::numeric_limits<uint32_t>::max() < result) {
            return false;
        }
        *out = static_cast<uint32_t>(result);
        return true;
    }

    bool ReadArguments(int argc, char** argv) {
        // Expected command line:
        //   target-slot [version] dexopt {DEXOPT_PARAMETERS}

        const char* target_slot_arg = argv[1];
        if (target_slot_arg == nullptr) {
            LOG(ERROR) << "Missing parameters";
            return false;
        }
        // Sanitize value. Only allow (a-zA-Z0-9_)+.
        target_slot_ = target_slot_arg;
        if (!ValidateTargetSlotSuffix(target_slot_)) {
            LOG(ERROR) << "Target slot suffix not legal: " << target_slot_;
            return false;
        }

        // Check for version or "dexopt" next.
        if (argv[2] == nullptr) {
            LOG(ERROR) << "Missing parameters";
            return false;
        }

        if (std::string("dexopt").compare(argv[2]) == 0) {
            // This is version 1 (N) or pre-versioning version 2.
            constexpr int kV2ArgCount =   1   // "otapreopt"
                                        + 1   // slot
                                        + 1   // "dexopt"
                                        + 1   // apk_path
                                        + 1   // uid
                                        + 1   // pkg
                                        + 1   // isa
                                        + 1   // dexopt_needed
                                        + 1   // oat_dir
                                        + 1   // dexopt_flags
                                        + 1   // filter
                                        + 1   // volume
                                        + 1   // libs
                                        + 1;  // seinfo
            if (argc == kV2ArgCount) {
                return ReadArgumentsV2(argc, argv, false);
            } else {
                return ReadArgumentsV1(argc, argv);
            }
        }

        uint32_t version;
        if (!ParseUInt(argv[2], &version)) {
            LOG(ERROR) << "Could not parse version: " << argv[2];
            return false;
        }

        switch (version) {
            case 2:
                return ReadArgumentsV2(argc, argv, true);
            case 3:
                return ReadArgumentsV3(argc, argv);

            default:
                LOG(ERROR) << "Unsupported version " << version;
                return false;
        }
    }

    bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) {
        size_t dexopt_index = versioned ? 3 : 2;

        // Check for "dexopt".
        if (argv[dexopt_index] == nullptr) {
            LOG(ERROR) << "Missing parameters";
            return false;
        }
        if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
            LOG(ERROR) << "Expected \"dexopt\"";
            return false;
        }

        size_t param_index = 0;
        for (;; ++param_index) {
            const char* param = argv[dexopt_index + 1 + param_index];
            if (param == nullptr) {
                break;
            }

            switch (param_index) {
                case 0:
                    package_parameters_.apk_path = param;
                    break;

                case 1:
                    package_parameters_.uid = atoi(param);
                    break;

                case 2:
                    package_parameters_.pkgName = param;
                    break;

                case 3:
                    package_parameters_.instruction_set = param;
                    break;

                case 4:
                    package_parameters_.dexopt_needed = atoi(param);
                    break;

                case 5:
                    package_parameters_.oat_dir = param;
                    break;

                case 6:
                    package_parameters_.dexopt_flags = atoi(param);
                    break;

                case 7:
                    package_parameters_.compiler_filter = param;
                    break;

                case 8:
                    package_parameters_.volume_uuid = ParseNull(param);
                    break;

                case 9:
                    package_parameters_.shared_libraries = ParseNull(param);
                    break;

                case 10:
                    package_parameters_.se_info = ParseNull(param);
                    break;

                default:
                    LOG(ERROR) << "Too many arguments, got " << param;
                    return false;
            }
        }

        // Set downgrade to false. It is only relevant when downgrading compiler
        // filter, which is not the case during ota.
        package_parameters_.downgrade = false;

        if (param_index != 11) {
            LOG(ERROR) << "Not enough parameters";
            return false;
        }

        return true;
    }

    bool ReadArgumentsV3(int argc ATTRIBUTE_UNUSED, char** argv) {
        size_t dexopt_index = 3;

        // Check for "dexopt".
        if (argv[dexopt_index] == nullptr) {
            LOG(ERROR) << "Missing parameters";
            return false;
        }
        if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
            LOG(ERROR) << "Expected \"dexopt\"";
            return false;
        }

        size_t param_index = 0;
        for (;; ++param_index) {
            const char* param = argv[dexopt_index + 1 + param_index];
            if (param == nullptr) {
                break;
            }

            switch (param_index) {
                case 0:
                    package_parameters_.apk_path = param;
                    break;

                case 1:
                    package_parameters_.uid = atoi(param);
                    break;

                case 2:
                    package_parameters_.pkgName = param;
                    break;

                case 3:
                    package_parameters_.instruction_set = param;
                    break;

                case 4:
                    package_parameters_.dexopt_needed = atoi(param);
                    break;

                case 5:
                    package_parameters_.oat_dir = param;
                    break;

                case 6:
                    package_parameters_.dexopt_flags = atoi(param);
                    break;

                case 7:
                    package_parameters_.compiler_filter = param;
                    break;

                case 8:
                    package_parameters_.volume_uuid = ParseNull(param);
                    break;

                case 9:
                    package_parameters_.shared_libraries = ParseNull(param);
                    break;

                case 10:
                    package_parameters_.se_info = ParseNull(param);
                    break;

                case 11:
                    package_parameters_.downgrade = ParseBool(param);
                    break;

                default:
                    LOG(ERROR) << "Too many arguments, got " << param;
                    return false;
            }
        }

        if (param_index != 12) {
            LOG(ERROR) << "Not enough parameters";
            return false;
        }

        return true;
    }

    static int ReplaceMask(int input, int old_mask, int new_mask) {
        return (input & old_mask) != 0 ? new_mask : 0;
    }

    bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) {
        // Check for "dexopt".
        if (argv[2] == nullptr) {
            LOG(ERROR) << "Missing parameters";
            return false;
        }
        if (std::string("dexopt").compare(argv[2]) != 0) {
            LOG(ERROR) << "Expected \"dexopt\"";
            return false;
        }

        size_t param_index = 0;
        for (;; ++param_index) {
            const char* param = argv[3 + param_index];
            if (param == nullptr) {
                break;
            }

            switch (param_index) {
                case 0:
                    package_parameters_.apk_path = param;
                    break;

                case 1:
                    package_parameters_.uid = atoi(param);
                    break;

                case 2:
                    package_parameters_.pkgName = param;
                    break;

                case 3:
                    package_parameters_.instruction_set = param;
                    break;

                case 4: {
                    // Version 1 had:
                    //   DEXOPT_DEX2OAT_NEEDED       = 1
                    //   DEXOPT_PATCHOAT_NEEDED      = 2
                    //   DEXOPT_SELF_PATCHOAT_NEEDED = 3
                    // We will simply use DEX2OAT_FROM_SCRATCH.
                    package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH;
                    break;
                }

                case 5:
                    package_parameters_.oat_dir = param;
                    break;

                case 6: {
                    // Version 1 had:
                    constexpr int OLD_DEXOPT_PUBLIC         = 1 << 1;
                    // Note: DEXOPT_SAFEMODE has been removed.
                    // constexpr int OLD_DEXOPT_SAFEMODE       = 1 << 2;
                    constexpr int OLD_DEXOPT_DEBUGGABLE     = 1 << 3;
                    constexpr int OLD_DEXOPT_BOOTCOMPLETE   = 1 << 4;
                    constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
                    constexpr int OLD_DEXOPT_OTA            = 1 << 6;
                    int input = atoi(param);
                    package_parameters_.dexopt_flags =
                            ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
                            ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
                            ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
                            ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) |
                            ReplaceMask(input, OLD_DEXOPT_OTA, 0);
                    break;
                }

                case 7:
                    package_parameters_.compiler_filter = param;
                    break;

                case 8:
                    package_parameters_.volume_uuid = ParseNull(param);
                    break;

                case 9:
                    package_parameters_.shared_libraries = ParseNull(param);
                    break;

                default:
                    LOG(ERROR) << "Too many arguments, got " << param;
                    return false;
            }
        }

        if (param_index != 10) {
            LOG(ERROR) << "Not enough parameters";
            return false;
        }

        // Set se_info to null. It is only relevant for secondary dex files, which we won't
        // receive from a v1 A side.
        package_parameters_.se_info = nullptr;

        // Set downgrade to false. It is only relevant when downgrading compiler
        // filter, which is not the case during ota.
        package_parameters_.downgrade = false;

        return true;
    }

    void PrepareEnvironment() {
        environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str()));
        environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str()));
        environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str()));

        for (const std::string& e : environ_) {
            putenv(const_cast<char*>(e.c_str()));
        }
    }

    // Ensure that we have the right boot image. The first time any app is
    // compiled, we'll try to generate it.
    bool PrepareBootImage(bool force) const {
        if (package_parameters_.instruction_set == nullptr) {
            LOG(ERROR) << "Instruction set missing.";
            return false;
        }
        const char* isa = package_parameters_.instruction_set;

        // Check whether the file exists where expected.
        std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE;
        std::string isa_path = dalvik_cache + "/" + isa;
        std::string art_path = isa_path + "/system@framework@boot.art";
        std::string oat_path = isa_path + "/system@framework@boot.oat";
        bool cleared = false;
        if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
            // Files exist, assume everything is alright if not forced. Otherwise clean up.
            if (!force) {
                return true;
            }
            ClearDirectory(isa_path);
            cleared = true;
        }

        // Reset umask in otapreopt, so that we control the the access for the files we create.
        umask(0);

        // Create the directories, if necessary.
        if (access(dalvik_cache.c_str(), F_OK) != 0) {
            if (!CreatePath(dalvik_cache)) {
                PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache;
                return false;
            }
        }
        if (access(isa_path.c_str(), F_OK) != 0) {
            if (!CreatePath(isa_path)) {
                PLOG(ERROR) << "Could not create dalvik-cache isa dir";
                return false;
            }
        }

        // Prepare to create.
        if (!cleared) {
            ClearDirectory(isa_path);
        }

        std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
        if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
          return PatchoatBootImage(art_path, isa);
        } else {
          // No preopted boot image. Try to compile.
          return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
        }
    }

    static bool CreatePath(const std::string& path) {
        // Create the given path. Use string processing instead of dirname, as dirname's need for
        // a writable char buffer is painful.

        // First, try to use the full path.
        if (mkdir(path.c_str(), 0711) == 0) {
            return true;
        }
        if (errno != ENOENT) {
            PLOG(ERROR) << "Could not create path " << path;
            return false;
        }

        // Now find the parent and try that first.
        size_t last_slash = path.find_last_of('/');
        if (last_slash == std::string::npos || last_slash == 0) {
            PLOG(ERROR) << "Could not create " << path;
            return false;
        }

        if (!CreatePath(path.substr(0, last_slash))) {
            return false;
        }

        if (mkdir(path.c_str(), 0711) == 0) {
            return true;
        }
        PLOG(ERROR) << "Could not create " << path;
        return false;
    }

    static void ClearDirectory(const std::string& dir) {
        DIR* c_dir = opendir(dir.c_str());
        if (c_dir == nullptr) {
            PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents";
            return;
        }

        for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
            const char* name = de->d_name;
            if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
                continue;
            }
            // We only want to delete regular files and symbolic links.
            std::string file = StringPrintf("%s/%s", dir.c_str(), name);
            if (de->d_type != DT_REG && de->d_type != DT_LNK) {
                LOG(WARNING) << "Unexpected file "
                             << file
                             << " of type "
                             << std::hex
                             << de->d_type
                             << " encountered.";
            } else {
                // Try to unlink the file.
                if (unlink(file.c_str()) != 0) {
                    PLOG(ERROR) << "Unable to unlink " << file;
                }
            }
        }
        CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
    }

    bool PatchoatBootImage(const std::string& art_path, const char* isa) const {
        // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.

        std::vector<std::string> cmd;
        cmd.push_back("/system/bin/patchoat");

        cmd.push_back("--input-image-location=/system/framework/boot.art");
        cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str()));

        cmd.push_back(StringPrintf("--instruction-set=%s", isa));

        int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
                                                          ART_BASE_ADDRESS_MAX_DELTA);
        cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset));

        std::string error_msg;
        bool result = Exec(cmd, &error_msg);
        if (!result) {
            LOG(ERROR) << "Could not generate boot image: " << error_msg;
        }
        return result;
    }

    bool Dex2oatBootImage(const std::string& boot_cp,
                          const std::string& art_path,
                          const std::string& oat_path,
                          const char* isa) const {
        // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
        std::vector<std::string> cmd;
        cmd.push_back("/system/bin/dex2oat");
        cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
        for (const std::string& boot_part : Split(boot_cp, ":")) {
            cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
        }
        cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str()));

        int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
                ART_BASE_ADDRESS_MAX_DELTA);
        cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset));

        cmd.push_back(StringPrintf("--instruction-set=%s", isa));

        // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp.
        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms",
                "-Xms",
                true,
                cmd);
        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx",
                "-Xmx",
                true,
                cmd);
        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter",
                "--compiler-filter=",
                false,
                cmd);
        cmd.push_back("--image-classes=/system/etc/preloaded-classes");
        // TODO: Compiled-classes.
        const std::string* extra_opts =
                system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
        if (extra_opts != nullptr) {
            std::vector<std::string> extra_vals = Split(*extra_opts, " ");
            cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end());
        }
        // TODO: Should we lower this? It's usually set close to max, because
        //       normally there's not much else going on at boot.
        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads",
                "-j",
                false,
                cmd);
        AddCompilerOptionFromSystemProperty(
                StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(),
                "--instruction-set-variant=",
                false,
                cmd);
        AddCompilerOptionFromSystemProperty(
                StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(),
                "--instruction-set-features=",
                false,
                cmd);

        std::string error_msg;
        bool result = Exec(cmd, &error_msg);
        if (!result) {
            LOG(ERROR) << "Could not generate boot image: " << error_msg;
        }
        return result;
    }

    static const char* ParseNull(const char* arg) {
        return (strcmp(arg, "!") == 0) ? nullptr : arg;
    }

    bool ShouldSkipPreopt() const {
        // There's one thing we have to be careful about: we may/will be asked to compile an app
        // living in the system image. This may be a valid request - if the app wasn't compiled,
        // e.g., if the system image wasn't large enough to include preopted files. However, the
        // data we have is from the old system, so the driver (the OTA service) can't actually
        // know. Thus, we will get requests for apps that have preopted components. To avoid
        // duplication (we'd generate files that are not used and are *not* cleaned up), do two
        // simple checks:
        //
        // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image)
        //    (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.)
        //
        // 2) If you replace the name in the apk_path with "oat," does the path exist?
        //    (=have a subdirectory for preopted files)
        //
        // If the answer to both is yes, skip the dexopt.
        //
        // Note: while one may think it's OK to call dexopt and it will fail (because APKs should
        //       be stripped), that's not true for APKs signed outside the build system (so the
        //       jar content must be exactly the same).

        //       (This is ugly as it's the only thing where we need to understand the contents
        //        of package_parameters_, but it beats postponing the decision or using the call-
        //        backs to do weird things.)
        const char* apk_path = package_parameters_.apk_path;
        CHECK(apk_path != nullptr);
        if (StartsWith(apk_path, android_root_.c_str())) {
            const char* last_slash = strrchr(apk_path, '/');
            if (last_slash != nullptr) {
                std::string path(apk_path, last_slash - apk_path + 1);
                CHECK(EndsWith(path, "/"));
                path = path + "oat";
                if (access(path.c_str(), F_OK) == 0) {
                    return true;
                }
            }
        }

        // Another issue is unavailability of files in the new system. If the partition
        // layout changes, otapreopt_chroot may not know about this. Then files from that
        // partition will not be available and fail to build. This is problematic, as
        // this tool will wipe the OTA artifact cache and try again (for robustness after
        // a failed OTA with remaining cache artifacts).
        if (access(apk_path, F_OK) != 0) {
            LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path;
            return true;
        }

        return false;
    }

    // Run dexopt with the parameters of package_parameters_.
    int Dexopt() {
        return dexopt(package_parameters_.apk_path,
                      package_parameters_.uid,
                      package_parameters_.pkgName,
                      package_parameters_.instruction_set,
                      package_parameters_.dexopt_needed,
                      package_parameters_.oat_dir,
                      package_parameters_.dexopt_flags,
                      package_parameters_.compiler_filter,
                      package_parameters_.volume_uuid,
                      package_parameters_.shared_libraries,
                      package_parameters_.se_info,
                      package_parameters_.downgrade);
    }

    int RunPreopt() {
        if (ShouldSkipPreopt()) {
            return 0;
        }

        int dexopt_result = Dexopt();
        if (dexopt_result == 0) {
            return 0;
        }

        // If the dexopt failed, we may have a stale boot image from a previous OTA run.
        // Then regenerate and retry.
        if (WEXITSTATUS(dexopt_result) ==
                static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
            if (!PrepareBootImage(/* force */ true)) {
                LOG(ERROR) << "Forced boot image creating failed. Original error return was "
                        << dexopt_result;
                return dexopt_result;
            }

            int dexopt_result_boot_image_retry = Dexopt();
            if (dexopt_result_boot_image_retry == 0) {
                return 0;
            }
        }

        // If this was a profile-guided run, we may have profile version issues. Try to downgrade,
        // if possible.
        if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) {
            return dexopt_result;
        }

        LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation";
        package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED;
        return Dexopt();
    }

    ////////////////////////////////////
    // Helpers, mostly taken from ART //
    ////////////////////////////////////

    // Wrapper on fork/execv to run a command in a subprocess.
    static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) {
        const std::string command_line = Join(arg_vector, ' ');

        CHECK_GE(arg_vector.size(), 1U) << command_line;

        // Convert the args to char pointers.
        const char* program = arg_vector[0].c_str();
        std::vector<char*> args;
        for (size_t i = 0; i < arg_vector.size(); ++i) {
            const std::string& arg = arg_vector[i];
            char* arg_str = const_cast<char*>(arg.c_str());
            CHECK(arg_str != nullptr) << i;
            args.push_back(arg_str);
        }
        args.push_back(nullptr);

        // Fork and exec.
        pid_t pid = fork();
        if (pid == 0) {
            // No allocation allowed between fork and exec.

            // Change process groups, so we don't get reaped by ProcessManager.
            setpgid(0, 0);

            execv(program, &args[0]);

            PLOG(ERROR) << "Failed to execv(" << command_line << ")";
            // _exit to avoid atexit handlers in child.
            _exit(1);
        } else {
            if (pid == -1) {
                *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
                        command_line.c_str(), strerror(errno));
                return false;
            }

            // wait for subprocess to finish
            int status;
            pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
            if (got_pid != pid) {
                *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
                        "wanted %d, got %d: %s",
                        command_line.c_str(), pid, got_pid, strerror(errno));
                return false;
            }
            if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
                *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
                        command_line.c_str());
                return false;
            }
        }
        return true;
    }

    // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc.
    static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
        constexpr size_t kPageSize = PAGE_SIZE;
        CHECK_EQ(min_delta % kPageSize, 0u);
        CHECK_EQ(max_delta % kPageSize, 0u);
        CHECK_LT(min_delta, max_delta);

        std::default_random_engine generator;
        generator.seed(GetSeed());
        std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
        int32_t r = distribution(generator);
        if (r % 2 == 0) {
            r = RoundUp(r, kPageSize);
        } else {
            r = RoundDown(r, kPageSize);
        }
        CHECK_LE(min_delta, r);
        CHECK_GE(max_delta, r);
        CHECK_EQ(r % kPageSize, 0u);
        return r;
    }

    static uint64_t GetSeed() {
#ifdef __BIONIC__
        // Bionic exposes arc4random, use it.
        uint64_t random_data;
        arc4random_buf(&random_data, sizeof(random_data));
        return random_data;
#else
#error "This is only supposed to run with bionic. Otherwise, implement..."
#endif
    }

    void AddCompilerOptionFromSystemProperty(const char* system_property,
            const char* prefix,
            bool runtime,
            std::vector<std::string>& out) const {
        const std::string* value = system_properties_.GetProperty(system_property);
        if (value != nullptr) {
            if (runtime) {
                out.push_back("--runtime-arg");
            }
            if (prefix != nullptr) {
                out.push_back(StringPrintf("%s%s", prefix, value->c_str()));
            } else {
                out.push_back(*value);
            }
        }
    }

    static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH";
    static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT";
    static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA";
    // The index of the instruction-set string inside the package parameters. Needed for
    // some special-casing that requires knowledge of the instruction-set.
    static constexpr size_t kISAIndex = 3;

    // Stores the system properties read out of the B partition. We need to use these properties
    // to compile, instead of the A properties we could get from init/get_property.
    SystemProperties system_properties_;

    // Some select properties that are always needed.
    std::string target_slot_;
    std::string android_root_;
    std::string android_data_;
    std::string boot_classpath_;
    std::string asec_mountpoint_;

    Parameters package_parameters_;

    // Store environment values we need to set.
    std::vector<std::string> environ_;
};

OTAPreoptService gOps;

////////////////////////
// Plug-in functions. //
////////////////////////

int get_property(const char *key, char *value, const char *default_value) {
    return gOps.GetProperty(key, value, default_value);
}

// Compute the output path of
bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir,
                             const char *apk_path,
                             const char *instruction_set) {
    const char *file_name_start;
    const char *file_name_end;

    file_name_start = strrchr(apk_path, '/');
    if (file_name_start == nullptr) {
        ALOGE("apk_path '%s' has no '/'s in it\n", apk_path);
        return false;
    }
    file_name_end = strrchr(file_name_start, '.');
    if (file_name_end == nullptr) {
        ALOGE("apk_path '%s' has no extension\n", apk_path);
        return false;
    }

    // Calculate file_name
    file_name_start++;  // Move past '/', is valid as file_name_end is valid.
    size_t file_name_len = file_name_end - file_name_start;
    std::string file_name(file_name_start, file_name_len);

    // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b
    snprintf(path,
             PKG_PATH_MAX,
             "%s/%s/%s.odex.%s",
             oat_dir,
             instruction_set,
             file_name.c_str(),
             gOps.GetTargetSlot().c_str());
    return true;
}

/*
 * Computes the odex file for the given apk_path and instruction_set.
 * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex
 *
 * Returns false if it failed to determine the odex file path.
 */
bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
                              const char *instruction_set) {
    const char *path_end = strrchr(apk_path, '/');
    if (path_end == nullptr) {
        ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
        return false;
    }
    std::string path_component(apk_path, path_end - apk_path);

    const char *name_begin = path_end + 1;
    const char *extension_start = strrchr(name_begin, '.');
    if (extension_start == nullptr) {
        ALOGE("apk_path '%s' has no extension.\n", apk_path);
        return false;
    }
    std::string name_component(name_begin, extension_start - name_begin);

    std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s",
                                        path_component.c_str(),
                                        instruction_set,
                                        name_component.c_str(),
                                        gOps.GetTargetSlot().c_str());
    if (new_path.length() >= PKG_PATH_MAX) {
        LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path;
        return false;
    }
    strcpy(path, new_path.c_str());
    return true;
}

bool create_cache_path(char path[PKG_PATH_MAX],
                       const char *src,
                       const char *instruction_set) {
    size_t srclen = strlen(src);

        /* demand that we are an absolute path */
    if ((src == 0) || (src[0] != '/') || strstr(src,"..")) {
        return false;
    }

    if (srclen > PKG_PATH_MAX) {        // XXX: PKG_NAME_MAX?
        return false;
    }

    std::string from_src = std::string(src + 1);
    std::replace(from_src.begin(), from_src.end(), '/', '@');

    std::string assembled_path = StringPrintf("%s/%s/%s/%s%s",
                                              gOps.GetOTADataDirectory().c_str(),
                                              DALVIK_CACHE,
                                              instruction_set,
                                              from_src.c_str(),
                                              DALVIK_CACHE_POSTFIX);

    if (assembled_path.length() + 1 > PKG_PATH_MAX) {
        return false;
    }
    strcpy(path, assembled_path.c_str());

    return true;
}

static int log_callback(int type, const char *fmt, ...) {
    va_list ap;
    int priority;

    switch (type) {
        case SELINUX_WARNING:
            priority = ANDROID_LOG_WARN;
            break;
        case SELINUX_INFO:
            priority = ANDROID_LOG_INFO;
            break;
        default:
            priority = ANDROID_LOG_ERROR;
            break;
    }
    va_start(ap, fmt);
    LOG_PRI_VA(priority, "SELinux", fmt, ap);
    va_end(ap);
    return 0;
}

static int otapreopt_main(const int argc, char *argv[]) {
    int selinux_enabled = (is_selinux_enabled() > 0);

    setenv("ANDROID_LOG_TAGS", "*:v", 1);
    android::base::InitLogging(argv);

    if (argc < 2) {
        ALOGE("Expecting parameters");
        exit(1);
    }

    union selinux_callback cb;
    cb.func_log = log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);

    if (selinux_enabled && selinux_status_open(true) < 0) {
        ALOGE("Could not open selinux status; exiting.\n");
        exit(1);
    }

    int ret = android::installd::gOps.Main(argc, argv);

    return ret;
}

}  // namespace installd
}  // namespace android

int main(const int argc, char *argv[]) {
    return android::installd::otapreopt_main(argc, argv);
}
