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

Commit 76268c56 authored by Calin Juravle's avatar Calin Juravle
Browse files

Use std::string for profile operations instead of const char

Will make things cleaner when adding secondary dex profile support.

Also, add tests to verify profile path creation.

Bug: 26719109
Test: /data/nativetest64/installd_utils_test/installd_utils_test
Change-Id: I8cb1a11cefee21f5001d2b729110696d52fc8323
parent 632dbe2c
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -424,12 +424,11 @@ binder::Status InstalldNativeService::clearAppProfiles(const std::string& packag
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    const char* pkgname = packageName.c_str();
    binder::Status res = ok();
    if (!clear_reference_profile(pkgname)) {
    if (!clear_reference_profile(packageName)) {
        res = error("Failed to clear reference profile for " + packageName);
    }
    if (!clear_current_profiles(pkgname)) {
    if (!clear_current_profiles(packageName)) {
        res = error("Failed to clear current profiles for " + packageName);
    }
    return res;
@@ -477,7 +476,7 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
            }
        }
        if (!only_cache) {
            if (!clear_current_profile(pkgname, userId)) {
            if (!clear_current_profile(packageName, userId)) {
                res = error("Failed to clear current profile for " + packageName);
            }
        }
@@ -485,13 +484,13 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
    return res;
}

static int destroy_app_reference_profile(const char *pkgname) {
static int destroy_app_reference_profile(const std::string& pkgname) {
    return delete_dir_contents_and_dir(
        create_data_ref_profile_package_path(pkgname),
        /*ignore_if_missing*/ true);
}

static int destroy_app_current_profiles(const char *pkgname, userid_t userid) {
static int destroy_app_current_profiles(const std::string& pkgname, userid_t userid) {
    return delete_dir_contents_and_dir(
        create_data_user_profile_package_path(userid, pkgname),
        /*ignore_if_missing*/ true);
@@ -502,15 +501,14 @@ binder::Status InstalldNativeService::destroyAppProfiles(const std::string& pack
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    const char* pkgname = packageName.c_str();
    binder::Status res = ok();
    std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
    for (auto user : users) {
        if (destroy_app_current_profiles(pkgname, user) != 0) {
        if (destroy_app_current_profiles(packageName, user) != 0) {
            res = error("Failed to destroy current profiles for " + packageName);
        }
    }
    if (destroy_app_reference_profile(pkgname) != 0) {
    if (destroy_app_reference_profile(packageName) != 0) {
        res = error("Failed to destroy reference profile for " + packageName);
    }
    return res;
@@ -538,11 +536,11 @@ binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::
        if (delete_dir_contents_and_dir(path) != 0) {
            res = error("Failed to delete " + path);
        }
        destroy_app_current_profiles(pkgname, userId);
        destroy_app_current_profiles(packageName, userId);
        // TODO(calin): If the package is still installed by other users it's probably
        // beneficial to keep the reference profile around.
        // Verify if it's ok to do that.
        destroy_app_reference_profile(pkgname);
        destroy_app_reference_profile(packageName);
    }
    return res;
}
+10 −14
Original line number Diff line number Diff line
@@ -101,19 +101,19 @@ static bool clear_profile(const std::string& profile) {
    return truncated;
}

bool clear_reference_profile(const char* pkgname) {
bool clear_reference_profile(const std::string& pkgname) {
    std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
    std::string reference_profile = create_primary_profile(reference_profile_dir);
    return clear_profile(reference_profile);
}

bool clear_current_profile(const char* pkgname, userid_t user) {
bool clear_current_profile(const std::string& pkgname, userid_t user) {
    std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
    std::string profile = create_primary_profile(profile_dir);
    return clear_profile(profile);
}

bool clear_current_profiles(const char* pkgname) {
bool clear_current_profiles(const std::string& pkgname) {
    bool success = true;
    std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
    for (auto user : users) {
@@ -512,12 +512,12 @@ static fd_t open_primary_profile_file_from_dir(const std::string& profile_dir, m
    return profile_fd;
}

static fd_t open_primary_profile_file(userid_t user, const char* pkgname) {
static fd_t open_primary_profile_file(userid_t user, const std::string& pkgname) {
    std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
    return open_primary_profile_file_from_dir(profile_dir, O_RDONLY);
}

static fd_t open_reference_profile(uid_t uid, const char* pkgname, bool read_write) {
static fd_t open_reference_profile(uid_t uid, const std::string& pkgname, bool read_write) {
    std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
    int flags = read_write ? O_RDWR | O_CREAT : O_RDONLY;
    fd_t fd = open_primary_profile_file_from_dir(reference_profile_dir, flags);
@@ -534,7 +534,7 @@ static fd_t open_reference_profile(uid_t uid, const char* pkgname, bool read_wri
    return fd;
}

static void open_profile_files(uid_t uid, const char* pkgname,
static void open_profile_files(uid_t uid, const std::string& pkgname,
            /*out*/ std::vector<fd_t>* profiles_fd, /*out*/ fd_t* reference_profile_fd) {
    // Open the reference profile in read-write mode as profman might need to save the merge.
    *reference_profile_fd = open_reference_profile(uid, pkgname, /*read_write*/ true);
@@ -614,7 +614,7 @@ static void run_profman_merge(const std::vector<fd_t>& profiles_fd, fd_t referen
// a re-compilation of 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 analyse_profiles(uid_t uid, const char* pkgname) {
bool analyse_profiles(uid_t uid, const std::string& pkgname) {
    std::vector<fd_t> profiles_fd;
    fd_t reference_profile_fd = -1;
    open_profile_files(uid, pkgname, &profiles_fd, &reference_profile_fd);
@@ -628,8 +628,6 @@ bool analyse_profiles(uid_t uid, const char* pkgname) {
        return false;
    }

    ALOGV("PROFMAN (MERGE): --- BEGIN '%s' ---\n", pkgname);

    pid_t pid = fork();
    if (pid == 0) {
        /* child -- drop privileges before continuing */
@@ -740,12 +738,10 @@ static const char* get_location_from_path(const char* path) {
    }
}

bool dump_profiles(int32_t uid, const char* pkgname, const char* code_paths) {
bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths) {
    std::vector<fd_t> profile_fds;
    fd_t reference_profile_fd = -1;
    std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname);

    ALOGV("PROFMAN (DUMP): --- BEGIN '%s' ---\n", pkgname);
    std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname.c_str());

    open_profile_files(uid, pkgname, &profile_fds, &reference_profile_fd);

@@ -753,7 +749,7 @@ bool dump_profiles(int32_t uid, const char* pkgname, const char* code_paths) {
    const bool has_profiles = !profile_fds.empty();

    if (!has_reference_profile && !has_profiles) {
        ALOGE("profman dump: no profiles to dump for '%s'", pkgname);
        LOG(ERROR)  << "profman dump: no profiles to dump for " << pkgname;
        return false;
    }

+5 −5
Original line number Diff line number Diff line
@@ -34,14 +34,14 @@ static constexpr int PATCHOAT_FOR_RELOCATION = 5;

typedef int fd_t;

bool clear_reference_profile(const char* pkgname);
bool clear_current_profile(const char* pkgname, userid_t user);
bool clear_current_profiles(const char* pkgname);
bool clear_reference_profile(const std::string& pkgname);
bool clear_current_profile(const std::string& pkgname, userid_t user);
bool clear_current_profiles(const std::string& pkgname);

bool move_ab(const char* apk_path, const char* instruction_set, const char* output_path);

bool analyse_profiles(uid_t uid, const char* pkgname);
bool dump_profiles(int32_t uid, const char* pkgname, const char* code_paths);
bool analyse_profiles(uid_t uid, const std::string& pkgname);
bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths);

bool delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);

+31 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#define TEST_SYSTEM_DIR1 "/system/app/"
#define TEST_SYSTEM_DIR2 "/vendor/app/"

#define TEST_PROFILE_DIR "/data/misc/profiles"

#define REALLY_LONG_APP_NAME "com.example." \
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
@@ -74,6 +76,9 @@ protected:

        android_system_dirs.dirs[1].path = (char*) TEST_SYSTEM_DIR2;
        android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2);

        android_profiles_dir.path = (char*) TEST_PROFILE_DIR;
        android_profiles_dir.len = strlen(TEST_PROFILE_DIR);
    }

    virtual void TearDown() {
@@ -515,5 +520,31 @@ TEST_F(UtilsTest, IsValidPackageName) {
    EXPECT_EQ(false, is_valid_package_name("/com.evil"));
}

TEST_F(UtilsTest, CreateDataUserProfilePath) {
    EXPECT_EQ("/data/misc/profiles/cur/0", create_data_user_profile_path(0));
    EXPECT_EQ("/data/misc/profiles/cur/1", create_data_user_profile_path(1));
}

TEST_F(UtilsTest, CreateDataUserProfilePackagePath) {
    EXPECT_EQ("/data/misc/profiles/cur/0/com.example",
            create_data_user_profile_package_path(0, "com.example"));
    EXPECT_EQ("/data/misc/profiles/cur/1/com.example",
            create_data_user_profile_package_path(1, "com.example"));
}

TEST_F(UtilsTest, CreateDataRefProfilePath) {
    EXPECT_EQ("/data/misc/profiles/ref", create_data_ref_profile_path());
}

TEST_F(UtilsTest, CreateDataRefProfilePackagePath) {
    EXPECT_EQ("/data/misc/profiles/ref/com.example",
        create_data_ref_profile_package_path("com.example"));
}

TEST_F(UtilsTest, CreatePrimaryProfile) {
    EXPECT_EQ("/data/misc/profiles/ref/com.example/primary.prof",
        create_primary_profile("/data/misc/profiles/ref/com.example"));
}

}  // namespace installd
}  // namespace android
+6 −6
Original line number Diff line number Diff line
@@ -217,18 +217,18 @@ std::string create_data_user_profile_path(userid_t userid) {
    return StringPrintf("%s/cur/%u", android_profiles_dir.path, userid);
}

std::string create_data_user_profile_package_path(userid_t user, const char* package_name) {
    check_package_name(package_name);
    return StringPrintf("%s/%s",create_data_user_profile_path(user).c_str(), package_name);
std::string create_data_user_profile_package_path(userid_t user, const std::string& package_name) {
    check_package_name(package_name.c_str());
    return StringPrintf("%s/%s",create_data_user_profile_path(user).c_str(), package_name.c_str());
}

std::string create_data_ref_profile_path() {
    return StringPrintf("%s/ref", android_profiles_dir.path);
}

std::string create_data_ref_profile_package_path(const char* package_name) {
    check_package_name(package_name);
    return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name);
std::string create_data_ref_profile_package_path(const std::string& package_name) {
    check_package_name(package_name.c_str());
    return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name.c_str());
}

std::string create_data_dalvik_cache_path() {
Loading