diff options
-rw-r--r-- | Android.bp | 89 | ||||
-rw-r--r-- | RuntimeInfo-host.cpp | 2 | ||||
-rw-r--r-- | RuntimeInfo-target.cpp | 7 | ||||
-rw-r--r-- | VintfObject.cpp | 65 | ||||
-rw-r--r-- | VintfObjectRecovery.cpp | 5 | ||||
-rw-r--r-- | check_vintf.cpp | 263 | ||||
-rw-r--r-- | include/vintf/DisabledChecks.h | 2 | ||||
-rw-r--r-- | include/vintf/MapValueIterator.h | 20 | ||||
-rw-r--r-- | include/vintf/RuntimeInfo.h | 1 | ||||
-rw-r--r-- | include/vintf/VintfObject.h | 10 | ||||
-rw-r--r-- | test/Android.bp | 5 | ||||
-rw-r--r-- | test/RuntimeInfo-fake.cpp | 12 | ||||
-rw-r--r-- | test/utils-fake.cpp | 14 | ||||
-rw-r--r-- | test/utils-fake.h | 18 | ||||
-rw-r--r-- | test/vintf_object_tests.cpp | 14 | ||||
-rw-r--r-- | utils-common.cpp | 42 | ||||
-rw-r--r-- | utils.cpp | 30 | ||||
-rw-r--r-- | utils.h | 12 |
18 files changed, 488 insertions, 123 deletions
@@ -24,8 +24,10 @@ cc_defaults { | |||
24 | ], | 24 | ], |
25 | } | 25 | } |
26 | 26 | ||
27 | cc_defaults { | 27 | cc_library_static { |
28 | name: "libvintf-common-srcs", | 28 | name: "libvintf_common", |
29 | defaults: ["libvintf-defaults"], | ||
30 | host_supported: true, | ||
29 | srcs: [ | 31 | srcs: [ |
30 | "parse_string.cpp", | 32 | "parse_string.cpp", |
31 | "parse_xml.cpp", | 33 | "parse_xml.cpp", |
@@ -33,6 +35,7 @@ cc_defaults { | |||
33 | "HalManifest.cpp", | 35 | "HalManifest.cpp", |
34 | "HalInterface.cpp", | 36 | "HalInterface.cpp", |
35 | "KernelConfigTypedValue.cpp", | 37 | "KernelConfigTypedValue.cpp", |
38 | "KernelConfigParser.cpp", | ||
36 | "RuntimeInfo.cpp", | 39 | "RuntimeInfo.cpp", |
37 | "ManifestHal.cpp", | 40 | "ManifestHal.cpp", |
38 | "MatrixHal.cpp", | 41 | "MatrixHal.cpp", |
@@ -41,47 +44,55 @@ cc_defaults { | |||
41 | "TransportArch.cpp", | 44 | "TransportArch.cpp", |
42 | "VintfObject.cpp", | 45 | "VintfObject.cpp", |
43 | "XmlFile.cpp", | 46 | "XmlFile.cpp", |
44 | ] | 47 | "utils-common.cpp", |
45 | } | 48 | ], |
46 | |||
47 | cc_library { | ||
48 | name: "libvintf", | ||
49 | host_supported: true, | ||
50 | defaults: ["libvintf-defaults", "libvintf-common-srcs"], | ||
51 | shared_libs: [ | 49 | shared_libs: [ |
52 | "libbase", | 50 | "libbase", |
53 | "liblog", | 51 | "liblog", |
54 | "libselinux", | 52 | "libselinux", |
55 | "libtinyxml2", | 53 | "libtinyxml2", |
54 | "libz", | ||
56 | ], | 55 | ], |
57 | export_include_dirs: ["include"], | 56 | export_include_dirs: ["include", "."], |
58 | local_include_dirs: ["include/vintf"], | 57 | local_include_dirs: ["include/vintf"], |
59 | 58 | ||
60 | srcs: [ | ||
61 | "KernelConfigParser.cpp", | ||
62 | "utils.cpp", | ||
63 | ], | ||
64 | |||
65 | target: { | 59 | target: { |
66 | host: { | 60 | host: { |
67 | srcs: [ | 61 | srcs: [ |
68 | "RuntimeInfo-host.cpp" | 62 | "RuntimeInfo-host.cpp", |
69 | ], | 63 | ], |
70 | }, | 64 | }, |
71 | android: { | 65 | android: { |
72 | shared_libs: [ | ||
73 | "libcutils", | ||
74 | "libutils", | ||
75 | "libz" | ||
76 | ], | ||
77 | srcs: [ | 66 | srcs: [ |
78 | "RuntimeInfo-target.cpp" | 67 | "RuntimeInfo-target.cpp", |
79 | ], | 68 | ], |
80 | cflags: ["-DLIBVINTF_TARGET"], | 69 | cflags: ["-DLIBVINTF_TARGET"], |
81 | }, | 70 | }, |
82 | } | 71 | } |
83 | } | 72 | } |
84 | 73 | ||
74 | // libvintf_common + utils.cpp | ||
75 | cc_library { | ||
76 | name: "libvintf", | ||
77 | host_supported: true, | ||
78 | defaults: ["libvintf-defaults"], | ||
79 | shared_libs: [ | ||
80 | "libbase", | ||
81 | "liblog", | ||
82 | "libselinux", | ||
83 | "libtinyxml2", | ||
84 | "libz", | ||
85 | ], | ||
86 | export_include_dirs: ["include"], | ||
87 | local_include_dirs: ["include/vintf"], | ||
88 | |||
89 | srcs: [ | ||
90 | "utils.cpp", | ||
91 | ], | ||
92 | |||
93 | whole_static_libs: ["libvintf_common"], | ||
94 | } | ||
95 | |||
85 | cc_binary { | 96 | cc_binary { |
86 | name: "vintf", | 97 | name: "vintf", |
87 | defaults: ["libvintf-defaults"], | 98 | defaults: ["libvintf-defaults"], |
@@ -98,7 +109,8 @@ cc_binary_host { | |||
98 | name: "checkvintf", | 109 | name: "checkvintf", |
99 | defaults: ["libvintf-defaults"], | 110 | defaults: ["libvintf-defaults"], |
100 | static_libs: [ | 111 | static_libs: [ |
101 | "libvintf", | 112 | "libvintf_common", |
113 | "libutils", | ||
102 | "libtinyxml2", | 114 | "libtinyxml2", |
103 | ], | 115 | ], |
104 | shared_libs: [ | 116 | shared_libs: [ |
@@ -106,7 +118,6 @@ cc_binary_host { | |||
106 | ], | 118 | ], |
107 | srcs: [ | 119 | srcs: [ |
108 | "check_vintf.cpp", | 120 | "check_vintf.cpp", |
109 | "utils.cpp" | ||
110 | ], | 121 | ], |
111 | } | 122 | } |
112 | 123 | ||
@@ -138,33 +149,3 @@ cc_binary_host { | |||
138 | "assemble_vintf_main.cpp" | 149 | "assemble_vintf_main.cpp" |
139 | ], | 150 | ], |
140 | } | 151 | } |
141 | |||
142 | cc_library_static { | ||
143 | name: "libvintftest", | ||
144 | defaults: ["libvintf-defaults", "libvintf-common-srcs"], | ||
145 | host_supported: true, | ||
146 | shared_libs: [ | ||
147 | "libbase", | ||
148 | "liblog", | ||
149 | "libselinux", | ||
150 | "libtinyxml2", | ||
151 | ], | ||
152 | export_include_dirs: ["include/vintf", "include", "test", "."], | ||
153 | local_include_dirs: ["include/vintf", "test", "."], | ||
154 | |||
155 | srcs: [ | ||
156 | "test/RuntimeInfo-fake.cpp", | ||
157 | "test/utils-fake.cpp", | ||
158 | ], | ||
159 | |||
160 | target: { | ||
161 | android: { | ||
162 | shared_libs: [ | ||
163 | "libcutils", | ||
164 | "libutils", | ||
165 | "libz" | ||
166 | ], | ||
167 | cflags: ["-DLIBVINTF_TARGET"], | ||
168 | }, | ||
169 | } | ||
170 | } | ||
diff --git a/RuntimeInfo-host.cpp b/RuntimeInfo-host.cpp index bd46a9f..e66e6f4 100644 --- a/RuntimeInfo-host.cpp +++ b/RuntimeInfo-host.cpp | |||
@@ -18,7 +18,7 @@ | |||
18 | #define LOG_TAG "libvintf" | 18 | #define LOG_TAG "libvintf" |
19 | #include <android-base/logging.h> | 19 | #include <android-base/logging.h> |
20 | 20 | ||
21 | #include "RuntimeInfo.h" | 21 | #include <vintf/RuntimeInfo.h> |
22 | 22 | ||
23 | namespace android { | 23 | namespace android { |
24 | namespace vintf { | 24 | namespace vintf { |
diff --git a/RuntimeInfo-target.cpp b/RuntimeInfo-target.cpp index 1bdf2c3..6f2e9e8 100644 --- a/RuntimeInfo-target.cpp +++ b/RuntimeInfo-target.cpp | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <iostream> | 33 | #include <iostream> |
34 | #include <sstream> | 34 | #include <sstream> |
35 | 35 | ||
36 | #include <cutils/properties.h> | 36 | #include <android-base/properties.h> |
37 | #include <selinux/selinux.h> | 37 | #include <selinux/selinux.h> |
38 | #include <zlib.h> | 38 | #include <zlib.h> |
39 | 39 | ||
@@ -148,12 +148,11 @@ status_t RuntimeInfoFetcher::parseKernelVersion() { | |||
148 | } | 148 | } |
149 | 149 | ||
150 | status_t RuntimeInfoFetcher::fetchAvb() { | 150 | status_t RuntimeInfoFetcher::fetchAvb() { |
151 | char prop[PROPERTY_VALUE_MAX]; | 151 | std::string prop = android::base::GetProperty("ro.boot.vbmeta.avb_version", "0.0"); |
152 | property_get("ro.boot.vbmeta.avb_version", prop, "0.0"); | ||
153 | if (!parse(prop, &mRuntimeInfo->mBootVbmetaAvbVersion)) { | 152 | if (!parse(prop, &mRuntimeInfo->mBootVbmetaAvbVersion)) { |
154 | return UNKNOWN_ERROR; | 153 | return UNKNOWN_ERROR; |
155 | } | 154 | } |
156 | property_get("ro.boot.avb_version", prop, "0.0"); | 155 | prop = android::base::GetProperty("ro.boot.avb_version", "0.0"); |
157 | if (!parse(prop, &mRuntimeInfo->mBootAvbVersion)) { | 156 | if (!parse(prop, &mRuntimeInfo->mBootAvbVersion)) { |
158 | return UNKNOWN_ERROR; | 157 | return UNKNOWN_ERROR; |
159 | } | 158 | } |
diff --git a/VintfObject.cpp b/VintfObject.cpp index c66011b..c10949c 100644 --- a/VintfObject.cpp +++ b/VintfObject.cpp | |||
@@ -27,10 +27,6 @@ | |||
27 | #include <memory> | 27 | #include <memory> |
28 | #include <mutex> | 28 | #include <mutex> |
29 | 29 | ||
30 | #ifdef LIBVINTF_TARGET | ||
31 | #include <android-base/properties.h> | ||
32 | #endif | ||
33 | |||
34 | #include <android-base/logging.h> | 30 | #include <android-base/logging.h> |
35 | 31 | ||
36 | using std::placeholders::_1; | 32 | using std::placeholders::_1; |
@@ -81,8 +77,7 @@ std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCa | |||
81 | // static | 77 | // static |
82 | std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) { | 78 | std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) { |
83 | static LockedSharedPtr<HalManifest> gFrameworkManifest; | 79 | static LockedSharedPtr<HalManifest> gFrameworkManifest; |
84 | return Get(&gFrameworkManifest, skipCache, | 80 | return Get(&gFrameworkManifest, skipCache, &VintfObject::FetchFrameworkHalManifest); |
85 | std::bind(&HalManifest::fetchAllInformation, _1, kSystemManifest, _2)); | ||
86 | } | 81 | } |
87 | 82 | ||
88 | 83 | ||
@@ -129,15 +124,12 @@ status_t VintfObject::GetCombinedFrameworkMatrix( | |||
129 | } | 124 | } |
130 | 125 | ||
131 | // TODO(b/70628538): Do not infer from Shipping API level. | 126 | // TODO(b/70628538): Do not infer from Shipping API level. |
132 | #ifdef LIBVINTF_TARGET | ||
133 | if (deviceLevel == Level::UNSPECIFIED) { | 127 | if (deviceLevel == Level::UNSPECIFIED) { |
134 | auto shippingApi = | 128 | auto shippingApi = getPropertyFetcher().getUintProperty("ro.product.first_api_level", 0u); |
135 | android::base::GetUintProperty<uint64_t>("ro.product.first_api_level", 0u); | ||
136 | if (shippingApi != 0u) { | 129 | if (shippingApi != 0u) { |
137 | deviceLevel = details::convertFromApiLevel(shippingApi); | 130 | deviceLevel = details::convertFromApiLevel(shippingApi); |
138 | } | 131 | } |
139 | } | 132 | } |
140 | #endif | ||
141 | 133 | ||
142 | if (deviceLevel == Level::UNSPECIFIED) { | 134 | if (deviceLevel == Level::UNSPECIFIED) { |
143 | // Cannot infer FCM version. Combine all matrices by assuming | 135 | // Cannot infer FCM version. Combine all matrices by assuming |
@@ -216,9 +208,8 @@ status_t VintfObject::FetchDeviceHalManifest(HalManifest* out, std::string* erro | |||
216 | status_t VintfObject::FetchOdmHalManifest(HalManifest* out, std::string* error) { | 208 | status_t VintfObject::FetchOdmHalManifest(HalManifest* out, std::string* error) { |
217 | status_t status; | 209 | status_t status; |
218 | 210 | ||
219 | #ifdef LIBVINTF_TARGET | ||
220 | std::string productModel; | 211 | std::string productModel; |
221 | productModel = android::base::GetProperty("ro.boot.product.hardware.sku", ""); | 212 | productModel = getPropertyFetcher().getProperty("ro.boot.product.hardware.sku", ""); |
222 | 213 | ||
223 | if (!productModel.empty()) { | 214 | if (!productModel.empty()) { |
224 | status = | 215 | status = |
@@ -227,14 +218,12 @@ status_t VintfObject::FetchOdmHalManifest(HalManifest* out, std::string* error) | |||
227 | return status; | 218 | return status; |
228 | } | 219 | } |
229 | } | 220 | } |
230 | #endif | ||
231 | 221 | ||
232 | status = FetchOneHalManifest(kOdmManifest, out, error); | 222 | status = FetchOneHalManifest(kOdmManifest, out, error); |
233 | if (status == OK || status != NAME_NOT_FOUND) { | 223 | if (status == OK || status != NAME_NOT_FOUND) { |
234 | return status; | 224 | return status; |
235 | } | 225 | } |
236 | 226 | ||
237 | #ifdef LIBVINTF_TARGET | ||
238 | if (!productModel.empty()) { | 227 | if (!productModel.empty()) { |
239 | status = FetchOneHalManifest(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml", out, | 228 | status = FetchOneHalManifest(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml", out, |
240 | error); | 229 | error); |
@@ -242,7 +231,6 @@ status_t VintfObject::FetchOdmHalManifest(HalManifest* out, std::string* error) | |||
242 | return status; | 231 | return status; |
243 | } | 232 | } |
244 | } | 233 | } |
245 | #endif | ||
246 | 234 | ||
247 | status = FetchOneHalManifest(kOdmLegacyManifest, out, error); | 235 | status = FetchOneHalManifest(kOdmLegacyManifest, out, error); |
248 | if (status == OK || status != NAME_NOT_FOUND) { | 236 | if (status == OK || status != NAME_NOT_FOUND) { |
@@ -273,6 +261,15 @@ status_t VintfObject::FetchDeviceMatrix(CompatibilityMatrix* out, std::string* e | |||
273 | return out->fetchAllInformation(kVendorLegacyMatrix, error); | 261 | return out->fetchAllInformation(kVendorLegacyMatrix, error); |
274 | } | 262 | } |
275 | 263 | ||
264 | status_t VintfObject::FetchFrameworkHalManifest(HalManifest* out, std::string* error) { | ||
265 | HalManifest etcManifest; | ||
266 | if (etcManifest.fetchAllInformation(kSystemManifest, error) == OK) { | ||
267 | *out = std::move(etcManifest); | ||
268 | return OK; | ||
269 | } | ||
270 | return out->fetchAllInformation(kSystemLegacyManifest, error); | ||
271 | } | ||
272 | |||
276 | std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels( | 273 | std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels( |
277 | std::string* error) { | 274 | std::string* error) { |
278 | std::vector<std::string> fileNames; | 275 | std::vector<std::string> fileNames; |
@@ -289,7 +286,7 @@ std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels | |||
289 | status_t status = details::gFetcher->fetch(path, content, &fetchError); | 286 | status_t status = details::gFetcher->fetch(path, content, &fetchError); |
290 | if (status != OK) { | 287 | if (status != OK) { |
291 | if (error) { | 288 | if (error) { |
292 | *error += "Ignore file " + path + ": " + fetchError + "\n"; | 289 | *error += "Framework Matrix: Ignore file " + path + ": " + fetchError + "\n"; |
293 | } | 290 | } |
294 | continue; | 291 | continue; |
295 | } | 292 | } |
@@ -297,7 +294,7 @@ std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels | |||
297 | auto it = results.emplace(results.end()); | 294 | auto it = results.emplace(results.end()); |
298 | if (!gCompatibilityMatrixConverter(&it->object, content, error)) { | 295 | if (!gCompatibilityMatrixConverter(&it->object, content, error)) { |
299 | if (error) { | 296 | if (error) { |
300 | *error += "Ignore file " + path + ": " + *error + "\n"; | 297 | *error += "Framework Matrix: Ignore file " + path + ": " + *error + "\n"; |
301 | } | 298 | } |
302 | results.erase(it); | 299 | results.erase(it); |
303 | continue; | 300 | continue; |
@@ -487,7 +484,9 @@ int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount, | |||
487 | (void)mounter.umountVendor(); // ignore errors | 484 | (void)mounter.umountVendor(); // ignore errors |
488 | } | 485 | } |
489 | 486 | ||
490 | updated.runtimeInfo = VintfObject::GetRuntimeInfo(true /* skipCache */); | 487 | if ((disabledChecks & DISABLE_RUNTIME_INFO) == 0) { |
488 | updated.runtimeInfo = VintfObject::GetRuntimeInfo(true /* skipCache */); | ||
489 | } | ||
491 | 490 | ||
492 | // null checks for files and runtime info after the update | 491 | // null checks for files and runtime info after the update |
493 | if (updated.fwk.manifest == nullptr) { | 492 | if (updated.fwk.manifest == nullptr) { |
@@ -506,9 +505,12 @@ int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount, | |||
506 | ADD_MESSAGE("No device matrix file from device or from update package"); | 505 | ADD_MESSAGE("No device matrix file from device or from update package"); |
507 | return NO_INIT; | 506 | return NO_INIT; |
508 | } | 507 | } |
509 | if (updated.runtimeInfo == nullptr) { | 508 | |
510 | ADD_MESSAGE("No runtime info from device"); | 509 | if ((disabledChecks & DISABLE_RUNTIME_INFO) == 0) { |
511 | return NO_INIT; | 510 | if (updated.runtimeInfo == nullptr) { |
511 | ADD_MESSAGE("No runtime info from device"); | ||
512 | return NO_INIT; | ||
513 | } | ||
512 | } | 514 | } |
513 | 515 | ||
514 | // compatiblity check. | 516 | // compatiblity check. |
@@ -526,11 +528,15 @@ int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount, | |||
526 | } | 528 | } |
527 | return INCOMPATIBLE; | 529 | return INCOMPATIBLE; |
528 | } | 530 | } |
529 | if (!updated.runtimeInfo->checkCompatibility(*updated.fwk.matrix, error, disabledChecks)) { | 531 | |
530 | if (error) { | 532 | if ((disabledChecks & DISABLE_RUNTIME_INFO) == 0) { |
531 | error->insert(0, "Runtime info and framework compatibility matrix are incompatible: "); | 533 | if (!updated.runtimeInfo->checkCompatibility(*updated.fwk.matrix, error, disabledChecks)) { |
534 | if (error) { | ||
535 | error->insert(0, | ||
536 | "Runtime info and framework compatibility matrix are incompatible: "); | ||
537 | } | ||
538 | return INCOMPATIBLE; | ||
532 | } | 539 | } |
533 | return INCOMPATIBLE; | ||
534 | } | 540 | } |
535 | 541 | ||
536 | return COMPATIBLE; | 542 | return COMPATIBLE; |
@@ -547,10 +553,19 @@ const std::string kOdmManifest = kOdmVintfDir + "manifest.xml"; | |||
547 | 553 | ||
548 | const std::string kVendorLegacyManifest = "/vendor/manifest.xml"; | 554 | const std::string kVendorLegacyManifest = "/vendor/manifest.xml"; |
549 | const std::string kVendorLegacyMatrix = "/vendor/compatibility_matrix.xml"; | 555 | const std::string kVendorLegacyMatrix = "/vendor/compatibility_matrix.xml"; |
556 | const std::string kSystemLegacyManifest = "/system/manifest.xml"; | ||
550 | const std::string kSystemLegacyMatrix = "/system/compatibility_matrix.xml"; | 557 | const std::string kSystemLegacyMatrix = "/system/compatibility_matrix.xml"; |
551 | const std::string kOdmLegacyVintfDir = "/odm/etc/"; | 558 | const std::string kOdmLegacyVintfDir = "/odm/etc/"; |
552 | const std::string kOdmLegacyManifest = kOdmLegacyVintfDir + "manifest.xml"; | 559 | const std::string kOdmLegacyManifest = kOdmLegacyVintfDir + "manifest.xml"; |
553 | 560 | ||
561 | std::vector<std::string> dumpFileList() { | ||
562 | return { | ||
563 | kSystemVintfDir, kVendorVintfDir, kOdmVintfDir, kOdmLegacyVintfDir, | ||
564 | |||
565 | kVendorLegacyManifest, kVendorLegacyMatrix, kSystemLegacyManifest, kSystemLegacyMatrix, | ||
566 | }; | ||
567 | } | ||
568 | |||
554 | } // namespace details | 569 | } // namespace details |
555 | 570 | ||
556 | // static | 571 | // static |
diff --git a/VintfObjectRecovery.cpp b/VintfObjectRecovery.cpp index 59fe6da..9d7cab7 100644 --- a/VintfObjectRecovery.cpp +++ b/VintfObjectRecovery.cpp | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include "VintfObjectRecovery.h" | 17 | #include "VintfObjectRecovery.h" |
18 | 18 | ||
19 | #include <android-base/properties.h> | ||
20 | #include <sys/mount.h> | 19 | #include <sys/mount.h> |
21 | #include <fs_mgr.h> | 20 | #include <fs_mgr.h> |
22 | 21 | ||
@@ -48,7 +47,7 @@ class RecoveryPartitionMounter : public PartitionMounter { | |||
48 | if (fstab == NULL) { | 47 | if (fstab == NULL) { |
49 | return UNKNOWN_ERROR; | 48 | return UNKNOWN_ERROR; |
50 | } | 49 | } |
51 | if (android::base::GetBoolProperty("ro.build.system_root_image", false)) { | 50 | if (getPropertyFetcher().getBoolProperty("ro.build.system_root_image", false)) { |
52 | return mountAt(fstab, "/", "/system_root"); | 51 | return mountAt(fstab, "/", "/system_root"); |
53 | } else { | 52 | } else { |
54 | return mountAt(fstab, "/system", "/system"); | 53 | return mountAt(fstab, "/system", "/system"); |
@@ -64,7 +63,7 @@ class RecoveryPartitionMounter : public PartitionMounter { | |||
64 | } | 63 | } |
65 | 64 | ||
66 | status_t umountSystem() const override { | 65 | status_t umountSystem() const override { |
67 | if (android::base::GetBoolProperty("ro.build.system_root_image", false)) { | 66 | if (getPropertyFetcher().getBoolProperty("ro.build.system_root_image", false)) { |
68 | return umount("/system_root"); | 67 | return umount("/system_root"); |
69 | } else { | 68 | } else { |
70 | return umount("/system"); | 69 | return umount("/system"); |
diff --git a/check_vintf.cpp b/check_vintf.cpp index f64f81d..6acc311 100644 --- a/check_vintf.cpp +++ b/check_vintf.cpp | |||
@@ -14,14 +14,119 @@ | |||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <getopt.h> | ||
18 | #include <unistd.h> | ||
19 | |||
17 | #include <iostream> | 20 | #include <iostream> |
21 | #include <map> | ||
18 | 22 | ||
23 | #include <android-base/parseint.h> | ||
24 | #include <utils/Errors.h> | ||
25 | #include <vintf/VintfObject.h> | ||
19 | #include <vintf/parse_xml.h> | 26 | #include <vintf/parse_xml.h> |
20 | #include "utils.h" | 27 | #include "utils.h" |
21 | 28 | ||
22 | namespace android { | 29 | namespace android { |
23 | namespace vintf { | 30 | namespace vintf { |
31 | namespace details { | ||
32 | |||
33 | // fake sysprops | ||
34 | using Properties = std::map<std::string, std::string>; | ||
35 | |||
36 | enum Option : int { | ||
37 | DUMP_FILE_LIST = 1, | ||
38 | ROOTDIR, | ||
39 | HELP, | ||
40 | PROPERTY, | ||
41 | CHECK_COMPAT, | ||
42 | }; | ||
43 | // command line arguments | ||
44 | using Args = std::multimap<Option, std::string>; | ||
45 | |||
46 | class HostFileFetcher : public FileFetcher { | ||
47 | public: | ||
48 | void setRootDir(const std::string& rootdir) { | ||
49 | mRootDir = rootdir; | ||
50 | if (!mRootDir.empty() && mRootDir.back() != '/') { | ||
51 | mRootDir.push_back('/'); | ||
52 | } | ||
53 | } | ||
54 | virtual status_t fetch(const std::string& path, std::string& fetched, std::string* error) { | ||
55 | return HostFileFetcher::fetchInternal(path, fetched, error); | ||
56 | } | ||
57 | virtual status_t fetch(const std::string& path, std::string& fetched) { | ||
58 | return HostFileFetcher::fetchInternal(path, fetched, nullptr); | ||
59 | } | ||
60 | virtual status_t listFiles(const std::string& path, std::vector<std::string>* out, | ||
61 | std::string* error) { | ||
62 | status_t status = FileFetcher::listFiles(mRootDir + path, out, error); | ||
63 | std::cerr << "Debug: List '" << mRootDir << path << "': " << toString(status) << std::endl; | ||
64 | return status; | ||
65 | } | ||
66 | |||
67 | private: | ||
68 | status_t fetchInternal(const std::string& path, std::string& fetched, std::string* error) { | ||
69 | status_t status = FileFetcher::fetchInternal(mRootDir + path, fetched, error); | ||
70 | std::cerr << "Debug: Fetch '" << mRootDir << path << "': " << toString(status) << std::endl; | ||
71 | return status; | ||
72 | } | ||
73 | static std::string toString(status_t status) { | ||
74 | return status == OK ? "SUCCESS" : strerror(-status); | ||
75 | } | ||
76 | std::string mRootDir; | ||
77 | }; | ||
78 | |||
79 | class PresetPropertyFetcher : public PropertyFetcher { | ||
80 | public: | ||
81 | std::string getProperty(const std::string& key, | ||
82 | const std::string& defaultValue) const override { | ||
83 | auto it = mProps.find(key); | ||
84 | if (it == mProps.end()) { | ||
85 | std::cerr << "Debug: Sysprop " << key << " is missing, default to '" << defaultValue | ||
86 | << "'" << std::endl; | ||
87 | return defaultValue; | ||
88 | } | ||
89 | std::cerr << "Debug: Sysprop " << key << "=" << it->second << std::endl; | ||
90 | return it->second; | ||
91 | } | ||
92 | uint64_t getUintProperty(const std::string& key, uint64_t defaultValue, | ||
93 | uint64_t max) const override { | ||
94 | uint64_t result; | ||
95 | std::string value = getProperty(key, ""); | ||
96 | if (!value.empty() && android::base::ParseUint(value, &result, max)) return result; | ||
97 | return defaultValue; | ||
98 | } | ||
99 | bool getBoolProperty(const std::string& key, bool defaultValue) const override { | ||
100 | std::string value = getProperty(key, ""); | ||
101 | if (value == "1" || value == "true") { | ||
102 | return true; | ||
103 | } else if (value == "0" || value == "false") { | ||
104 | return false; | ||
105 | } | ||
106 | return defaultValue; | ||
107 | } | ||
108 | void setProperties(const Properties& props) { mProps.insert(props.begin(), props.end()); } | ||
109 | |||
110 | private: | ||
111 | std::map<std::string, std::string> mProps; | ||
112 | }; | ||
24 | 113 | ||
114 | // globals | ||
115 | static HostFileFetcher hostFileFetcher; | ||
116 | FileFetcher* gFetcher = &hostFileFetcher; | ||
117 | |||
118 | static PartitionMounter partitionMounter; | ||
119 | PartitionMounter* gPartitionMounter = &partitionMounter; | ||
120 | |||
121 | static ObjectFactory<RuntimeInfo> runtimeInfoFactory; | ||
122 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory; | ||
123 | |||
124 | static PresetPropertyFetcher hostPropertyFetcher; | ||
125 | const PropertyFetcher& getPropertyFetcher() { | ||
126 | return hostPropertyFetcher; | ||
127 | } | ||
128 | |||
129 | // helper functions | ||
25 | template <typename T> | 130 | template <typename T> |
26 | std::unique_ptr<T> readObject(const std::string& path, const XmlConverter<T>& converter) { | 131 | std::unique_ptr<T> readObject(const std::string& path, const XmlConverter<T>& converter) { |
27 | std::string xml; | 132 | std::string xml; |
@@ -40,20 +145,9 @@ std::unique_ptr<T> readObject(const std::string& path, const XmlConverter<T>& co | |||
40 | return ret; | 145 | return ret; |
41 | } | 146 | } |
42 | 147 | ||
43 | } // namespace vintf | 148 | int checkCompatibilityForFiles(const std::string& manifestPath, const std::string& matrixPath) { |
44 | } // namespace android | 149 | auto manifest = readObject(manifestPath, gHalManifestConverter); |
45 | 150 | auto matrix = readObject(matrixPath, gCompatibilityMatrixConverter); | |
46 | int main(int argc, char** argv) { | ||
47 | using namespace android::vintf; | ||
48 | if (argc < 3) { | ||
49 | std::cerr << "usage: " << argv[0] << " <manifest.xml> <matrix.xml>" << std::endl | ||
50 | << " Checks compatibility between a manifest and a compatibility matrix." | ||
51 | << std::endl; | ||
52 | return -1; | ||
53 | } | ||
54 | |||
55 | auto manifest = readObject(argv[1], gHalManifestConverter); | ||
56 | auto matrix = readObject(argv[2], gCompatibilityMatrixConverter); | ||
57 | if (manifest == nullptr || matrix == nullptr) { | 151 | if (manifest == nullptr || matrix == nullptr) { |
58 | return -1; | 152 | return -1; |
59 | } | 153 | } |
@@ -68,3 +162,144 @@ int main(int argc, char** argv) { | |||
68 | std::cout << "true" << std::endl; | 162 | std::cout << "true" << std::endl; |
69 | return 0; | 163 | return 0; |
70 | } | 164 | } |
165 | |||
166 | Args parseArgs(int argc, char** argv) { | ||
167 | int longOptFlag; | ||
168 | int optionIndex; | ||
169 | Args ret; | ||
170 | std::vector<struct option> longopts{ | ||
171 | {"dump-file-list", no_argument, &longOptFlag, DUMP_FILE_LIST}, | ||
172 | {"rootdir", required_argument, &longOptFlag, ROOTDIR}, | ||
173 | {"help", no_argument, &longOptFlag, HELP}, | ||
174 | {"property", required_argument, &longOptFlag, PROPERTY}, | ||
175 | {"check-compat", no_argument, &longOptFlag, CHECK_COMPAT}, | ||
176 | {0, 0, 0, 0}}; | ||
177 | std::map<int, Option> shortopts{ | ||
178 | {'h', HELP}, {'D', PROPERTY}, {'c', CHECK_COMPAT}, | ||
179 | }; | ||
180 | for (;;) { | ||
181 | int c = getopt_long(argc, argv, "hcD:", longopts.data(), &optionIndex); | ||
182 | if (c == -1) { | ||
183 | break; | ||
184 | } | ||
185 | std::string argValue = optarg ? optarg : std::string{}; | ||
186 | if (c == 0) { | ||
187 | ret.emplace(static_cast<Option>(longOptFlag), std::move(argValue)); | ||
188 | } else { | ||
189 | ret.emplace(shortopts[c], std::move(argValue)); | ||
190 | } | ||
191 | } | ||
192 | if (optind < argc) { | ||
193 | // see non option | ||
194 | std::cerr << "unrecognized option `" << argv[optind] << "'" << std::endl; | ||
195 | return {{HELP, ""}}; | ||
196 | } | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | template <typename T> | ||
201 | Properties getProperties(const T& args) { | ||
202 | Properties ret; | ||
203 | for (const auto& arg : args) { | ||
204 | auto pos = arg.find('='); | ||
205 | auto key = arg.substr(0, pos); | ||
206 | auto value = pos == std::string::npos ? std::string{} : arg.substr(pos + 1); | ||
207 | ret[key] = value; | ||
208 | } | ||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | int usage(const char* me) { | ||
213 | std::cerr | ||
214 | << me << ": check VINTF metadata." << std::endl | ||
215 | << " Options:" << std::endl | ||
216 | << " --dump-file-list: Dump a list of directories / files on device" << std::endl | ||
217 | << " that is required to be used by --check-compat." << std::endl | ||
218 | << " -c, --check-compat: check compatibility for files under the root" << std::endl | ||
219 | << " directory specified by --root-dir." << std::endl | ||
220 | << " --rootdir=<dir>: specify root directory for all metadata." << std::endl | ||
221 | << " -D, --property <key>=<value>: specify sysprops." << std::endl | ||
222 | << " --help: show this message." << std::endl | ||
223 | << std::endl | ||
224 | << " Example:" << std::endl | ||
225 | << " # Get the list of required files." << std::endl | ||
226 | << " " << me << " --dump-file-list > /tmp/files.txt" << std::endl | ||
227 | << " # Pull from ADB, or use your own command to extract files from images" | ||
228 | << std::endl | ||
229 | << " ROOTDIR=/tmp/device/" << std::endl | ||
230 | << " cat /tmp/files.txt | xargs -I{} bash -c \"mkdir -p $ROOTDIR`dirname {}` && adb " | ||
231 | "pull {} $ROOTDIR{}\"" | ||
232 | << std::endl | ||
233 | << " # Check compatibility." << std::endl | ||
234 | << " " << me << " --check-compat --rootdir=$ROOTDIR \\" << std::endl | ||
235 | << " --property ro.product.first_api_level=`adb shell getprop " | ||
236 | "ro.product.first_api_level` \\" | ||
237 | << std::endl | ||
238 | << " --property ro.boot.product.hardware.sku=`adb shell getprop " | ||
239 | "ro.boot.product.hardware.sku`" | ||
240 | << std::endl; | ||
241 | return 1; | ||
242 | } | ||
243 | |||
244 | int checkAllFiles(const std::string& rootdir, const Properties& props, std::string* error) { | ||
245 | hostFileFetcher.setRootDir(rootdir); | ||
246 | hostPropertyFetcher.setProperties(props); | ||
247 | |||
248 | return VintfObject::CheckCompatibility({} /* packageInfo */, error, DISABLE_RUNTIME_INFO); | ||
249 | } | ||
250 | |||
251 | } // namespace details | ||
252 | } // namespace vintf | ||
253 | } // namespace android | ||
254 | |||
255 | int main(int argc, char** argv) { | ||
256 | using namespace android::vintf; | ||
257 | using namespace android::vintf::details; | ||
258 | // legacy usage: check_vintf <manifest.xml> <matrix.xml> | ||
259 | if (argc == 3) { | ||
260 | int ret = checkCompatibilityForFiles(argv[1], argv[2]); | ||
261 | if (ret >= 0) return ret; | ||
262 | } | ||
263 | |||
264 | Args args = parseArgs(argc, argv); | ||
265 | |||
266 | if (!iterateValues(args, HELP).empty()) { | ||
267 | return usage(argv[0]); | ||
268 | } | ||
269 | |||
270 | if (!iterateValues(args, DUMP_FILE_LIST).empty()) { | ||
271 | for (const auto& file : dumpFileList()) { | ||
272 | std::cout << file << std::endl; | ||
273 | } | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | auto rootdirs = iterateValues(args, ROOTDIR); | ||
278 | auto properties = getProperties(iterateValues(args, PROPERTY)); | ||
279 | |||
280 | auto checkCompat = iterateValues(args, CHECK_COMPAT); | ||
281 | if (!checkCompat.empty()) { | ||
282 | if (rootdirs.empty()) { | ||
283 | std::cerr << "Missing --rootdir option." << std::endl; | ||
284 | return usage(argv[0]); | ||
285 | } | ||
286 | int ret = COMPATIBLE; | ||
287 | for (const auto& rootdir : rootdirs) { | ||
288 | std::cerr << "Debug: checking files under " << rootdir << "..." << std::endl; | ||
289 | std::string error; | ||
290 | int compat = checkAllFiles(rootdir, properties, &error); | ||
291 | std::cerr << "Debug: files under " << rootdir | ||
292 | << (compat == COMPATIBLE | ||
293 | ? " is compatible" | ||
294 | : compat == INCOMPATIBLE ? " are incompatible" | ||
295 | : (" has encountered an error: " + error)) | ||
296 | << std::endl; | ||
297 | } | ||
298 | if (ret == COMPATIBLE) { | ||
299 | std::cout << "true" << std::endl; | ||
300 | } | ||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | return usage(argv[0]); | ||
305 | } | ||
diff --git a/include/vintf/DisabledChecks.h b/include/vintf/DisabledChecks.h index 09f49a3..43ff2b5 100644 --- a/include/vintf/DisabledChecks.h +++ b/include/vintf/DisabledChecks.h | |||
@@ -25,6 +25,8 @@ enum DisabledChecks : int32_t { | |||
25 | ENABLE_ALL_CHECKS = 0, | 25 | ENABLE_ALL_CHECKS = 0, |
26 | // Disable AVB version check in RuntimeInfo::checkCompatibility | 26 | // Disable AVB version check in RuntimeInfo::checkCompatibility |
27 | DISABLE_AVB_CHECK = 1 << 0, | 27 | DISABLE_AVB_CHECK = 1 << 0, |
28 | // Disable RuntimeInfo <-> Framework Matrix check. This implies DISABLE_AVB_CHECK. | ||
29 | DISABLE_RUNTIME_INFO = 1 << 1, | ||
28 | }; | 30 | }; |
29 | 31 | ||
30 | } // namespace vintf | 32 | } // namespace vintf |
diff --git a/include/vintf/MapValueIterator.h b/include/vintf/MapValueIterator.h index ec9fb19..c9bf4b2 100644 --- a/include/vintf/MapValueIterator.h +++ b/include/vintf/MapValueIterator.h | |||
@@ -98,6 +98,20 @@ struct MapIterTypes { | |||
98 | map_ref mMap; | 98 | map_ref mMap; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | template <bool is_const> | ||
102 | struct RangeImpl { | ||
103 | using iter_type = typename std::conditional<is_const, typename Map::const_iterator, | ||
104 | typename Map::iterator>::type; | ||
105 | using range_type = std::pair<iter_type, iter_type>; | ||
106 | RangeImpl(range_type r) : mRange(r) {} | ||
107 | IteratorImpl<is_const> begin() const { return mRange.first; } | ||
108 | IteratorImpl<is_const> end() const { return mRange.second; } | ||
109 | bool empty() const { return begin() == end(); } | ||
110 | |||
111 | private: | ||
112 | range_type mRange; | ||
113 | }; | ||
114 | |||
101 | using ValueIterable = IterableImpl<false>; | 115 | using ValueIterable = IterableImpl<false>; |
102 | using ConstValueIterable = IterableImpl<true>; | 116 | using ConstValueIterable = IterableImpl<true>; |
103 | }; | 117 | }; |
@@ -116,6 +130,12 @@ ConstMultiMapValueIterable<K, V> iterateValues(const std::multimap<K, V> &map) { | |||
116 | return map; | 130 | return map; |
117 | } | 131 | } |
118 | 132 | ||
133 | template <typename K, typename V> | ||
134 | typename MapIterTypes<std::multimap<K, V>>::template RangeImpl<true> iterateValues( | ||
135 | const std::multimap<K, V>& map, const K& key) { | ||
136 | return map.equal_range(key); | ||
137 | } | ||
138 | |||
119 | } // namespace vintf | 139 | } // namespace vintf |
120 | } // namespace android | 140 | } // namespace android |
121 | 141 | ||
diff --git a/include/vintf/RuntimeInfo.h b/include/vintf/RuntimeInfo.h index b7d3c0c..6ba8a22 100644 --- a/include/vintf/RuntimeInfo.h +++ b/include/vintf/RuntimeInfo.h | |||
@@ -91,7 +91,6 @@ struct RuntimeInfo { | |||
91 | protected: | 91 | protected: |
92 | virtual status_t fetchAllInformation(FetchFlags flags); | 92 | virtual status_t fetchAllInformation(FetchFlags flags); |
93 | 93 | ||
94 | private: | ||
95 | friend struct RuntimeInfoFetcher; | 94 | friend struct RuntimeInfoFetcher; |
96 | friend class VintfObject; | 95 | friend class VintfObject; |
97 | friend struct LibVintfTest; | 96 | friend struct LibVintfTest; |
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h index 7e671f0..2e260ab 100644 --- a/include/vintf/VintfObject.h +++ b/include/vintf/VintfObject.h | |||
@@ -151,6 +151,7 @@ public: | |||
151 | static status_t FetchOdmHalManifest(HalManifest* out, std::string* error = nullptr); | 151 | static status_t FetchOdmHalManifest(HalManifest* out, std::string* error = nullptr); |
152 | static status_t FetchOneHalManifest(const std::string& path, HalManifest* out, | 152 | static status_t FetchOneHalManifest(const std::string& path, HalManifest* out, |
153 | std::string* error = nullptr); | 153 | std::string* error = nullptr); |
154 | static status_t FetchFrameworkHalManifest(HalManifest* out, std::string* error = nullptr); | ||
154 | 155 | ||
155 | static bool isHalDeprecated(const MatrixHal& oldMatrixHal, | 156 | static bool isHalDeprecated(const MatrixHal& oldMatrixHal, |
156 | const CompatibilityMatrix& targetMatrix, | 157 | const CompatibilityMatrix& targetMatrix, |
@@ -187,8 +188,17 @@ extern const std::string kVendorMatrix; | |||
187 | extern const std::string kOdmManifest; | 188 | extern const std::string kOdmManifest; |
188 | extern const std::string kVendorLegacyManifest; | 189 | extern const std::string kVendorLegacyManifest; |
189 | extern const std::string kVendorLegacyMatrix; | 190 | extern const std::string kVendorLegacyMatrix; |
191 | extern const std::string kSystemLegacyManifest; | ||
190 | extern const std::string kSystemLegacyMatrix; | 192 | extern const std::string kSystemLegacyMatrix; |
191 | 193 | ||
194 | // Convenience function to dump all files and directories that could be read | ||
195 | // by calling Get(Framework|Device)(HalManifest|CompatibilityMatrix). The list | ||
196 | // include files that may not actually be read when the four functions are called | ||
197 | // because some files have a higher priority than others. The list does NOT | ||
198 | // include "files" (including kernel interfaces) that are read when GetRuntimeInfo | ||
199 | // is called. | ||
200 | std::vector<std::string> dumpFileList(); | ||
201 | |||
192 | } // namespace details | 202 | } // namespace details |
193 | 203 | ||
194 | } // namespace vintf | 204 | } // namespace vintf |
diff --git a/test/Android.bp b/test/Android.bp index 6777ca3..50afb63 100644 --- a/test/Android.bp +++ b/test/Android.bp | |||
@@ -51,6 +51,8 @@ cc_test { | |||
51 | host_supported: true, | 51 | host_supported: true, |
52 | native_coverage: true, | 52 | native_coverage: true, |
53 | srcs: [ | 53 | srcs: [ |
54 | "RuntimeInfo-fake.cpp", | ||
55 | "utils-fake.cpp", | ||
54 | "vintf_object_tests.cpp", | 56 | "vintf_object_tests.cpp", |
55 | ], | 57 | ], |
56 | shared_libs: [ | 58 | shared_libs: [ |
@@ -64,7 +66,8 @@ cc_test { | |||
64 | "libgtest", | 66 | "libgtest", |
65 | "libgmock", | 67 | "libgmock", |
66 | "libhidl-gen-utils", | 68 | "libhidl-gen-utils", |
67 | "libvintftest", | 69 | "libvintf_common", |
70 | "libz", | ||
68 | ], | 71 | ], |
69 | cflags: [ | 72 | cflags: [ |
70 | "-O0", | 73 | "-O0", |
diff --git a/test/RuntimeInfo-fake.cpp b/test/RuntimeInfo-fake.cpp index c13eac2..0efcae7 100644 --- a/test/RuntimeInfo-fake.cpp +++ b/test/RuntimeInfo-fake.cpp | |||
@@ -14,13 +14,16 @@ | |||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "RuntimeInfo.h" | 17 | #include "utils-fake.h" |
18 | 18 | ||
19 | namespace android { | 19 | namespace android { |
20 | namespace vintf { | 20 | namespace vintf { |
21 | 21 | namespace details { | |
22 | // Fake implementation used for testing. | 22 | status_t MockRuntimeInfo::doFetch(RuntimeInfo::FetchFlags) { |
23 | status_t RuntimeInfo::fetchAllInformation(RuntimeInfo::FetchFlags) { | 23 | if (failNextFetch_) { |
24 | failNextFetch_ = false; | ||
25 | return android::UNKNOWN_ERROR; | ||
26 | } | ||
24 | mOsName = "Linux"; | 27 | mOsName = "Linux"; |
25 | mNodeName = "localhost"; | 28 | mNodeName = "localhost"; |
26 | mOsRelease = "3.18.31-g936f9a479d0f"; | 29 | mOsRelease = "3.18.31-g936f9a479d0f"; |
@@ -37,5 +40,6 @@ status_t RuntimeInfo::fetchAllInformation(RuntimeInfo::FetchFlags) { | |||
37 | return OK; | 40 | return OK; |
38 | } | 41 | } |
39 | 42 | ||
43 | } // namespace details | ||
40 | } // namespace vintf | 44 | } // namespace vintf |
41 | } // namespace android | 45 | } // namespace android |
diff --git a/test/utils-fake.cpp b/test/utils-fake.cpp index 151b3bf..38f6ab0 100644 --- a/test/utils-fake.cpp +++ b/test/utils-fake.cpp | |||
@@ -14,7 +14,7 @@ | |||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "utils.h" | 17 | #include "utils-fake.h" |
18 | 18 | ||
19 | namespace android { | 19 | namespace android { |
20 | namespace vintf { | 20 | namespace vintf { |
@@ -28,6 +28,18 @@ PartitionMounter* gPartitionMounter = nullptr; | |||
28 | 28 | ||
29 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = nullptr; | 29 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = nullptr; |
30 | 30 | ||
31 | MockPropertyFetcher::MockPropertyFetcher() { | ||
32 | using namespace ::testing; | ||
33 | using namespace std::placeholders; | ||
34 | ON_CALL(*this, getProperty(_, _)) | ||
35 | .WillByDefault(Invoke(std::bind(&PropertyFetcher::getProperty, real_, _1, _2))); | ||
36 | } | ||
37 | |||
38 | MockPropertyFetcher* gPropertyFetcher = nullptr; | ||
39 | const PropertyFetcher& getPropertyFetcher() { | ||
40 | return *gPropertyFetcher; | ||
41 | } | ||
42 | |||
31 | } // namespace details | 43 | } // namespace details |
32 | } // namespace vintf | 44 | } // namespace vintf |
33 | } // namespace android | 45 | } // namespace android |
diff --git a/test/utils-fake.h b/test/utils-fake.h index e2b2706..0253bca 100644 --- a/test/utils-fake.h +++ b/test/utils-fake.h | |||
@@ -96,13 +96,7 @@ class MockRuntimeInfo : public RuntimeInfo { | |||
96 | .WillByDefault(Invoke(this, &MockRuntimeInfo::doFetch)); | 96 | .WillByDefault(Invoke(this, &MockRuntimeInfo::doFetch)); |
97 | } | 97 | } |
98 | MOCK_METHOD1(fetchAllInformation, status_t(RuntimeInfo::FetchFlags)); | 98 | MOCK_METHOD1(fetchAllInformation, status_t(RuntimeInfo::FetchFlags)); |
99 | status_t doFetch(RuntimeInfo::FetchFlags flags) { | 99 | status_t doFetch(RuntimeInfo::FetchFlags flags); |
100 | if (failNextFetch_) { | ||
101 | failNextFetch_ = false; | ||
102 | return android::UNKNOWN_ERROR; | ||
103 | } | ||
104 | return RuntimeInfo::fetchAllInformation(flags); | ||
105 | } | ||
106 | void failNextFetch() { failNextFetch_ = true; } | 100 | void failNextFetch() { failNextFetch_ = true; } |
107 | 101 | ||
108 | private: | 102 | private: |
@@ -118,6 +112,16 @@ class MockRuntimeInfoFactory : public ObjectFactory<RuntimeInfo> { | |||
118 | std::shared_ptr<MockRuntimeInfo> object_; | 112 | std::shared_ptr<MockRuntimeInfo> object_; |
119 | }; | 113 | }; |
120 | 114 | ||
115 | class MockPropertyFetcher : public PropertyFetcher { | ||
116 | public: | ||
117 | MockPropertyFetcher(); | ||
118 | MOCK_CONST_METHOD2(getProperty, std::string(const std::string&, const std::string&)); | ||
119 | |||
120 | private: | ||
121 | PropertyFetcher real_; | ||
122 | }; | ||
123 | extern MockPropertyFetcher* gPropertyFetcher; | ||
124 | |||
121 | } // namespace details | 125 | } // namespace details |
122 | } // namespace vintf | 126 | } // namespace vintf |
123 | } // namespace android | 127 | } // namespace android |
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp index 3d834eb..d2f62d1 100644 --- a/test/vintf_object_tests.cpp +++ b/test/vintf_object_tests.cpp | |||
@@ -21,10 +21,6 @@ | |||
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | 23 | ||
24 | #ifdef LIBVINTF_TARGET | ||
25 | #include <android-base/properties.h> | ||
26 | #endif | ||
27 | |||
28 | #include <android-base/strings.h> | 24 | #include <android-base/strings.h> |
29 | #include <vintf/VintfObject.h> | 25 | #include <vintf/VintfObject.h> |
30 | #include <vintf/parse_string.h> | 26 | #include <vintf/parse_string.h> |
@@ -290,9 +286,9 @@ static MockFileFetcher &fetcher() { | |||
290 | class VintfObjectTestBase : public testing::Test { | 286 | class VintfObjectTestBase : public testing::Test { |
291 | protected: | 287 | protected: |
292 | virtual void SetUp() { | 288 | virtual void SetUp() { |
293 | #ifdef LIBVINTF_TARGET | 289 | productModel = "fake_sku"; |
294 | productModel = android::base::GetProperty("ro.boot.product.hardware.sku", ""); | 290 | ON_CALL(*gPropertyFetcher, getProperty("ro.boot.product.hardware.sku", _)) |
295 | #endif | 291 | .WillByDefault(Return(productModel)); |
296 | } | 292 | } |
297 | virtual void TearDown() { | 293 | virtual void TearDown() { |
298 | Mock::VerifyAndClear(&mounter()); | 294 | Mock::VerifyAndClear(&mounter()); |
@@ -724,7 +720,6 @@ bool containsOdmProductManifest(const std::shared_ptr<const HalManifest>& p) { | |||
724 | 720 | ||
725 | class DeviceManifestTest : public VintfObjectTestBase { | 721 | class DeviceManifestTest : public VintfObjectTestBase { |
726 | protected: | 722 | protected: |
727 | virtual void SetUp() override {} | ||
728 | 723 | ||
729 | // Expect that /vendor/etc/vintf/manifest.xml is fetched. | 724 | // Expect that /vendor/etc/vintf/manifest.xml is fetched. |
730 | void expectVendorManifest() { expectFetch(kVendorManifest, vendorEtcManifest); } | 725 | void expectVendorManifest() { expectFetch(kVendorManifest, vendorEtcManifest); } |
@@ -986,5 +981,8 @@ int main(int argc, char** argv) { | |||
986 | std::make_shared<NiceMock<MockRuntimeInfo>>()); | 981 | std::make_shared<NiceMock<MockRuntimeInfo>>()); |
987 | gRuntimeInfoFactory = &runtimeInfoFactory; | 982 | gRuntimeInfoFactory = &runtimeInfoFactory; |
988 | 983 | ||
984 | NiceMock<MockPropertyFetcher> properties; | ||
985 | gPropertyFetcher = &properties; | ||
986 | |||
989 | return RUN_ALL_TESTS(); | 987 | return RUN_ALL_TESTS(); |
990 | } | 988 | } |
diff --git a/utils-common.cpp b/utils-common.cpp new file mode 100644 index 0000000..3e7e736 --- /dev/null +++ b/utils-common.cpp | |||
@@ -0,0 +1,42 @@ | |||
1 | |||
2 | /* | ||
3 | * Copyright (C) 2017 The Android Open Source Project | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | */ | ||
17 | |||
18 | #include "utils.h" | ||
19 | |||
20 | // Default implementations for classes defined in utils.h | ||
21 | |||
22 | namespace android { | ||
23 | namespace vintf { | ||
24 | namespace details { | ||
25 | |||
26 | std::string PropertyFetcher::getProperty(const std::string&, | ||
27 | const std::string& defaultValue) const { | ||
28 | return defaultValue; | ||
29 | } | ||
30 | |||
31 | uint64_t PropertyFetcher::getUintProperty(const std::string&, uint64_t, | ||
32 | uint64_t defaultValue) const { | ||
33 | return defaultValue; | ||
34 | } | ||
35 | |||
36 | bool PropertyFetcher::getBoolProperty(const std::string&, bool defaultValue) const { | ||
37 | return defaultValue; | ||
38 | } | ||
39 | |||
40 | } // namespace details | ||
41 | } // namespace vintf | ||
42 | } // namespace android | ||
@@ -16,6 +16,10 @@ | |||
16 | 16 | ||
17 | #include "utils.h" | 17 | #include "utils.h" |
18 | 18 | ||
19 | #ifdef LIBVINTF_TARGET | ||
20 | #include <android-base/properties.h> | ||
21 | #endif | ||
22 | |||
19 | namespace android { | 23 | namespace android { |
20 | namespace vintf { | 24 | namespace vintf { |
21 | namespace details { | 25 | namespace details { |
@@ -29,6 +33,32 @@ PartitionMounter* gPartitionMounter = &partitionMounter; | |||
29 | static ObjectFactory<RuntimeInfo> runtimeInfoFactory; | 33 | static ObjectFactory<RuntimeInfo> runtimeInfoFactory; |
30 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory; | 34 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory; |
31 | 35 | ||
36 | #ifdef LIBVINTF_TARGET | ||
37 | class DevicePropertyFetcher : public PropertyFetcher { | ||
38 | public: | ||
39 | std::string getProperty(const std::string& key, | ||
40 | const std::string& defaultValue) const override { | ||
41 | return android::base::GetProperty(key, defaultValue); | ||
42 | } | ||
43 | uint64_t getUintProperty(const std::string& key, uint64_t defaultValue, | ||
44 | uint64_t max) const override { | ||
45 | return android::base::GetUintProperty(key, defaultValue, max); | ||
46 | } | ||
47 | bool getBoolProperty(const std::string& key, bool defaultValue) const override { | ||
48 | return android::base::GetBoolProperty(key, defaultValue); | ||
49 | } | ||
50 | }; | ||
51 | const PropertyFetcher& getPropertyFetcher() { | ||
52 | static DevicePropertyFetcher fetcher; | ||
53 | return fetcher; | ||
54 | } | ||
55 | #else | ||
56 | const PropertyFetcher& getPropertyFetcher() { | ||
57 | static PropertyFetcher fetcher; | ||
58 | return fetcher; | ||
59 | } | ||
60 | #endif | ||
61 | |||
32 | } // namespace details | 62 | } // namespace details |
33 | } // namespace vintf | 63 | } // namespace vintf |
34 | } // namespace android | 64 | } // namespace android |
@@ -141,6 +141,18 @@ inline Level convertFromApiLevel(size_t apiLevel) { | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | class PropertyFetcher { | ||
145 | public: | ||
146 | virtual ~PropertyFetcher() = default; | ||
147 | virtual std::string getProperty(const std::string& key, | ||
148 | const std::string& defaultValue = "") const; | ||
149 | virtual uint64_t getUintProperty(const std::string& key, uint64_t defaultValue, | ||
150 | uint64_t max = UINT64_MAX) const; | ||
151 | virtual bool getBoolProperty(const std::string& key, bool defaultValue) const; | ||
152 | }; | ||
153 | |||
154 | const PropertyFetcher& getPropertyFetcher(); | ||
155 | |||
144 | } // namespace details | 156 | } // namespace details |
145 | } // namespace vintf | 157 | } // namespace vintf |
146 | } // namespace android | 158 | } // namespace android |