Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50dc8549 authored by Calin Juravle's avatar Calin Juravle Committed by Automerger Merge Worker
Browse files

Merge changes from topics "delete_odex", "verify-prof" am: d8ee0ace am:...

Merge changes from topics "delete_odex", "verify-prof" am: d8ee0ace am: 54d29c40 am: 6854365c am: 6298bdc1

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1734999

Change-Id: I65bdada803d5730f6fac1de47267376178fd7592
parents 6a621729 6298bdc1
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -2357,7 +2357,7 @@ binder::Status InstalldNativeService::copySystemProfile(const std::string& syste

// TODO: Consider returning error codes.
binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
        const std::string& profileName, bool* _aidl_return) {
        const std::string& profileName, int* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);
@@ -2657,7 +2657,8 @@ binder::Status InstalldNativeService::moveAb(const std::string& apkPath,
}

binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
        const std::string& instructionSet, const std::optional<std::string>& outputPath) {
        const std::string& instructionSet, const std::optional<std::string>& outputPath,
        int64_t* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PATH(apkPath);
    CHECK_ARGUMENT_PATH(outputPath);
@@ -2667,8 +2668,8 @@ binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
    const char* instruction_set = instructionSet.c_str();
    const char* oat_dir = outputPath ? outputPath->c_str() : nullptr;

    bool res = delete_odex(apk_path, instruction_set, oat_dir);
    return res ? ok() : error();
    *_aidl_return = delete_odex(apk_path, instruction_set, oat_dir);
    return *_aidl_return == -1 ? error() : ok();
}

// This kernel feature is experimental.
+2 −2
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ public:
    binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);

    binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
            const std::string& profileName, bool* _aidl_return);
            const std::string& profileName, int* _aidl_return);
    binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
            const std::string& profileName, const std::string& codePath, bool* _aidl_return);
    binder::Status copySystemProfile(const std::string& systemProfile,
@@ -150,7 +150,7 @@ public:
    binder::Status moveAb(const std::string& apkPath, const std::string& instructionSet,
            const std::string& outputPath);
    binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
            const std::optional<std::string>& outputPath);
            const std::optional<std::string>& outputPath, int64_t* _aidl_return);
    binder::Status installApkVerity(const std::string& filePath,
            android::base::unique_fd verityInput, int32_t contentSize);
    binder::Status assertFsverityRootHashMatches(const std::string& filePath,
+2 −2
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ interface IInstalld {

    void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet);

    boolean mergeProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName);
    int mergeProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName);
    boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String  profileName,
            @utf8InCpp String codePath);
    boolean copySystemProfile(@utf8InCpp String systemProfile, int uid,
@@ -91,7 +91,7 @@ interface IInstalld {
            @utf8InCpp String toBase);
    void moveAb(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
            @utf8InCpp String outputPath);
    void deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
    long deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
            @nullable @utf8InCpp String outputPath);
    void installApkVerity(@utf8InCpp String filePath, in FileDescriptor verityInput,
            int contentSize);
