• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #ifdef ENABLE_STORAGE_CRATES
20 
21 #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 
32 #include <utils.h>
33 #include <fstream>
34 #include <functional>
35 #include <string>
36 
37 #include "utils.h"
38 
39 using android::base::StringPrintf;
40 
41 namespace android {
42 namespace installd {
43 
CrateManager(const char * uuid,userid_t userId,const std::string & packageName)44 CrateManager::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 
~CrateManager()50 CrateManager::~CrateManager() {}
51 
getValidatedCratedPath(std::string path)52 static 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 
traverseChildDir(const std::string & targetDir,std::function<void (FTSENT *)> & onVisitChildDir)61 void 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 
traverseAllPackagesForUser(const std::optional<std::string> & uuid,userid_t userId,std::function<void (FTSENT *)> & onHandlingPackage)89 void CrateManager::traverseAllPackagesForUser(
90         const std::optional<std::string>& uuid, userid_t userId,
91         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 
createCrate(CratedFolder cratedFolder,std::function<void (CratedFolder,CrateMetadata &&)> & onCreateCrate)98 void CrateManager::createCrate(
99         CratedFolder cratedFolder,
100         std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) {
101     const char* path = cratedFolder->fts_path;
102     if (path == nullptr || *path == '\0') {
103         return;
104     }
105 
106     CrateMetadata crateMetadata;
107     crateMetadata.uid = cratedFolder->fts_statp->st_uid;
108     crateMetadata.packageName = mPackageName;
109     crateMetadata.id = getValidatedCratedPath(path);
110 
111     onCreateCrate(cratedFolder, std::move(crateMetadata));
112 }
113 
traverseAllCrates(std::function<void (CratedFolder,CrateMetadata &&)> & onCreateCrate)114 void CrateManager::traverseAllCrates(std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) {
115     std::function<void(FTSENT*)> onVisitCrateDir = [&](FTSENT* cratedFolder) -> void {
116         createCrate(cratedFolder, onCreateCrate);
117     };
118     traverseChildDir(mCratedFoldersRoot, onVisitCrateDir);
119 }
120 
121 #if CRATE_DEBUG
dump(const CrateMetadata & CrateMetadata)122 void CrateManager::dump(const CrateMetadata& CrateMetadata) {
123     LOG(DEBUG) << "CrateMetadata = {"
124             << "uid : \"" << CrateMetadata.uid
125             << "\", packageName : \"" << CrateMetadata.packageName
126             << "\", id : \"" << CrateMetadata.id
127             << "\"}";
128 }
129 #endif
130 
131 } // namespace installd
132 } // namespace android
133 
134 #endif // ENABLE_STORAGE_CRATES