1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker * Copyright (C) 2017 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 #ifndef ANDROID_VINTF_UTILS_H
18*70a7ec85SAndroid Build Coastguard Worker #define ANDROID_VINTF_UTILS_H
19*70a7ec85SAndroid Build Coastguard Worker
20*70a7ec85SAndroid Build Coastguard Worker #include <memory>
21*70a7ec85SAndroid Build Coastguard Worker #include <mutex>
22*70a7ec85SAndroid Build Coastguard Worker
23*70a7ec85SAndroid Build Coastguard Worker #include <utils/Errors.h>
24*70a7ec85SAndroid Build Coastguard Worker #include <vintf/FileSystem.h>
25*70a7ec85SAndroid Build Coastguard Worker #include <vintf/PropertyFetcher.h>
26*70a7ec85SAndroid Build Coastguard Worker #include <vintf/RuntimeInfo.h>
27*70a7ec85SAndroid Build Coastguard Worker #include <vintf/parse_xml.h>
28*70a7ec85SAndroid Build Coastguard Worker
29*70a7ec85SAndroid Build Coastguard Worker // Equality for timespec. This should be in global namespace where timespec
30*70a7ec85SAndroid Build Coastguard Worker // is defined.
31*70a7ec85SAndroid Build Coastguard Worker
32*70a7ec85SAndroid Build Coastguard Worker inline bool operator==(const timespec& a, const timespec& b) noexcept {
33*70a7ec85SAndroid Build Coastguard Worker return a.tv_sec == b.tv_sec && a.tv_nsec == b.tv_nsec;
34*70a7ec85SAndroid Build Coastguard Worker }
35*70a7ec85SAndroid Build Coastguard Worker
36*70a7ec85SAndroid Build Coastguard Worker inline bool operator!=(const timespec& a, const timespec& b) noexcept {
37*70a7ec85SAndroid Build Coastguard Worker return !(a == b);
38*70a7ec85SAndroid Build Coastguard Worker }
39*70a7ec85SAndroid Build Coastguard Worker
40*70a7ec85SAndroid Build Coastguard Worker namespace android {
41*70a7ec85SAndroid Build Coastguard Worker namespace vintf {
42*70a7ec85SAndroid Build Coastguard Worker namespace details {
43*70a7ec85SAndroid Build Coastguard Worker
44*70a7ec85SAndroid Build Coastguard Worker template <typename T>
fetchAllInformation(const FileSystem * fileSystem,const std::string & path,T * outObject,std::string * error)45*70a7ec85SAndroid Build Coastguard Worker status_t fetchAllInformation(const FileSystem* fileSystem, const std::string& path, T* outObject,
46*70a7ec85SAndroid Build Coastguard Worker std::string* error) {
47*70a7ec85SAndroid Build Coastguard Worker if (outObject->fileName().empty()) {
48*70a7ec85SAndroid Build Coastguard Worker outObject->setFileName(path);
49*70a7ec85SAndroid Build Coastguard Worker } else {
50*70a7ec85SAndroid Build Coastguard Worker outObject->setFileName(outObject->fileName() + ":" + path);
51*70a7ec85SAndroid Build Coastguard Worker }
52*70a7ec85SAndroid Build Coastguard Worker
53*70a7ec85SAndroid Build Coastguard Worker std::string info;
54*70a7ec85SAndroid Build Coastguard Worker status_t result = fileSystem->fetch(path, &info, error);
55*70a7ec85SAndroid Build Coastguard Worker
56*70a7ec85SAndroid Build Coastguard Worker if (result != OK) {
57*70a7ec85SAndroid Build Coastguard Worker return result;
58*70a7ec85SAndroid Build Coastguard Worker }
59*70a7ec85SAndroid Build Coastguard Worker
60*70a7ec85SAndroid Build Coastguard Worker bool success = fromXml(outObject, info, error);
61*70a7ec85SAndroid Build Coastguard Worker if (!success) {
62*70a7ec85SAndroid Build Coastguard Worker if (error) {
63*70a7ec85SAndroid Build Coastguard Worker *error = "Illformed file: " + path + ": " + *error;
64*70a7ec85SAndroid Build Coastguard Worker }
65*70a7ec85SAndroid Build Coastguard Worker return BAD_VALUE;
66*70a7ec85SAndroid Build Coastguard Worker }
67*70a7ec85SAndroid Build Coastguard Worker return OK;
68*70a7ec85SAndroid Build Coastguard Worker }
69*70a7ec85SAndroid Build Coastguard Worker
70*70a7ec85SAndroid Build Coastguard Worker class PropertyFetcherImpl : public PropertyFetcher {
71*70a7ec85SAndroid Build Coastguard Worker public:
72*70a7ec85SAndroid Build Coastguard Worker virtual std::string getProperty(const std::string& key,
73*70a7ec85SAndroid Build Coastguard Worker const std::string& defaultValue = "") const;
74*70a7ec85SAndroid Build Coastguard Worker virtual uint64_t getUintProperty(const std::string& key, uint64_t defaultValue,
75*70a7ec85SAndroid Build Coastguard Worker uint64_t max = UINT64_MAX) const;
76*70a7ec85SAndroid Build Coastguard Worker virtual bool getBoolProperty(const std::string& key, bool defaultValue) const;
77*70a7ec85SAndroid Build Coastguard Worker };
78*70a7ec85SAndroid Build Coastguard Worker
79*70a7ec85SAndroid Build Coastguard Worker class PropertyFetcherNoOp : public PropertyFetcher {
80*70a7ec85SAndroid Build Coastguard Worker public:
81*70a7ec85SAndroid Build Coastguard Worker virtual std::string getProperty(const std::string& key,
82*70a7ec85SAndroid Build Coastguard Worker const std::string& defaultValue = "") const override;
83*70a7ec85SAndroid Build Coastguard Worker virtual uint64_t getUintProperty(const std::string& key, uint64_t defaultValue,
84*70a7ec85SAndroid Build Coastguard Worker uint64_t max = UINT64_MAX) const override;
85*70a7ec85SAndroid Build Coastguard Worker virtual bool getBoolProperty(const std::string& key, bool defaultValue) const override;
86*70a7ec85SAndroid Build Coastguard Worker };
87*70a7ec85SAndroid Build Coastguard Worker
88*70a7ec85SAndroid Build Coastguard Worker // Merge src into dst.
89*70a7ec85SAndroid Build Coastguard Worker // postcondition (if successful): *src == empty.
90*70a7ec85SAndroid Build Coastguard Worker template <typename T>
91*70a7ec85SAndroid Build Coastguard Worker static bool mergeField(T* dst, T* src, const T& empty = T{}) {
92*70a7ec85SAndroid Build Coastguard Worker if (*dst == *src) {
93*70a7ec85SAndroid Build Coastguard Worker *src = empty;
94*70a7ec85SAndroid Build Coastguard Worker return true; // no conflict
95*70a7ec85SAndroid Build Coastguard Worker }
96*70a7ec85SAndroid Build Coastguard Worker if (*src == empty) {
97*70a7ec85SAndroid Build Coastguard Worker return true;
98*70a7ec85SAndroid Build Coastguard Worker }
99*70a7ec85SAndroid Build Coastguard Worker if (*dst == empty) {
100*70a7ec85SAndroid Build Coastguard Worker *dst = std::move(*src);
101*70a7ec85SAndroid Build Coastguard Worker *src = empty;
102*70a7ec85SAndroid Build Coastguard Worker return true;
103*70a7ec85SAndroid Build Coastguard Worker }
104*70a7ec85SAndroid Build Coastguard Worker return false;
105*70a7ec85SAndroid Build Coastguard Worker }
106*70a7ec85SAndroid Build Coastguard Worker
107*70a7ec85SAndroid Build Coastguard Worker // Check legacy instances (i.e. <version> + <interface> + <instance>) can be
108*70a7ec85SAndroid Build Coastguard Worker // converted into FqInstance because forEachInstance relies on FqInstance.
109*70a7ec85SAndroid Build Coastguard Worker // If error and appendedError is not null, error message is appended to appendedError.
110*70a7ec85SAndroid Build Coastguard Worker // Return the corresponding value in <fqname> (i.e. @ver::Interface/instance for
111*70a7ec85SAndroid Build Coastguard Worker // HIDL, Interface/instance for AIDL, @ver[::Interface]/instance for native)
112*70a7ec85SAndroid Build Coastguard Worker [[nodiscard]] std::optional<FqInstance> convertLegacyInstanceIntoFqInstance(
113*70a7ec85SAndroid Build Coastguard Worker const std::string& package, const Version& version, const std::string& interface,
114*70a7ec85SAndroid Build Coastguard Worker const std::string& instance, HalFormat format, std::string* appendedError);
115*70a7ec85SAndroid Build Coastguard Worker
116*70a7ec85SAndroid Build Coastguard Worker bool isCoreHal(const std::string& halName);
117*70a7ec85SAndroid Build Coastguard Worker
118*70a7ec85SAndroid Build Coastguard Worker } // namespace details
119*70a7ec85SAndroid Build Coastguard Worker } // namespace vintf
120*70a7ec85SAndroid Build Coastguard Worker } // namespace android
121*70a7ec85SAndroid Build Coastguard Worker
122*70a7ec85SAndroid Build Coastguard Worker
123*70a7ec85SAndroid Build Coastguard Worker
124*70a7ec85SAndroid Build Coastguard Worker #endif
125