+69 −40
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@
#include "execv_helper.h"
#include "globals.h"
#include "installd_deps.h"
#include "installd_constants.h"
#include "otapreopt_utils.h"
#include "run_dex2oat.h"
#include "unique_file.h"
@@ -416,11 +417,12 @@ static void open_profile_files(uid_t uid, const std::string& package_name,

static constexpr int PROFMAN_BIN_RETURN_CODE_SUCCESS = 0;
static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 1;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 2;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_NOT_ENOUGH_DELTA = 2;
static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 3;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 4;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 5;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_DIFFERENT_VERSIONS = 6;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_EMPTY_PROFILES = 7;

class RunProfman : public ExecVHelper {
  public:
@@ -555,15 +557,7 @@ class RunProfman : public ExecVHelper {
    std::vector<unique_fd> apk_fds_;
};



// Decides if profile guided compilation is needed or not based on existing profiles.
// The location is the package name for primary apks or the dex path for secondary dex files.
// Returns true if there is enough information in the current profiles that makes it
// worth to recompile the given location.
// If the return value is true all the current profiles would have been merged into
// the reference profiles accessible with open_reference_profile().
static bool analyze_profiles(uid_t uid, const std::string& package_name,
static int analyze_profiles(uid_t uid, const std::string& package_name,
        const std::string& location, bool is_secondary_dex) {
    std::vector<unique_fd> profiles_fd;
    unique_fd reference_profile_fd;
@@ -572,7 +566,7 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
        // Skip profile guided compilation because no profiles were found.
        // Or if the reference profile info couldn't be opened.
        return false;
        return PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES;
    }

    RunProfman profman_merge;
@@ -594,6 +588,7 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    /* parent */
    int return_code = wait_child(pid);
    bool need_to_compile = false;
    bool empty_profiles = false;
    bool should_clear_current_profiles = false;
    bool should_clear_reference_profile = false;
    if (!WIFEXITED(return_code)) {
@@ -606,8 +601,14 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
                should_clear_current_profiles = true;
                should_clear_reference_profile = false;
                break;
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_NOT_ENOUGH_DELTA:
                need_to_compile = false;
                should_clear_current_profiles = false;
                should_clear_reference_profile = false;
                break;
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_EMPTY_PROFILES:
                need_to_compile = false;
                empty_profiles = true;
                should_clear_current_profiles = false;
                should_clear_reference_profile = false;
                break;
@@ -653,16 +654,29 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    if (should_clear_reference_profile) {
        clear_reference_profile(package_name, location, is_secondary_dex);
    }
    return need_to_compile;
    int result = 0;
    if (need_to_compile) {
        result = PROFILES_ANALYSIS_OPTIMIZE;
    } else if (empty_profiles) {
        result = PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES;
    } else {
        result = PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA;
    }
    return result;
}

// Decides if profile guided compilation is needed or not based on existing profiles.
// The analysis is done for the primary apks of the given package.
// Returns true if there is enough information in the current profiles that makes it
// worth to recompile the package.
// If the return value is true all the current profiles would have been merged into
// the reference profiles accessible with open_reference_profile().
bool analyze_primary_profiles(uid_t uid, const std::string& package_name,
// The analysis is done for a single profile name (which corresponds to a single code path).
//
// Returns PROFILES_ANALYSIS_OPTIMIZE if there is enough information in the current profiles
// that makes it worth to recompile the package.
// If the return value is PROFILES_ANALYSIS_OPTIMIZE all the current profiles would have been
// merged into the reference profiles accessible with open_reference_profile().
//
// Return PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA if the package should not optimize.
// As a special case returns PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES if all profiles are
// empty.
int analyze_primary_profiles(uid_t uid, const std::string& package_name,
        const std::string& profile_name) {
    return analyze_profiles(uid, package_name, profile_name, /*is_secondary_dex*/false);
}
@@ -1166,7 +1180,7 @@ class RunDexoptAnalyzer : public ExecVHelper {
                      int zip_fd,
                      const std::string& instruction_set,
                      const std::string& compiler_filter,
                      bool profile_was_updated,
                      int profile_analysis_result,
                      bool downgrade,
                      const char* class_loader_context,
                      const std::string& class_loader_context_fds) {
@@ -1182,7 +1196,8 @@ class RunDexoptAnalyzer : public ExecVHelper {
        std::string zip_fd_arg = "--zip-fd=" + std::to_string(zip_fd);
        std::string isa_arg = "--isa=" + instruction_set;
        std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter;
        const char* assume_profile_changed = "--assume-profile-changed";
        std::string profile_analysis_arg = "--profile-analysis-result="
                + std::to_string(profile_analysis_result);
        const char* downgrade_flag = "--downgrade";
        std::string class_loader_context_arg = "--class-loader-context=";
        if (class_loader_context != nullptr) {
@@ -1204,9 +1219,8 @@ class RunDexoptAnalyzer : public ExecVHelper {
            AddArg(vdex_fd_arg);
        }
        AddArg(zip_fd_arg);
        if (profile_was_updated) {
            AddArg(assume_profile_changed);
        }
        AddArg(profile_analysis_arg);

        if (downgrade) {
            AddArg(downgrade_flag);
        }
@@ -1578,7 +1592,7 @@ static bool process_secondary_dex_dexopt(const std::string& dex_path, const char
        }

        // Analyze profiles.
        bool profile_was_updated = analyze_profiles(uid, pkgname, dex_path,
        int profile_analysis_result = analyze_profiles(uid, pkgname, dex_path,
                /*is_secondary_dex*/true);

        // Run dexoptanalyzer to get dexopt_needed code. This is not expected to return.
@@ -1589,7 +1603,8 @@ static bool process_secondary_dex_dexopt(const std::string& dex_path, const char
                                              oat_file_fd.get(),
                                              zip_fd.get(),
                                              instruction_set,
                                              compiler_filter, profile_was_updated,
                                              compiler_filter,
                                              profile_analysis_result,
                                              downgrade,
                                              class_loader_context,
                                              join_fds(context_zip_fds));
@@ -2237,38 +2252,52 @@ bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_
    return success;
}

bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) {
int64_t delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) {
    // Delete the oat/odex file.
    char out_path[PKG_PATH_MAX];
    if (!create_oat_out_path(apk_path, instruction_set, oat_dir,
            /*is_secondary_dex*/false, out_path)) {
        return false;
        LOG(ERROR) << "Cannot create apk path for " << apk_path;
        return -1;
    }

    // In case of a permission failure report the issue. Otherwise just print a warning.
    auto unlink_and_check = [](const char* path) -> bool {
        int result = unlink(path);
        if (result != 0) {
            if (errno == EACCES || errno == EPERM) {
    auto unlink_and_check = [](const char* path) -> int64_t {
        struct stat file_stat;
        if (stat(path, &file_stat) != 0) {
            if (errno != ENOENT) {
                PLOG(ERROR) << "Could not stat " << path;
                return -1;
            }
            return 0;
        }

        if (unlink(path) != 0) {
            if (errno != ENOENT) {
                PLOG(ERROR) << "Could not unlink " << path;
                return false;
                return -1;
            }
            PLOG(WARNING) << "Could not unlink " << path;
        }
        return true;
        return static_cast<int64_t>(file_stat.st_size);
    };

    // Delete the oat/odex file.
    bool return_value_oat = unlink_and_check(out_path);
    int64_t return_value_oat = unlink_and_check(out_path);

    // Derive and delete the app image.
    bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
    int64_t return_value_art = unlink_and_check(create_image_filename(out_path).c_str());

    // Derive and delete the vdex file.
    bool return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str());
    int64_t return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str());

    // Report result
    if (return_value_oat == -1
            || return_value_art == -1
            || return_value_vdex == -1) {
        return -1;
    }

    // Report success.
    return return_value_oat && return_value_art && return_value_vdex;
    return return_value_oat + return_value_art + return_value_vdex;
}

static bool is_absolute_path(const std::string& path) {
+15 −9
Original line number Diff line number Diff line
@@ -54,13 +54,18 @@ bool clear_primary_current_profile(const std::string& pkgname, const std::string
// Clear all current profiles identified by the given profile name (all users).
bool clear_primary_current_profiles(const std::string& pkgname, const std::string& profile_name);

// Decide if profile guided compilation is needed or not based on existing profiles.
// Decides if profile guided compilation is needed or not based on existing profiles.
// The analysis is done for a single profile name (which corresponds to a single code path).
// Returns true if there is enough information in the current profiles that makes it
// worth to recompile the package.
// If the return value is true all the current profiles would have been merged into
// the reference profiles accessible with open_reference_profile().
bool analyze_primary_profiles(uid_t uid,
//
// Returns PROFILES_ANALYSIS_OPTIMIZE if there is enough information in the current profiles
// that makes it worth to recompile the package.
// If the return value is PROFILES_ANALYSIS_OPTIMIZE all the current profiles would have been
// merged into the reference profiles accessible with open_reference_profile().
//
// Return PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA if the package should not optimize.
// As a special case returns PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES if all profiles are
// empty.
int analyze_primary_profiles(uid_t uid,
                             const std::string& pkgname,
                             const std::string& profile_name);

@@ -104,7 +109,8 @@ bool prepare_app_profile(const std::string& package_name,
                         const std::string& code_path,
                         const std::optional<std::string>& dex_metadata);

bool delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);
// Returns the total bytes that were freed, or -1 in case of errors.
int64_t delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);

bool reconcile_secondary_dex_file(const std::string& dex_path,
        const std::string& pkgname, int uid, const std::vector<std::string>& isas,
Loading