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

Commit 562de815 authored by Calin Juravle's avatar Calin Juravle
Browse files

[installd] Extend profile operations to take the profile name

Extend the installd profile interface to take the profile name as
argument. This shifts the responsibility for choosing the names of
profiles for primary apks completely to PackageManager. Each of the
application code paths will get an unique profile name.

All the profile operations will now work on a specific profile name rather
than assuming a default global name.

Test: installd_dexopt_test
Bug: 30934496
Change-Id: I5847d35fe4d3caa5a2b32293426a24683af42030
parent ffa0ad89
Loading
Loading
Loading
Loading
+15 −33
Original line number Diff line number Diff line
@@ -107,10 +107,6 @@ namespace {

constexpr const char* kDump = "android.permission.DUMP";

// TODO(calin): We can stop hardcoding this here once the PM passes the profile
// name for all profile related operations.
constexpr const char* kPrimaryProfileName = "primary.prof";

static binder::Status ok() {
    return binder::Status::ok();
}
@@ -389,14 +385,6 @@ static bool prepare_app_profile_dir(const std::string& packageName, int32_t appI
        return false;
    }

    const std::string profile_file = create_current_profile_path(userId, packageName,
            kPrimaryProfileName, /*is_secondary_dex*/false);
    // read-write only for the app user.
    if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) {
        PLOG(ERROR) << "Failed to prepare " << profile_file;
        return false;
    }

    const std::string ref_profile_path =
            create_primary_reference_profile_package_dir_path(packageName);

@@ -545,16 +533,17 @@ binder::Status InstalldNativeService::migrateAppData(const std::unique_ptr<std::
}


binder::Status InstalldNativeService::clearAppProfiles(const std::string& packageName) {
binder::Status InstalldNativeService::clearAppProfiles(const std::string& packageName,
        const std::string& profileName) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    binder::Status res = ok();
    if (!clear_primary_reference_profile(packageName, kPrimaryProfileName)) {
    if (!clear_primary_reference_profile(packageName, profileName)) {
        res = error("Failed to clear reference profile for " + packageName);
    }
    if (!clear_primary_current_profiles(packageName, kPrimaryProfileName)) {
    if (!clear_primary_current_profiles(packageName, profileName)) {
        res = error("Failed to clear current profiles for " + packageName);
    }
    return res;
@@ -604,11 +593,6 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
                res = error("Failed to delete contents of " + path);
            }
        }
        if (!only_cache) {
            if (!clear_primary_current_profile(packageName, kPrimaryProfileName, userId)) {
                res = error("Failed to clear current profile for " + packageName);
            }
        }
    }
    return res;
}
@@ -1856,37 +1840,34 @@ binder::Status InstalldNativeService::setAppQuota(const std::unique_ptr<std::str
// Dumps the contents of a profile file, using pkgname's dex files for pretty
// printing the result.
binder::Status InstalldNativeService::dumpProfiles(int32_t uid, const std::string& packageName,
        const std::string& codePaths, bool* _aidl_return) {
        const std::string& profileName, const std::string& codePath, bool* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    const char* pkgname = packageName.c_str();
    const char* code_paths = codePaths.c_str();

    *_aidl_return = dump_profiles(uid, pkgname, code_paths);
    *_aidl_return = dump_profiles(uid, packageName, profileName, codePath);
    return ok();
}

// Copy the contents of a system profile over the data profile.
binder::Status InstalldNativeService::copySystemProfile(const std::string& systemProfile,
        int32_t packageUid, const std::string& packageName, bool* _aidl_return) {
        int32_t packageUid, const std::string& packageName, const std::string& profileName,
        bool* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);
    *_aidl_return = copy_system_profile(systemProfile, packageUid, packageName,
            kPrimaryProfileName);
    *_aidl_return = copy_system_profile(systemProfile, packageUid, packageName, profileName);
    return ok();
}

// TODO: Consider returning error codes.
binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
        bool* _aidl_return) {
        const std::string& profileName, bool* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    *_aidl_return = analyze_primary_profiles(uid, packageName, kPrimaryProfileName);
    *_aidl_return = analyze_primary_profiles(uid, packageName, profileName);
    return ok();
}

@@ -1918,7 +1899,8 @@ binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t
        int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
        const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
        const std::unique_ptr<std::string>& classLoaderContext,
        const std::unique_ptr<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion) {
        const std::unique_ptr<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
        const std::unique_ptr<std::string>& profileName) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_UUID(uuid);
    if (packageName && *packageName != "*") {
@@ -1934,10 +1916,10 @@ binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t
    const char* volume_uuid = uuid ? uuid->c_str() : nullptr;
    const char* class_loader_context = classLoaderContext ? classLoaderContext->c_str() : nullptr;
    const char* se_info = seInfo ? seInfo->c_str() : nullptr;

    const char* profile_name = profileName ? profileName->c_str() : nullptr;
    int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded,
            oat_dir, dexFlags, compiler_filter, volume_uuid, class_loader_context, se_info,
            downgrade, targetSdkVersion, kPrimaryProfileName);
            downgrade, targetSdkVersion, profile_name);
    return res ? error(res, "Failed to dexopt") : ok();
}

