diff options
author | 2019-11-20 14:20:40 +0800 | |
---|---|---|
committer | 2019-12-18 14:13:26 +0800 | |
commit | 2a0a246603f9fe167d6f868667538d86092d8856 (patch) | |
tree | 29fc63375403f1102d82c00c23712ed95353d476 /cmds/installd/CrateManager.cpp | |
parent | 1730b0be85f5005ffef0e9f2a68727045b039218 (diff) |
add function to traversal the crates
The system_server needs to traversal Context.getCratesDir() to get all
of crates. But, system_server doesn't have the permission. system_server
needs installd to traverse Context.getCratesDir().
The depth of traversal in Context.getCratesDir is 1. installd returns the
list CrateMetadata. CrateMetadata contains the following information.
* crateName: it is the folder name
To add .gitigTo add .gitignore to collect the ignore file list.
Test: atest \
CtsOsTestCases:android.os.storage.cts.CrateInfoTest \
CtsOsTestCases:android.os.storage.cts.StorageManagerCratesTest \
CtsOsTestCases:android.os.storage.cts.StorageStatsManagerTest
Bug: 141660526
Change-Id: Iea5eee4606e4ff437edef617a1f8db93e37f51c4
Diffstat (limited to 'cmds/installd/CrateManager.cpp')
-rw-r--r-- | cmds/installd/CrateManager.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/cmds/installd/CrateManager.cpp b/cmds/installd/CrateManager.cpp new file mode 100644 index 0000000000..344aefbcbe --- /dev/null +++ b/cmds/installd/CrateManager.cpp @@ -0,0 +1,129 @@ +/* + * 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 |