Loading cmds/installd/dexopt.cpp +0 −23 Original line number Original line Diff line number Diff line Loading @@ -67,14 +67,6 @@ static unique_fd invalid_unique_fd() { return unique_fd(-1); return unique_fd(-1); } } static const char* parse_null(const char* arg) { if (strcmp(arg, "!") == 0) { return nullptr; } else { return arg; } } static bool clear_profile(const std::string& profile) { static bool clear_profile(const std::string& profile) { unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); if (ufd.get() < 0) { if (ufd.get() < 0) { Loading Loading @@ -1863,20 +1855,5 @@ bool delete_odex(const char* apk_path, const char* instruction_set, const char* return return_value_oat && return_value_art; return return_value_oat && return_value_art; } } int dexopt(const char* const params[DEXOPT_PARAM_COUNT]) { return dexopt(params[0], // apk_path atoi(params[1]), // uid params[2], // pkgname params[3], // instruction_set atoi(params[4]), // dexopt_needed params[5], // oat_dir atoi(params[6]), // dexopt_flags params[7], // compiler_filter parse_null(params[8]), // volume_uuid parse_null(params[9]), // shared_libraries parse_null(params[10])); // se_info static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param count"); } } // namespace installd } // namespace installd } // namespace android } // namespace android cmds/installd/dexopt.h +0 −6 Original line number Original line Diff line number Diff line Loading @@ -61,12 +61,6 @@ int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *ins int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, 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); const char* volume_uuid, const char* shared_libraries, const char* se_info); static constexpr size_t DEXOPT_PARAM_COUNT = 11U; static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param size"); // Helper for the above, converting arguments. int dexopt(const char* const params[DEXOPT_PARAM_COUNT]); } // namespace installd } // namespace installd } // namespace android } // namespace android Loading cmds/installd/otapreopt.cpp +276 −33 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <algorithm> #include <algorithm> #include <inttypes.h> #include <inttypes.h> #include <limits> #include <random> #include <random> #include <regex> #include <regex> #include <selinux/android.h> #include <selinux/android.h> Loading @@ -40,6 +41,7 @@ #include "dexopt.h" #include "dexopt.h" #include "file_parsing.h" #include "file_parsing.h" #include "globals.h" #include "globals.h" #include "installd_constants.h" #include "installd_deps.h" // Need to fill in requirements of commands. #include "installd_deps.h" // Need to fill in requirements of commands. #include "otapreopt_utils.h" #include "otapreopt_utils.h" #include "system_properties.h" #include "system_properties.h" Loading Loading @@ -145,6 +147,20 @@ class OTAPreoptService { private: 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 ReadSystemProperties() { bool ReadSystemProperties() { static constexpr const char* kPropertyFiles[] = { static constexpr const char* kPropertyFiles[] = { "/default.prop", "/system/build.prop" "/default.prop", "/system/build.prop" Loading Loading @@ -246,15 +262,23 @@ private: return true; return true; } } bool ReadArguments(int argc ATTRIBUTE_UNUSED, char** argv) { bool ParseUInt(const char* in, uint32_t* out) { // Expected command line: char* end; // target-slot dexopt {DEXOPT_PARAMETERS} long long int result = strtoll(in, &end, 0); // The DEXOPT_PARAMETERS are passed on to dexopt(), so we expect DEXOPT_PARAM_COUNT if (in == end || *end != '\0') { // of them. We store them in package_parameters_ (size checks are done when return false; // parsing the special parameters and when copying into package_parameters_. } 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; } static_assert(DEXOPT_PARAM_COUNT == ARRAY_SIZE(package_parameters_), bool ReadArguments(int argc, char** argv) { "Unexpected dexopt param count"); // Expected command line: // target-slot [version] dexopt {DEXOPT_PARAMETERS} const char* target_slot_arg = argv[1]; const char* target_slot_arg = argv[1]; if (target_slot_arg == nullptr) { if (target_slot_arg == nullptr) { Loading @@ -268,28 +292,230 @@ private: return false; return false; } } // Check for "dexopt" next. // 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 + 1; // null 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); 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; } } if (param_index != 11) { 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) { if (argv[2] == nullptr) { LOG(ERROR) << "Missing parameters"; LOG(ERROR) << "Missing parameters"; return false; return false; } } if (std::string("dexopt").compare(argv[2]) != 0) { if (std::string("dexopt").compare(argv[2]) != 0) { LOG(ERROR) << "Second parameter not dexopt: " << argv[2]; LOG(ERROR) << "Expected \"dexopt\""; return false; return false; } } // Copy the rest into package_parameters_, but be careful about over- and underflow. size_t param_index = 0; size_t index = 0; for (;; ++param_index) { while (index < DEXOPT_PARAM_COUNT && const char* param = argv[3 + param_index]; argv[index + 3] != nullptr) { if (param == nullptr) { package_parameters_[index] = argv[index + 3]; break; index++; } } if (index != ARRAY_SIZE(package_parameters_) || argv[index + 3] != nullptr) { LOG(ERROR) << "Wrong number of parameters"; 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; 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_SAFEMODE, DEXOPT_SAFEMODE) | 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; 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; return true; return true; } } Loading @@ -306,11 +532,11 @@ private: // Ensure that we have the right boot image. The first time any app is // Ensure that we have the right boot image. The first time any app is // compiled, we'll try to generate it. // compiled, we'll try to generate it. bool PrepareBootImage(bool force) const { bool PrepareBootImage(bool force) const { if (package_parameters_[kISAIndex] == nullptr) { if (package_parameters_.instruction_set == nullptr) { LOG(ERROR) << "Instruction set missing."; LOG(ERROR) << "Instruction set missing."; return false; return false; } } const char* isa = package_parameters_[kISAIndex]; const char* isa = package_parameters_.instruction_set; // Check whether the file exists where expected. // Check whether the file exists where expected. std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; Loading Loading @@ -536,14 +762,12 @@ private: // (This is ugly as it's the only thing where we need to understand the contents // (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- // of package_parameters_, but it beats postponing the decision or using the call- // backs to do weird things.) // backs to do weird things.) constexpr size_t kApkPathIndex = 0; const char* apk_path = package_parameters_.apk_path; CHECK_GT(DEXOPT_PARAM_COUNT, kApkPathIndex); CHECK(apk_path != nullptr); CHECK(package_parameters_[kApkPathIndex] != nullptr); if (StartsWith(apk_path, android_root_.c_str())) { if (StartsWith(package_parameters_[kApkPathIndex], android_root_.c_str())) { const char* last_slash = strrchr(apk_path, '/'); const char* last_slash = strrchr(package_parameters_[kApkPathIndex], '/'); if (last_slash != nullptr) { if (last_slash != nullptr) { std::string path(package_parameters_[kApkPathIndex], std::string path(apk_path, last_slash - apk_path + 1); last_slash - package_parameters_[kApkPathIndex] + 1); CHECK(EndsWith(path, "/")); CHECK(EndsWith(path, "/")); path = path + "oat"; path = path + "oat"; if (access(path.c_str(), F_OK) == 0) { if (access(path.c_str(), F_OK) == 0) { Loading @@ -557,9 +781,8 @@ private: // partition will not be available and fail to build. This is problematic, as // 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 // this tool will wipe the OTA artifact cache and try again (for robustness after // a failed OTA with remaining cache artifacts). // a failed OTA with remaining cache artifacts). if (access(package_parameters_[kApkPathIndex], F_OK) != 0) { if (access(apk_path, F_OK) != 0) { LOG(WARNING) << "Skipping preopt of non-existing package " LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path; << package_parameters_[kApkPathIndex]; return true; return true; } } Loading @@ -571,7 +794,17 @@ private: return 0; return 0; } } int dexopt_result = dexopt(package_parameters_); int dexopt_result = 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); if (dexopt_result == 0) { if (dexopt_result == 0) { return 0; return 0; } } Loading @@ -590,7 +823,17 @@ private: } } LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; return dexopt(package_parameters_); 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); } } //////////////////////////////////// //////////////////////////////////// Loading Loading @@ -720,7 +963,7 @@ private: std::string boot_classpath_; std::string boot_classpath_; std::string asec_mountpoint_; std::string asec_mountpoint_; const char* package_parameters_[DEXOPT_PARAM_COUNT]; Parameters package_parameters_; // Store environment values we need to set. // Store environment values we need to set. std::vector<std::string> environ_; std::vector<std::string> environ_; Loading Loading
cmds/installd/dexopt.cpp +0 −23 Original line number Original line Diff line number Diff line Loading @@ -67,14 +67,6 @@ static unique_fd invalid_unique_fd() { return unique_fd(-1); return unique_fd(-1); } } static const char* parse_null(const char* arg) { if (strcmp(arg, "!") == 0) { return nullptr; } else { return arg; } } static bool clear_profile(const std::string& profile) { static bool clear_profile(const std::string& profile) { unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); if (ufd.get() < 0) { if (ufd.get() < 0) { Loading Loading @@ -1863,20 +1855,5 @@ bool delete_odex(const char* apk_path, const char* instruction_set, const char* return return_value_oat && return_value_art; return return_value_oat && return_value_art; } } int dexopt(const char* const params[DEXOPT_PARAM_COUNT]) { return dexopt(params[0], // apk_path atoi(params[1]), // uid params[2], // pkgname params[3], // instruction_set atoi(params[4]), // dexopt_needed params[5], // oat_dir atoi(params[6]), // dexopt_flags params[7], // compiler_filter parse_null(params[8]), // volume_uuid parse_null(params[9]), // shared_libraries parse_null(params[10])); // se_info static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param count"); } } // namespace installd } // namespace installd } // namespace android } // namespace android
cmds/installd/dexopt.h +0 −6 Original line number Original line Diff line number Diff line Loading @@ -61,12 +61,6 @@ int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *ins int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, 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); const char* volume_uuid, const char* shared_libraries, const char* se_info); static constexpr size_t DEXOPT_PARAM_COUNT = 11U; static_assert(DEXOPT_PARAM_COUNT == 11U, "Unexpected dexopt param size"); // Helper for the above, converting arguments. int dexopt(const char* const params[DEXOPT_PARAM_COUNT]); } // namespace installd } // namespace installd } // namespace android } // namespace android Loading
cmds/installd/otapreopt.cpp +276 −33 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <algorithm> #include <algorithm> #include <inttypes.h> #include <inttypes.h> #include <limits> #include <random> #include <random> #include <regex> #include <regex> #include <selinux/android.h> #include <selinux/android.h> Loading @@ -40,6 +41,7 @@ #include "dexopt.h" #include "dexopt.h" #include "file_parsing.h" #include "file_parsing.h" #include "globals.h" #include "globals.h" #include "installd_constants.h" #include "installd_deps.h" // Need to fill in requirements of commands. #include "installd_deps.h" // Need to fill in requirements of commands. #include "otapreopt_utils.h" #include "otapreopt_utils.h" #include "system_properties.h" #include "system_properties.h" Loading Loading @@ -145,6 +147,20 @@ class OTAPreoptService { private: 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 ReadSystemProperties() { bool ReadSystemProperties() { static constexpr const char* kPropertyFiles[] = { static constexpr const char* kPropertyFiles[] = { "/default.prop", "/system/build.prop" "/default.prop", "/system/build.prop" Loading Loading @@ -246,15 +262,23 @@ private: return true; return true; } } bool ReadArguments(int argc ATTRIBUTE_UNUSED, char** argv) { bool ParseUInt(const char* in, uint32_t* out) { // Expected command line: char* end; // target-slot dexopt {DEXOPT_PARAMETERS} long long int result = strtoll(in, &end, 0); // The DEXOPT_PARAMETERS are passed on to dexopt(), so we expect DEXOPT_PARAM_COUNT if (in == end || *end != '\0') { // of them. We store them in package_parameters_ (size checks are done when return false; // parsing the special parameters and when copying into package_parameters_. } 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; } static_assert(DEXOPT_PARAM_COUNT == ARRAY_SIZE(package_parameters_), bool ReadArguments(int argc, char** argv) { "Unexpected dexopt param count"); // Expected command line: // target-slot [version] dexopt {DEXOPT_PARAMETERS} const char* target_slot_arg = argv[1]; const char* target_slot_arg = argv[1]; if (target_slot_arg == nullptr) { if (target_slot_arg == nullptr) { Loading @@ -268,28 +292,230 @@ private: return false; return false; } } // Check for "dexopt" next. // 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 + 1; // null 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); 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; } } if (param_index != 11) { 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) { if (argv[2] == nullptr) { LOG(ERROR) << "Missing parameters"; LOG(ERROR) << "Missing parameters"; return false; return false; } } if (std::string("dexopt").compare(argv[2]) != 0) { if (std::string("dexopt").compare(argv[2]) != 0) { LOG(ERROR) << "Second parameter not dexopt: " << argv[2]; LOG(ERROR) << "Expected \"dexopt\""; return false; return false; } } // Copy the rest into package_parameters_, but be careful about over- and underflow. size_t param_index = 0; size_t index = 0; for (;; ++param_index) { while (index < DEXOPT_PARAM_COUNT && const char* param = argv[3 + param_index]; argv[index + 3] != nullptr) { if (param == nullptr) { package_parameters_[index] = argv[index + 3]; break; index++; } } if (index != ARRAY_SIZE(package_parameters_) || argv[index + 3] != nullptr) { LOG(ERROR) << "Wrong number of parameters"; 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; 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_SAFEMODE, DEXOPT_SAFEMODE) | 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; 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; return true; return true; } } Loading @@ -306,11 +532,11 @@ private: // Ensure that we have the right boot image. The first time any app is // Ensure that we have the right boot image. The first time any app is // compiled, we'll try to generate it. // compiled, we'll try to generate it. bool PrepareBootImage(bool force) const { bool PrepareBootImage(bool force) const { if (package_parameters_[kISAIndex] == nullptr) { if (package_parameters_.instruction_set == nullptr) { LOG(ERROR) << "Instruction set missing."; LOG(ERROR) << "Instruction set missing."; return false; return false; } } const char* isa = package_parameters_[kISAIndex]; const char* isa = package_parameters_.instruction_set; // Check whether the file exists where expected. // Check whether the file exists where expected. std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; Loading Loading @@ -536,14 +762,12 @@ private: // (This is ugly as it's the only thing where we need to understand the contents // (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- // of package_parameters_, but it beats postponing the decision or using the call- // backs to do weird things.) // backs to do weird things.) constexpr size_t kApkPathIndex = 0; const char* apk_path = package_parameters_.apk_path; CHECK_GT(DEXOPT_PARAM_COUNT, kApkPathIndex); CHECK(apk_path != nullptr); CHECK(package_parameters_[kApkPathIndex] != nullptr); if (StartsWith(apk_path, android_root_.c_str())) { if (StartsWith(package_parameters_[kApkPathIndex], android_root_.c_str())) { const char* last_slash = strrchr(apk_path, '/'); const char* last_slash = strrchr(package_parameters_[kApkPathIndex], '/'); if (last_slash != nullptr) { if (last_slash != nullptr) { std::string path(package_parameters_[kApkPathIndex], std::string path(apk_path, last_slash - apk_path + 1); last_slash - package_parameters_[kApkPathIndex] + 1); CHECK(EndsWith(path, "/")); CHECK(EndsWith(path, "/")); path = path + "oat"; path = path + "oat"; if (access(path.c_str(), F_OK) == 0) { if (access(path.c_str(), F_OK) == 0) { Loading @@ -557,9 +781,8 @@ private: // partition will not be available and fail to build. This is problematic, as // 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 // this tool will wipe the OTA artifact cache and try again (for robustness after // a failed OTA with remaining cache artifacts). // a failed OTA with remaining cache artifacts). if (access(package_parameters_[kApkPathIndex], F_OK) != 0) { if (access(apk_path, F_OK) != 0) { LOG(WARNING) << "Skipping preopt of non-existing package " LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path; << package_parameters_[kApkPathIndex]; return true; return true; } } Loading @@ -571,7 +794,17 @@ private: return 0; return 0; } } int dexopt_result = dexopt(package_parameters_); int dexopt_result = 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); if (dexopt_result == 0) { if (dexopt_result == 0) { return 0; return 0; } } Loading @@ -590,7 +823,17 @@ private: } } LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; return dexopt(package_parameters_); 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); } } //////////////////////////////////// //////////////////////////////////// Loading Loading @@ -720,7 +963,7 @@ private: std::string boot_classpath_; std::string boot_classpath_; std::string asec_mountpoint_; std::string asec_mountpoint_; const char* package_parameters_[DEXOPT_PARAM_COUNT]; Parameters package_parameters_; // Store environment values we need to set. // Store environment values we need to set. std::vector<std::string> environ_; std::vector<std::string> environ_; Loading