+9 −7
Original line number Diff line number Diff line
@@ -85,22 +85,24 @@ public:
            const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
            const std::unique_ptr<std::string>& classLoaderContext,
            const std::unique_ptr<std::string>& seInfo, bool downgrade,
            int32_t targetSdkVersion);
            int32_t targetSdkVersion, const std::unique_ptr<std::string>& profileName);

    binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);

    binder::Status mergeProfiles(int32_t uid, const std::string& packageName, bool* _aidl_return);
    binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
            const std::string& profileName, bool* _aidl_return);
    binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
            const std::string& codePaths, bool* _aidl_return);
            const std::string& profileName, const std::string& codePath, bool* _aidl_return);
    binder::Status copySystemProfile(const std::string& systemProfile,
            int32_t uid, const std::string& packageName, bool* _aidl_return);
    binder::Status clearAppProfiles(const std::string& packageName);
            int32_t uid, const std::string& packageName, const std::string& profileName,
            bool* _aidl_return);
    binder::Status clearAppProfiles(const std::string& packageName, const std::string& profileName);
    binder::Status destroyAppProfiles(const std::string& packageName);

    binder::Status createProfileSnapshot(int32_t appId, const std::string& packageName,
            const std::string& codePath, bool* _aidl_return);
            const std::string& profileName, bool* _aidl_return);
    binder::Status destroyProfileSnapshot(const std::string& packageName,
            const std::string& codePath);
            const std::string& profileName);

    binder::Status idmap(const std::string& targetApkPath, const std::string& overlayApkPath,
            int32_t uid);
+9 −7
Original line number Diff line number Diff line
@@ -51,20 +51,22 @@ interface IInstalld {
            @nullable @utf8InCpp String outputPath, int dexFlags,
            @utf8InCpp String compilerFilter, @nullable @utf8InCpp String uuid,
            @nullable @utf8InCpp String sharedLibraries,
            @nullable @utf8InCpp String seInfo, boolean downgrade, int targetSdkVersion);
            @nullable @utf8InCpp String seInfo, boolean downgrade, int targetSdkVersion,
            @nullable @utf8InCpp String profileName);

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

    boolean mergeProfiles(int uid, @utf8InCpp String packageName);
    boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String codePaths);
    boolean 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,
            @utf8InCpp String packageName);
    void clearAppProfiles(@utf8InCpp String packageName);
            @utf8InCpp String packageName, @utf8InCpp String profileName);
    void clearAppProfiles(@utf8InCpp String packageName, @utf8InCpp String profileName);
    void destroyAppProfiles(@utf8InCpp String packageName);

    boolean createProfileSnapshot(int appId, @utf8InCpp String packageName,
            @utf8InCpp String codePath);
    void destroyProfileSnapshot(@utf8InCpp String packageName, @utf8InCpp String codePath);
            @utf8InCpp String profileName);
    void destroyProfileSnapshot(@utf8InCpp String packageName, @utf8InCpp String profileName);

    void idmap(@utf8InCpp String targetApkPath, @utf8InCpp String overlayApkPath, int uid);
    void removeIdmap(@utf8InCpp String overlayApkPath);
+14 −15
Original line number Diff line number Diff line
@@ -876,13 +876,14 @@ static void run_profman_dump(const std::vector<unique_fd>& profile_fds,
    exit(68);   /* only get here on exec failure */
}

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

    // TODO(calin): get the profile name as a parameter.
    open_profile_files(uid, pkgname, "primary.prof", /*is_secondary_dex*/false,
    open_profile_files(uid, pkgname, profile_name, /*is_secondary_dex*/false,
            &profile_fds, &reference_profile_fd);

    const bool has_reference_profile = (reference_profile_fd.get() != -1);
@@ -896,22 +897,20 @@ bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_pat
    unique_fd output_fd(open(out_file_name.c_str(),
            O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644));
    if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
        ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
        LOG(ERROR) << "installd cannot chmod file for dump_profile" << out_file_name;
        return false;
    }
    std::vector<std::string> code_full_paths = base::Split(code_paths, ";");

    std::vector<std::string> dex_locations;
    std::vector<unique_fd> apk_fds;
    for (const std::string& code_full_path : code_full_paths) {
        const char* full_path = code_full_path.c_str();
        unique_fd apk_fd(open(full_path, O_RDONLY | O_NOFOLLOW));
    unique_fd apk_fd(open(code_path.c_str(), O_RDONLY | O_NOFOLLOW));
    if (apk_fd == -1) {
            ALOGE("installd cannot open '%s'\n", full_path);
        PLOG(ERROR) << "installd cannot open " << code_path.c_str();
        return false;
    }
        dex_locations.push_back(get_location_from_path(full_path));
    dex_locations.push_back(get_location_from_path(code_path.c_str()));
    apk_fds.push_back(std::move(apk_fd));
    }


    pid_t pid = fork();
    if (pid == 0) {
+4 −1
Original line number Diff line number Diff line
@@ -63,7 +63,10 @@ bool analyze_primary_profiles(uid_t uid,
bool create_profile_snapshot(int32_t app_id, const std::string& package,
        const std::string& profile_name);

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

bool copy_system_profile(const std::string& system_profile,
                         uid_t packageUid,
Loading