summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot2018-03-20 02:23:00 -0500
committerandroid-build-team Robot2018-03-20 02:23:00 -0500
commit8d5f214fac328f720d703d010b28bc8bc5d625f7 (patch)
tree0e2b8789b3fb7c65d47bfd7490c05e4b06a0d0a9
parentb1e0a04b45fe9527a037328d8ab3d39ec212fa7d (diff)
parent58523e1952e7fdf9a49eb7d34bb98ccc7c4335be (diff)
downloadplatform-system-libvintf-8d5f214fac328f720d703d010b28bc8bc5d625f7.tar.gz
platform-system-libvintf-8d5f214fac328f720d703d010b28bc8bc5d625f7.tar.xz
platform-system-libvintf-8d5f214fac328f720d703d010b28bc8bc5d625f7.zip
Snap for 4665332 from 58523e1952e7fdf9a49eb7d34bb98ccc7c4335be to pi-release
Change-Id: I149a3a2778f9efc229d09606b8fdf5607c706774
-rw-r--r--CompatibilityMatrix.cpp49
-rw-r--r--MatrixHal.cpp89
-rw-r--r--include/vintf/CompatibilityMatrix.h3
-rw-r--r--include/vintf/HalGroup.h18
-rw-r--r--include/vintf/MatrixHal.h20
-rw-r--r--test/LibVintfTest.cpp197
6 files changed, 337 insertions, 39 deletions
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 3f05881..5b216f7 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -75,6 +75,30 @@ std::string CompatibilityMatrix::getXmlSchemaPath(const std::string& xmlFileName
75 return ""; 75 return "";
76} 76}
77 77
78// Split existingHal into a HAL that contains only interface/instance and a HAL
79// that does not contain it. Return the HAL that contains only interface/instance.
80// - Return nullptr if existingHal does not contain interface/instance
81// - Return existingHal if existingHal contains only interface/instance
82// - Remove interface/instance from existingHal, and return a new MatrixHal (that is added
83// to "this") that contains only interface/instance.
84MatrixHal* CompatibilityMatrix::splitInstance(MatrixHal* existingHal, const std::string& interface,
85 const std::string& instance) {
86 if (!existingHal->hasInstance(interface, instance)) {
87 return nullptr;
88 }
89
90 if (existingHal->hasOnlyInstance(interface, instance)) {
91 return existingHal;
92 }
93
94 existingHal->removeInstance(interface, instance);
95 MatrixHal copy = *existingHal;
96 copy.clearInstances();
97 copy.insertInstance(interface, instance);
98
99 return addInternal(std::move(copy));
100}
101
78// Add all package@other_version::interface/instance as an optional instance. 102// Add all package@other_version::interface/instance as an optional instance.
79// If package@this_version::interface/instance is in this (that is, some instance 103// If package@this_version::interface/instance is in this (that is, some instance
80// with the same package and interface and instance exists), then other_version is 104// with the same package and interface and instance exists), then other_version is
@@ -89,16 +113,27 @@ bool CompatibilityMatrix::addAllHalsAsOptional(CompatibilityMatrix* other, std::
89 const std::string& name = pair.first; 113 const std::string& name = pair.first;
90 MatrixHal& halToAdd = pair.second; 114 MatrixHal& halToAdd = pair.second;
91 115
92 bool added = false; 116 std::set<std::pair<std::string, std::string>> insertedInstances;
93 for (auto* existingHal : getHals(name)) { 117 auto existingHals = getHals(name);
94 if (existingHal->containsInstances(halToAdd)) { 118
95 existingHal->insertVersionRanges(halToAdd); 119 halToAdd.forEachInstance([&](const std::vector<VersionRange>& versionRanges,
96 added = true; 120 const std::string& interface, const std::string& instance) {
97 // Do not break here; try other <hal> with the same name as well. 121 for (auto* existingHal : existingHals) {
122 MatrixHal* splitInstance = this->splitInstance(existingHal, interface, instance);
123 if (splitInstance != nullptr) {
124 splitInstance->insertVersionRanges(versionRanges);
125 insertedInstances.insert(std::make_pair(interface, instance));
126 }
98 } 127 }
128 return true;
129 });
130
131 // Add the remaining instances.
132 for (const auto& pair : insertedInstances) {
133 halToAdd.removeInstance(pair.first, pair.second);
99 } 134 }
100 135
101 if (!added) { 136 if (halToAdd.hasAnyInstance()) {
102 halToAdd.setOptional(true); 137 halToAdd.setOptional(true);
103 if (!add(std::move(halToAdd))) { 138 if (!add(std::move(halToAdd))) {
104 if (error) { 139 if (error) {
diff --git a/MatrixHal.cpp b/MatrixHal.cpp
index 504265e..62e0cd8 100644
--- a/MatrixHal.cpp
+++ b/MatrixHal.cpp
@@ -52,24 +52,6 @@ std::set<std::string> MatrixHal::getInstances(const std::string& interfaceName)
52 return ret; 52 return ret;
53} 53}
54 54
55bool MatrixHal::containsInstances(const MatrixHal& other) const {
56 for (const auto& pair : other.interfaces) {
57 const std::string& interfaceName = pair.first;
58 auto thisIt = interfaces.find(interfaceName);
59 if (thisIt == interfaces.end()) {
60 return false;
61 }
62
63 const std::set<std::string>& thisInstances = thisIt->second.instances;
64 const std::set<std::string>& otherInstances = pair.second.instances;
65 if (!std::includes(thisInstances.begin(), thisInstances.end(), otherInstances.begin(),
66 otherInstances.end())) {
67 return false;
68 }
69 }
70 return true;
71}
72
73bool MatrixHal::forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const { 55bool MatrixHal::forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const {
74 for (const auto& vr : versionRanges) { 56 for (const auto& vr : versionRanges) {
75 if (!forEachInstance(vr, func)) { 57 if (!forEachInstance(vr, func)) {
@@ -95,6 +77,19 @@ bool MatrixHal::forEachInstance(const VersionRange& vr,
95 return true; 77 return true;
96} 78}
97 79
80bool MatrixHal::forEachInstance(
81 const std::function<bool(const std::vector<VersionRange>&, const std::string&,
82 const std::string&)>& func) const {
83 for (const auto& intf : iterateValues(interfaces)) {
84 for (const auto& instance : intf.instances) {
85 if (!func(versionRanges, intf.name, instance)) {
86 return false;
87 }
88 }
89 }
90 return true;
91}
92
98bool MatrixHal::isCompatible(const std::set<FqInstance>& providedInstances, 93bool MatrixHal::isCompatible(const std::set<FqInstance>& providedInstances,
99 const std::set<Version>& providedVersions) const { 94 const std::set<Version>& providedVersions) const {
100 // <version>'s are related by OR. 95 // <version>'s are related by OR.
@@ -136,8 +131,8 @@ void MatrixHal::setOptional(bool o) {
136 this->optional = o; 131 this->optional = o;
137} 132}
138 133
139void MatrixHal::insertVersionRanges(const MatrixHal& other) { 134void MatrixHal::insertVersionRanges(const std::vector<VersionRange>& other) {
140 for (const VersionRange& otherVr : other.versionRanges) { 135 for (const VersionRange& otherVr : other) {
141 auto existingVr = std::find_if(this->versionRanges.begin(), this->versionRanges.end(), 136 auto existingVr = std::find_if(this->versionRanges.begin(), this->versionRanges.end(),
142 [&](const auto& e) { return e.overlaps(otherVr); }); 137 [&](const auto& e) { return e.overlaps(otherVr); });
143 138
@@ -150,5 +145,59 @@ void MatrixHal::insertVersionRanges(const MatrixHal& other) {
150 } 145 }
151} 146}
152 147
148void MatrixHal::insertInstance(const std::string& interface, const std::string& instance) {
149 auto it = interfaces.find(interface);
150 if (it == interfaces.end())
151 it = interfaces.emplace(interface, HalInterface{interface, {}}).first;
152 it->second.instances.insert(instance);
153}
154
155bool MatrixHal::hasAnyInstance() const {
156 bool found = false;
157 forEachInstance([&](const auto&) {
158 found = true;
159 return false; // break if any instance
160 });
161 return found;
162}
163
164bool MatrixHal::hasInstance(const std::string& interface, const std::string& instance) const {
165 bool found = false;
166 forEachInstance([&](const auto& matrixInstance) {
167 found |= matrixInstance.interface() == interface && matrixInstance.instance() == instance;
168 return !found; // continue if not match
169 });
170 return found;
171}
172
173bool MatrixHal::hasOnlyInstance(const std::string& interface, const std::string& instance) const {
174 bool found = false;
175 bool foundOthers = false;
176
177 forEachInstance([&](const auto& matrixInstance) {
178 bool match =
179 matrixInstance.interface() == interface && matrixInstance.instance() == instance;
180
181 found |= match;
182 foundOthers |= (!match);
183
184 return !foundOthers;
185 });
186
187 return found && !foundOthers;
188}
189
190bool MatrixHal::removeInstance(const std::string& interface, const std::string& instance) {
191 auto it = interfaces.find(interface);
192 if (it == interfaces.end()) return false;
193 it->second.instances.erase(instance);
194 if (it->second.instances.empty()) interfaces.erase(it);
195 return true;
196}
197
198void MatrixHal::clearInstances() {
199 this->interfaces.clear();
200}
201
153} // namespace vintf 202} // namespace vintf
154} // namespace android 203} // namespace android
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 6431836..02326ae 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -91,6 +91,9 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat
91 static CompatibilityMatrix* findOrInsertBaseMatrix( 91 static CompatibilityMatrix* findOrInsertBaseMatrix(
92 std::vector<Named<CompatibilityMatrix>>* matrices, std::string* error); 92 std::vector<Named<CompatibilityMatrix>>* matrices, std::string* error);
93 93
94 MatrixHal* splitInstance(MatrixHal* existingHal, const std::string& interface,
95 const std::string& instance);
96
94 friend struct HalManifest; 97 friend struct HalManifest;
95 friend struct RuntimeInfo; 98 friend struct RuntimeInfo;
96 friend struct CompatibilityMatrixConverter; 99 friend struct CompatibilityMatrixConverter;
diff --git a/include/vintf/HalGroup.h b/include/vintf/HalGroup.h
index 033adf0..2a1e1c3 100644
--- a/include/vintf/HalGroup.h
+++ b/include/vintf/HalGroup.h
@@ -48,14 +48,7 @@ struct HalGroup {
48 } 48 }
49 49
50 // Add an hal to this HalGroup so that it can be constructed programatically. 50 // Add an hal to this HalGroup so that it can be constructed programatically.
51 virtual bool add(Hal&& hal) { 51 virtual bool add(Hal&& hal) { return addInternal(std::move(hal)) != nullptr; }
52 if (!shouldAdd(hal)) {
53 return false;
54 }
55 std::string name = hal.getName();
56 mHals.emplace(std::move(name), std::move(hal)); // always succeed
57 return true;
58 }
59 52
60 // Get all hals with the given name (e.g "android.hardware.camera"). 53 // Get all hals with the given name (e.g "android.hardware.camera").
61 // There could be multiple hals that matches the same given name. 54 // There could be multiple hals that matches the same given name.
@@ -191,6 +184,15 @@ struct HalGroup {
191 } 184 }
192 return &(it->second); 185 return &(it->second);
193 } 186 }
187
188 Hal* addInternal(Hal&& hal) {
189 if (!shouldAdd(hal)) {
190 return nullptr;
191 }
192 std::string name = hal.getName();
193 auto it = mHals.emplace(std::move(name), std::move(hal)); // always succeeds
194 return &it->second;
195 }
194}; 196};
195 197
196} // namespace vintf 198} // namespace vintf
diff --git a/include/vintf/MatrixHal.h b/include/vintf/MatrixHal.h
index 6044792..595c57a 100644
--- a/include/vintf/MatrixHal.h
+++ b/include/vintf/MatrixHal.h
@@ -48,23 +48,35 @@ struct MatrixHal {
48 48
49 inline const std::string& getName() const { return name; } 49 inline const std::string& getName() const { return name; }
50 50
51 // Return true if "this" contains all interface/instance instances in "other".
52 bool containsInstances(const MatrixHal& other) const;
53
54 bool forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const; 51 bool forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const;
55 52
56 private: 53 private:
57 friend struct HalManifest; 54 friend struct HalManifest;
58 friend struct CompatibilityMatrix; 55 friend struct CompatibilityMatrix;
56 // Loop over interface/instance for a specific VersionRange.
59 bool forEachInstance(const VersionRange& vr, 57 bool forEachInstance(const VersionRange& vr,
60 const std::function<bool(const MatrixInstance&)>& func) const; 58 const std::function<bool(const MatrixInstance&)>& func) const;
59 // Loop over interface/instance. VersionRange is supplied to the function as a vector.
60 bool forEachInstance(
61 const std::function<bool(const std::vector<VersionRange>&, const std::string&,
62 const std::string&)>& func) const;
61 bool isCompatible(const std::set<FqInstance>& providedInstances, 63 bool isCompatible(const std::set<FqInstance>& providedInstances,
62 const std::set<Version>& providedVersions) const; 64 const std::set<Version>& providedVersions) const;
63 bool isCompatible(const VersionRange& vr, const std::set<FqInstance>& providedInstances, 65 bool isCompatible(const VersionRange& vr, const std::set<FqInstance>& providedInstances,
64 const std::set<Version>& providedVersions) const; 66 const std::set<Version>& providedVersions) const;
65 67
66 void setOptional(bool o); 68 void setOptional(bool o);
67 void insertVersionRanges(const MatrixHal& other); 69 void insertVersionRanges(const std::vector<VersionRange>& other);
70 void insertInstance(const std::string& interface, const std::string& instance);
71 // Return true if it has any interface/instance tags.
72 bool hasAnyInstance() const;
73 bool hasInstance(const std::string& interface, const std::string& instance) const;
74 // Return true if it contains only interface/instance.
75 bool hasOnlyInstance(const std::string& interface, const std::string& instance) const;
76 // Remove a specific interface/instances. Return true if removed, false otherwise.
77 bool removeInstance(const std::string& interface, const std::string& instance);
78 // Remove all <interface> tags.
79 void clearInstances();
68}; 80};
69 81
70} // namespace vintf 82} // namespace vintf
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index fc7ebc9..8c42d77 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -2275,6 +2275,203 @@ TEST_F(LibVintfTest, AddOptionalHalMinorVersionDiffInstance) {
2275 "</compatibility-matrix>\n"); 2275 "</compatibility-matrix>\n");
2276} 2276}
2277 2277
2278TEST_F(LibVintfTest, AddRequiredHalOverlapInstance) {
2279 CompatibilityMatrix cm1;
2280 std::string error;
2281 std::string xml;
2282
2283 xml =
2284 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
2285 " <hal format=\"hidl\" optional=\"false\">\n"
2286 " <name>android.hardware.foo</name>\n"
2287 " <version>1.0</version>\n"
2288 " <interface>\n"
2289 " <name>IFoo</name>\n"
2290 " <instance>default</instance>\n"
2291 " <instance>custom</instance>\n"
2292 " </interface>\n"
2293 " </hal>\n"
2294 "</compatibility-matrix>\n";
2295 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm1, xml))
2296 << gCompatibilityMatrixConverter.lastError();
2297
2298 {
2299 // Test that 2.0 should be added to IFoo/default, so 1.0::IFoo/custom
2300 // should be in a new <hal> tag
2301 CompatibilityMatrix cm2;
2302 xml =
2303 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n"
2304 " <hal format=\"hidl\" optional=\"false\">\n"
2305 " <name>android.hardware.foo</name>\n"
2306 " <version>2.0</version>\n"
2307 " <interface>\n"
2308 " <name>IFoo</name>\n"
2309 " <instance>default</instance>\n"
2310 " </interface>\n"
2311 " </hal>\n"
2312 "</compatibility-matrix>\n";
2313 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm2, xml))
2314 << gCompatibilityMatrixConverter.lastError();
2315
2316 EXPECT_TRUE(addAllHalsAsOptional(&cm1, &cm2, &error)) << error;
2317
2318 xml = gCompatibilityMatrixConverter(cm1, SerializeFlag::HALS_ONLY);
2319 EXPECT_EQ(xml,
2320 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
2321 " <hal format=\"hidl\" optional=\"false\">\n"
2322 " <name>android.hardware.foo</name>\n"
2323 " <version>1.0</version>\n"
2324 " <interface>\n"
2325 " <name>IFoo</name>\n"
2326 " <instance>custom</instance>\n"
2327 " </interface>\n"
2328 " </hal>\n"
2329 " <hal format=\"hidl\" optional=\"false\">\n"
2330 " <name>android.hardware.foo</name>\n"
2331 " <version>1.0</version>\n"
2332 " <version>2.0</version>\n"
2333 " <interface>\n"
2334 " <name>IFoo</name>\n"
2335 " <instance>default</instance>\n"
2336 " </interface>\n"
2337 " </hal>\n"
2338 "</compatibility-matrix>\n");
2339 }
2340
2341 {
2342 // Test that 2.0::IFoo/strong should be added as an optional <hal> tag.
2343 CompatibilityMatrix cm2;
2344 xml =
2345 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n"
2346 " <hal format=\"hidl\" optional=\"false\">\n"
2347 " <name>android.hardware.foo</name>\n"
2348 " <version>2.0</version>\n"
2349 " <interface>\n"
2350 " <name>IFoo</name>\n"
2351 " <instance>default</instance>\n"
2352 " <instance>strong</instance>\n"
2353 " </interface>\n"
2354 " </hal>\n"
2355 "</compatibility-matrix>\n";
2356 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm2, xml))
2357 << gCompatibilityMatrixConverter.lastError();
2358
2359 EXPECT_TRUE(addAllHalsAsOptional(&cm1, &cm2, &error)) << error;
2360
2361 xml = gCompatibilityMatrixConverter(cm1, SerializeFlag::HALS_ONLY);
2362 EXPECT_EQ(xml,
2363 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
2364 " <hal format=\"hidl\" optional=\"false\">\n"
2365 " <name>android.hardware.foo</name>\n"
2366 " <version>1.0</version>\n"
2367 " <interface>\n"
2368 " <name>IFoo</name>\n"
2369 " <instance>custom</instance>\n"
2370 " </interface>\n"
2371 " </hal>\n"
2372 " <hal format=\"hidl\" optional=\"false\">\n"
2373 " <name>android.hardware.foo</name>\n"
2374 " <version>1.0</version>\n"
2375 " <version>2.0</version>\n"
2376 " <interface>\n"
2377 " <name>IFoo</name>\n"
2378 " <instance>default</instance>\n"
2379 " </interface>\n"
2380 " </hal>\n"
2381 " <hal format=\"hidl\" optional=\"true\">\n"
2382 " <name>android.hardware.foo</name>\n"
2383 " <version>2.0</version>\n"
2384 " <interface>\n"
2385 " <name>IFoo</name>\n"
2386 " <instance>strong</instance>\n"
2387 " </interface>\n"
2388 " </hal>\n"
2389 "</compatibility-matrix>\n");
2390 }
2391}
2392
2393TEST_F(LibVintfTest, AddRequiredHalOverlapInstanceSplit) {
2394 CompatibilityMatrix cm1;
2395 CompatibilityMatrix cm2;
2396 std::string error;
2397 std::string xml;
2398
2399 xml =
2400 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
2401 " <hal format=\"hidl\" optional=\"false\">\n"
2402 " <name>android.hardware.foo</name>\n"
2403 " <version>1.0</version>\n"
2404 " <interface>\n"
2405 " <name>IFoo</name>\n"
2406 " <instance>default</instance>\n"
2407 " </interface>\n"
2408 " </hal>\n"
2409 " <hal format=\"hidl\" optional=\"false\">\n"
2410 " <name>android.hardware.foo</name>\n"
2411 " <version>1.0</version>\n"
2412 " <interface>\n"
2413 " <name>IFoo</name>\n"
2414 " <instance>custom</instance>\n"
2415 " </interface>\n"
2416 " </hal>\n"
2417 "</compatibility-matrix>\n";
2418 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm1, xml))
2419 << gCompatibilityMatrixConverter.lastError();
2420
2421 xml =
2422 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n"
2423 " <hal format=\"hidl\" optional=\"false\">\n"
2424 " <name>android.hardware.foo</name>\n"
2425 " <version>2.0</version>\n"
2426 " <interface>\n"
2427 " <name>IFoo</name>\n"
2428 " <instance>default</instance>\n"
2429 " </interface>\n"
2430 " </hal>\n"
2431 " <hal format=\"hidl\" optional=\"false\">\n"
2432 " <name>android.hardware.foo</name>\n"
2433 " <version>2.0</version>\n"
2434 " <interface>\n"
2435 " <name>IFoo</name>\n"
2436 " <instance>strong</instance>\n"
2437 " </interface>\n"
2438 " </hal>\n"
2439 "</compatibility-matrix>\n";
2440 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm2, xml))
2441 << gCompatibilityMatrixConverter.lastError();
2442
2443 EXPECT_TRUE(addAllHalsAsOptional(&cm1, &cm2, &error)) << error;
2444 xml = gCompatibilityMatrixConverter(cm1, SerializeFlag::HALS_ONLY);
2445 EXPECT_EQ(
2446 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n"
2447 " <hal format=\"hidl\" optional=\"false\">\n"
2448 " <name>android.hardware.foo</name>\n"
2449 " <version>1.0</version>\n"
2450 " <version>2.0</version>\n"
2451 " <interface>\n"
2452 " <name>IFoo</name>\n"
2453 " <instance>default</instance>\n"
2454 " </interface>\n"
2455 " </hal>\n"
2456 " <hal format=\"hidl\" optional=\"false\">\n"
2457 " <name>android.hardware.foo</name>\n"
2458 " <version>1.0</version>\n"
2459 " <interface>\n"
2460 " <name>IFoo</name>\n"
2461 " <instance>custom</instance>\n"
2462 " </interface>\n"
2463 " </hal>\n"
2464 " <hal format=\"hidl\" optional=\"true\">\n"
2465 " <name>android.hardware.foo</name>\n"
2466 " <version>2.0</version>\n"
2467 " <interface>\n"
2468 " <name>IFoo</name>\n"
2469 " <instance>strong</instance>\n"
2470 " </interface>\n"
2471 " </hal>\n"
2472 "</compatibility-matrix>\n",
2473 xml);
2474}
2278TEST_F(LibVintfTest, AddOptionalXmlFile) { 2475TEST_F(LibVintfTest, AddOptionalXmlFile) {
2279 CompatibilityMatrix cm1; 2476 CompatibilityMatrix cm1;
2280 CompatibilityMatrix cm2; 2477 CompatibilityMatrix cm2;