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