1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*70a7ec85SAndroid Build Coastguard Worker *
4*70a7ec85SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*70a7ec85SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*70a7ec85SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*70a7ec85SAndroid Build Coastguard Worker *
8*70a7ec85SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*70a7ec85SAndroid Build Coastguard Worker *
10*70a7ec85SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*70a7ec85SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*70a7ec85SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*70a7ec85SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*70a7ec85SAndroid Build Coastguard Worker * limitations under the License.
15*70a7ec85SAndroid Build Coastguard Worker */
16*70a7ec85SAndroid Build Coastguard Worker
17*70a7ec85SAndroid Build Coastguard Worker #include <vintf/HostFileSystem.h>
18*70a7ec85SAndroid Build Coastguard Worker
19*70a7ec85SAndroid Build Coastguard Worker #include <android-base/logging.h>
20*70a7ec85SAndroid Build Coastguard Worker #include <android-base/strings.h>
21*70a7ec85SAndroid Build Coastguard Worker
22*70a7ec85SAndroid Build Coastguard Worker namespace android::vintf::details {
23*70a7ec85SAndroid Build Coastguard Worker
HostFileSystem(const Dirmap & dirmap,status_t missingError)24*70a7ec85SAndroid Build Coastguard Worker HostFileSystem::HostFileSystem(const Dirmap& dirmap, status_t missingError)
25*70a7ec85SAndroid Build Coastguard Worker : HostFileSystem(dirmap, missingError, std::make_unique<FileSystemImpl>()) {}
26*70a7ec85SAndroid Build Coastguard Worker
HostFileSystem(const Dirmap & dirmap,status_t missingError,std::unique_ptr<FileSystem> && impl)27*70a7ec85SAndroid Build Coastguard Worker HostFileSystem::HostFileSystem(const Dirmap& dirmap, status_t missingError,
28*70a7ec85SAndroid Build Coastguard Worker std::unique_ptr<FileSystem>&& impl)
29*70a7ec85SAndroid Build Coastguard Worker : HostFileSystem(dirmap, missingError, impl.get()) {
30*70a7ec85SAndroid Build Coastguard Worker mImplUniq = std::move(impl);
31*70a7ec85SAndroid Build Coastguard Worker }
32*70a7ec85SAndroid Build Coastguard Worker
HostFileSystem(const Dirmap & dirmap,status_t missingError,FileSystem * impl)33*70a7ec85SAndroid Build Coastguard Worker HostFileSystem::HostFileSystem(const Dirmap& dirmap, status_t missingError, FileSystem* impl)
34*70a7ec85SAndroid Build Coastguard Worker : mDirMap(dirmap), mMissingError(missingError), mImpl(impl) {}
35*70a7ec85SAndroid Build Coastguard Worker
fetch(const std::string & path,std::string * fetched,std::string * error) const36*70a7ec85SAndroid Build Coastguard Worker status_t HostFileSystem::fetch(const std::string& path, std::string* fetched,
37*70a7ec85SAndroid Build Coastguard Worker std::string* error) const {
38*70a7ec85SAndroid Build Coastguard Worker auto resolved = resolve(path, error);
39*70a7ec85SAndroid Build Coastguard Worker if (resolved.empty()) {
40*70a7ec85SAndroid Build Coastguard Worker return mMissingError;
41*70a7ec85SAndroid Build Coastguard Worker }
42*70a7ec85SAndroid Build Coastguard Worker status_t status = mImpl->fetch(resolved, fetched, error);
43*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << "Fetch '" << resolved << "': " << statusToString(status);
44*70a7ec85SAndroid Build Coastguard Worker return status;
45*70a7ec85SAndroid Build Coastguard Worker }
46*70a7ec85SAndroid Build Coastguard Worker
listFiles(const std::string & path,std::vector<std::string> * out,std::string * error) const47*70a7ec85SAndroid Build Coastguard Worker status_t HostFileSystem::listFiles(const std::string& path, std::vector<std::string>* out,
48*70a7ec85SAndroid Build Coastguard Worker std::string* error) const {
49*70a7ec85SAndroid Build Coastguard Worker auto resolved = resolve(path, error);
50*70a7ec85SAndroid Build Coastguard Worker if (resolved.empty()) {
51*70a7ec85SAndroid Build Coastguard Worker return mMissingError;
52*70a7ec85SAndroid Build Coastguard Worker }
53*70a7ec85SAndroid Build Coastguard Worker status_t status = mImpl->listFiles(resolved, out, error);
54*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << "List '" << resolved << "': " << statusToString(status);
55*70a7ec85SAndroid Build Coastguard Worker return status;
56*70a7ec85SAndroid Build Coastguard Worker }
57*70a7ec85SAndroid Build Coastguard Worker
modifiedTime(const std::string & path,timespec * mtime,std::string * error) const58*70a7ec85SAndroid Build Coastguard Worker status_t HostFileSystem::modifiedTime(const std::string& path, timespec* mtime,
59*70a7ec85SAndroid Build Coastguard Worker std::string* error) const {
60*70a7ec85SAndroid Build Coastguard Worker auto resolved = resolve(path, error);
61*70a7ec85SAndroid Build Coastguard Worker if (resolved.empty()) {
62*70a7ec85SAndroid Build Coastguard Worker return mMissingError;
63*70a7ec85SAndroid Build Coastguard Worker }
64*70a7ec85SAndroid Build Coastguard Worker status_t status = mImpl->modifiedTime(resolved, mtime, error);
65*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << "Get modified time '" << resolved << "': " << statusToString(status);
66*70a7ec85SAndroid Build Coastguard Worker return status;
67*70a7ec85SAndroid Build Coastguard Worker }
68*70a7ec85SAndroid Build Coastguard Worker
resolve(const std::string & path,std::string * error) const69*70a7ec85SAndroid Build Coastguard Worker std::string HostFileSystem::resolve(const std::string& path, std::string* error) const {
70*70a7ec85SAndroid Build Coastguard Worker for (auto [prefix, mappedPath] : mDirMap) {
71*70a7ec85SAndroid Build Coastguard Worker if (path == prefix) {
72*70a7ec85SAndroid Build Coastguard Worker return mappedPath;
73*70a7ec85SAndroid Build Coastguard Worker }
74*70a7ec85SAndroid Build Coastguard Worker if (android::base::StartsWith(path, prefix + "/")) {
75*70a7ec85SAndroid Build Coastguard Worker return mappedPath + "/" + path.substr(prefix.size() + 1);
76*70a7ec85SAndroid Build Coastguard Worker }
77*70a7ec85SAndroid Build Coastguard Worker }
78*70a7ec85SAndroid Build Coastguard Worker if (error) {
79*70a7ec85SAndroid Build Coastguard Worker *error = "Cannot resolve path " + path;
80*70a7ec85SAndroid Build Coastguard Worker } else {
81*70a7ec85SAndroid Build Coastguard Worker LOG(mMissingError == NAME_NOT_FOUND ? INFO : ERROR) << "Cannot resolve path " << path;
82*70a7ec85SAndroid Build Coastguard Worker }
83*70a7ec85SAndroid Build Coastguard Worker return "";
84*70a7ec85SAndroid Build Coastguard Worker }
85*70a7ec85SAndroid Build Coastguard Worker
86*70a7ec85SAndroid Build Coastguard Worker } // namespace android::vintf::details
87