blob: fd1df35aee73f692a7d8e09630cf01b7b0864639 [file] [log] [blame]
Felka Chang2a0a2462019-11-20 14:20:40 +08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "CrateManager.h"
18
Felka Chang4df87f62020-02-11 19:08:43 +080019#ifdef ENABLE_STORAGE_CRATES
20
Felka Chang2a0a2462019-11-20 14:20:40 +080021#include <android-base/logging.h>
22#include <android-base/stringprintf.h>
23#include <android/log.h>
24#include <errno.h>
25#include <inttypes.h>
26#include <libgen.h>
27#include <stdint.h>
28#include <string.h>
29#include <sys/xattr.h>
30#include <unistd.h>
31
Felka Chang2a0a2462019-11-20 14:20:40 +080032#include <utils.h>
Ryan Prichard644a5b72023-07-20 21:39:48 -070033#include <fstream>
34#include <functional>
35#include <string>
Felka Chang2a0a2462019-11-20 14:20:40 +080036
37#include "utils.h"
38
39using android::base::StringPrintf;
40
41namespace android {
42namespace installd {
43
44CrateManager::CrateManager(const char* uuid, userid_t userId, const std::string& packageName) {
45 mPackageName = packageName;
46 mRoot = create_data_user_ce_package_path(uuid, userId, (const char*)packageName.c_str());
47 mCratedFoldersRoot = StringPrintf("%s/crates", mRoot.c_str());
48}
49
50CrateManager::~CrateManager() {}
51
52static std::string getValidatedCratedPath(std::string path) {
53 size_t pos = path.rfind("/");
54 if (pos == std::string::npos) {
55 return path;
56 }
57
58 return path.substr(pos + 1, path.length());
59}
60
61void CrateManager::traverseChildDir(const std::string& targetDir,
62 std::function<void(FTSENT*)>& onVisitChildDir) {
63 char* argv[] = {(char*)targetDir.c_str(), nullptr};
64 FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr);
65 if (fts == nullptr) {
66 PLOG(WARNING) << "Failed to fts_open " << targetDir;
67 return;
68 }
69
70 FTSENT* p;
71 while ((p = fts_read(fts)) != nullptr) {
72 switch (p->fts_info) {
73 case FTS_D:
74 if (p->fts_level == 1) {
75 onVisitChildDir(p);
76 }
77 break;
78 default:
79 break;
80 }
81
82 if (p->fts_level == 1) {
83 fts_set(fts, p, FTS_SKIP);
84 }
85 }
86 fts_close(fts);
87}
88
89void CrateManager::traverseAllPackagesForUser(
Jooyung Han2d5878e2020-01-23 12:45:10 +090090 const std::optional<std::string>& uuid, userid_t userId,
Felka Chang2a0a2462019-11-20 14:20:40 +080091 std::function<void(FTSENT*)>& onHandlingPackage) {
92 const char* uuid_ = uuid ? uuid->c_str() : nullptr;
93
94 auto ce_path = create_data_user_ce_path(uuid_, userId);
95 traverseChildDir(ce_path, onHandlingPackage);
96}
97
98void CrateManager::createCrate(
99 CratedFolder cratedFolder,
Jooyung Han2d5878e2020-01-23 12:45:10 +0900100 std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) {
Felka Chang2a0a2462019-11-20 14:20:40 +0800101 const char* path = cratedFolder->fts_path;
102 if (path == nullptr || *path == '\0') {
103 return;
104 }
105
Jooyung Han2d5878e2020-01-23 12:45:10 +0900106 CrateMetadata crateMetadata;
107 crateMetadata.uid = cratedFolder->fts_statp->st_uid;
108 crateMetadata.packageName = mPackageName;
109 crateMetadata.id = getValidatedCratedPath(path);
Felka Chang2a0a2462019-11-20 14:20:40 +0800110
Jooyung Han2d5878e2020-01-23 12:45:10 +0900111 onCreateCrate(cratedFolder, std::move(crateMetadata));
Felka Chang2a0a2462019-11-20 14:20:40 +0800112}
113
Jooyung Han2d5878e2020-01-23 12:45:10 +0900114void CrateManager::traverseAllCrates(std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) {
Felka Chang2a0a2462019-11-20 14:20:40 +0800115 std::function<void(FTSENT*)> onVisitCrateDir = [&](FTSENT* cratedFolder) -> void {
116 createCrate(cratedFolder, onCreateCrate);
117 };
118 traverseChildDir(mCratedFoldersRoot, onVisitCrateDir);
119}
120
121#if CRATE_DEBUG
Jooyung Han2d5878e2020-01-23 12:45:10 +0900122void CrateManager::dump(const CrateMetadata& CrateMetadata) {
Felka Chang2a0a2462019-11-20 14:20:40 +0800123 LOG(DEBUG) << "CrateMetadata = {"
Jooyung Han2d5878e2020-01-23 12:45:10 +0900124 << "uid : \"" << CrateMetadata.uid
125 << "\", packageName : \"" << CrateMetadata.packageName
126 << "\", id : \"" << CrateMetadata.id
Felka Chang2a0a2462019-11-20 14:20:40 +0800127 << "\"}";
128}
129#endif
130
131} // namespace installd
132} // namespace android
Felka Chang4df87f62020-02-11 19:08:43 +0800133
134#endif // ENABLE_STORAGE_CRATES