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

Commit f24033eb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "add function to traversal the crates"

parents 8914b952 2a0a2466
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
# ignore the files generated by intellij
.idea
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ cc_defaults {
    srcs: [
        "CacheItem.cpp",
        "CacheTracker.cpp",
        "CrateManager.cpp",
        "InstalldNativeService.cpp",
        "QuotaUtils.cpp",
        "dexopt.cpp",
@@ -163,6 +164,7 @@ filegroup {
    name: "installd_aidl",
    srcs: [
        "binder/android/os/IInstalld.aidl",
        "binder/android/os/storage/CrateMetadata.aidl",
    ],
    path: "binder",
}
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 "CrateManager.h"

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android/log.h>
#include <errno.h>
#include <inttypes.h>
#include <libgen.h>
#include <stdint.h>
#include <string.h>
#include <sys/xattr.h>
#include <unistd.h>

#include <fstream>
#include <string>
#include <utils.h>

#include "utils.h"

using android::base::StringPrintf;

namespace android {
namespace installd {

CrateManager::CrateManager(const char* uuid, userid_t userId, const std::string& packageName) {
    mPackageName = packageName;
    mRoot = create_data_user_ce_package_path(uuid, userId, (const char*)packageName.c_str());
    mCratedFoldersRoot = StringPrintf("%s/crates", mRoot.c_str());
}

CrateManager::~CrateManager() {}

static std::string getValidatedCratedPath(std::string path) {
    size_t pos = path.rfind("/");
    if (pos == std::string::npos) {
        return path;
    }

    return path.substr(pos + 1, path.length());
}

void CrateManager::traverseChildDir(const std::string& targetDir,
    std::function<void(FTSENT*)>& onVisitChildDir) {
    char* argv[] = {(char*)targetDir.c_str(), nullptr};
    FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr);
    if (fts == nullptr) {
        PLOG(WARNING) << "Failed to fts_open " << targetDir;
        return;
    }

    FTSENT* p;
    while ((p = fts_read(fts)) != nullptr) {
        switch (p->fts_info) {
            case FTS_D:
                if (p->fts_level == 1) {
                    onVisitChildDir(p);
                }
                break;
            default:
                break;
        }

        if (p->fts_level == 1) {
            fts_set(fts, p, FTS_SKIP);
        }
    }
    fts_close(fts);
}

void CrateManager::traverseAllPackagesForUser(
        const std::unique_ptr<std::string>& uuid, userid_t userId,
        std::function<void(FTSENT*)>& onHandlingPackage) {
    const char* uuid_ = uuid ? uuid->c_str() : nullptr;

    auto ce_path = create_data_user_ce_path(uuid_, userId);
    traverseChildDir(ce_path, onHandlingPackage);
}

void CrateManager::createCrate(
        CratedFolder cratedFolder,
        std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate) {
    const char* path = cratedFolder->fts_path;
    if (path == nullptr || *path == '\0') {
        return;
    }

    std::unique_ptr<CrateMetadata> crateMetadata = std::make_unique<CrateMetadata>();
    crateMetadata->uid = cratedFolder->fts_statp->st_uid;
    crateMetadata->packageName = mPackageName;
    crateMetadata->id = getValidatedCratedPath(path);

    onCreateCrate(cratedFolder, crateMetadata);
}

void CrateManager::traverseAllCrates(std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate) {
    std::function<void(FTSENT*)> onVisitCrateDir = [&](FTSENT* cratedFolder) -> void {
        createCrate(cratedFolder, onCreateCrate);
    };
    traverseChildDir(mCratedFoldersRoot, onVisitCrateDir);
}

#if CRATE_DEBUG
void CrateManager::dump(std::unique_ptr<CrateMetadata>& CrateMetadata) {
    LOG(DEBUG) << "CrateMetadata = {"
            << "uid : \"" << CrateMetadata->uid
            << "\", packageName : \"" << CrateMetadata->packageName
            << "\", id : \"" << CrateMetadata->id
            << "\"}";
}
#endif

} // namespace installd
} // namespace android
+82 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

#ifndef ANDROID_INSTALLD_CRATE_INFO_MANAGER_H
#define ANDROID_INSTALLD_CRATE_INFO_MANAGER_H

#include <android/os/storage/CrateMetadata.h>
#include <cutils/multiuser.h>
#include <fts.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <memory>
#include <string>
#include <vector>

#ifndef CRATE_DEBUG
#define CRATE_DEBUG 1
#endif

namespace android {
namespace installd {

using android::os::storage::CrateMetadata;

/**
 * The crated folder actually is a folder that is the first level child director. In order to
 * distingish between the crated folder and the other FTSENT*, to define the type "CratedFolder"
 * make the code easy to identify the difference.
 */
typedef FTSENT* CratedFolder;

/**
 * In order to give the users more fine-grained files controlling, the crate information can help
 * applications' developers to show the more detail information to the users. The crate information
 * include the Label, Expiration etc..
 */
class CrateManager {
public:
    CrateManager(const char* uuid, userid_t userId, const std::string& packageName);
    ~CrateManager();

    void traverseAllCrates(std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate);

    static void traverseChildDir(const std::string& targetDir,
            std::function<void(FTSENT*)>& onVisitChildDir);

    static void traverseAllPackagesForUser(
        const std::unique_ptr<std::string>& uuid,
        userid_t userId,
        std::function<void(FTSENT*)>& onHandlingPackage);

#if CRATE_DEBUG
    static void dump(std::unique_ptr<CrateMetadata>& CrateMetadata);
#endif
private:
    std::string mRoot;
    std::string mCratedFoldersRoot;
    std::string mPackageName;

    void createCrate(
        CratedFolder cratedFolder,
        std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate);
};

} // namespace installd
} // namespace android

#endif // ANDROID_INSTALLD_CRATE_INFO_MANAGER_H
+77 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@
#include "view_compiler.h"

#include "CacheTracker.h"
#include "CrateManager.h"
#include "MatchExtensionGen.h"
#include "QuotaUtils.h"

@@ -2045,6 +2046,82 @@ binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std:
    return ok();
}

binder::Status InstalldNativeService::getAppCrates(
        const std::unique_ptr<std::string>& uuid,
        const std::vector<std::string>& packageNames, int32_t userId,
        std::unique_ptr<std::vector<std::unique_ptr<CrateMetadata>>>* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_UUID(uuid);
    for (const auto& packageName : packageNames) {
        CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    }
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto retVector = std::make_unique<std::vector<std::unique_ptr<CrateMetadata>>>();
    const char* uuid_ = uuid ? uuid->c_str() : nullptr;

    std::function<void(CratedFolder, std::unique_ptr<CrateMetadata> &)> onCreateCrate =
            [&](CratedFolder cratedFolder, std::unique_ptr<CrateMetadata> &crateMetadata) -> void {
        if (cratedFolder == nullptr) {
            return;
        }
        retVector->push_back(std::move(crateMetadata));
    };

    for (const auto& packageName : packageNames) {
#if CRATE_DEBUG
        LOG(DEBUG) << "packageName = " << packageName;
#endif
        auto crateManager = std::make_unique<CrateManager>(uuid_, userId, packageName);
        crateManager->traverseAllCrates(onCreateCrate);
    }

#if CRATE_DEBUG
    LOG(WARNING) << "retVector->size() =" << retVector->size();
    for (auto iter = retVector->begin(); iter != retVector->end(); ++iter) {
        CrateManager::dump(*iter);
    }
#endif

    *_aidl_return = std::move(retVector);
    return ok();
}

binder::Status InstalldNativeService::getUserCrates(
        const std::unique_ptr<std::string>& uuid, int32_t userId,
        std::unique_ptr<std::vector<std::unique_ptr<CrateMetadata>>>* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_UUID(uuid);
    std::lock_guard<std::recursive_mutex> lock(mLock);

    const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    auto retVector = std::make_unique<std::vector<std::unique_ptr<CrateMetadata>>>();

    std::function<void(CratedFolder, std::unique_ptr<CrateMetadata> &)> onCreateCrate =
            [&](CratedFolder cratedFolder, std::unique_ptr<CrateMetadata> &crateMetadata) -> void {
        if (cratedFolder == nullptr) {
            return;
        }
        retVector->push_back(std::move(crateMetadata));
    };

    std::function<void(FTSENT*)> onHandingPackage = [&](FTSENT* packageDir) -> void {
        auto crateManager = std::make_unique<CrateManager>(uuid_, userId, packageDir->fts_name);
        crateManager->traverseAllCrates(onCreateCrate);
    };
    CrateManager::traverseAllPackagesForUser(uuid, userId, onHandingPackage);

#if CRATE_DEBUG
    LOG(DEBUG) << "retVector->size() =" << retVector->size();
    for (auto iter = retVector->begin(); iter != retVector->end(); ++iter) {
        CrateManager::dump(*iter);
    }
#endif

    *_aidl_return = std::move(retVector);
    return ok();
}

binder::Status InstalldNativeService::setAppQuota(const std::unique_ptr<std::string>& uuid,
        int32_t userId, int32_t appId, int64_t cacheQuota) {
    ENFORCE_UID(AID_SYSTEM);
Loading