DO NOT MERGE: Make veridex resolve API conflicts in favor of most accessible
Previously, if veridex was using a hidden APi flags file
(out/soong/hiddenapi/hiddenapi-flags.csv) that was generated from both
source and prebuilt APIs it would abort if an API element had
conficting flags, e.g. `whitelist` and `greylist`. That would happen
when attempting to build in R against prebuilts that contained updated
.apks and SDK files. That was because the hidden API flag handling was
not modularized until the S build.
This change fixes the R veridex tool to handle the conflicting flags
by selecting the most accessible, e.g. if the conflicting flags were
`whitelist` and `greylist` then merging them would use the `whitelist`
flag as that API is more accessible than the `greylist` API. That
behavior was chosen on the assumption that in order to preserve
backwards compatibility an API would never become less accessible so
if an API element has two conflicting flags then that is because the
API has been made more accessible in the prebuilts. e.g. the
`android.net.wifi.WifiConfiguration#lastConnectUid` was previously part
of the `greylist` but has since been added to the system API and so is
now part of the `whitelist` API.
Bug: 253335210
Test: build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_cf_x86_64_phone TARGET_BUILD_VARIANT=userdebug droid dist
# First, reproduce the build failure so that the above fails in
# veridex due to conflicting flags. See the bug for detailed
# instructions on how to reproduce the initial build failure.
# Second, apply this change and rerun to make sure that it is
# fixed.
Change-Id: Ibda4443baa9aaed540e16dc9b325d843df37a29c
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h
index 9d0a18e..41a0644 100644
--- a/libartbase/base/hiddenapi_flags.h
+++ b/libartbase/base/hiddenapi_flags.h
@@ -263,11 +263,12 @@
bool operator<(const ApiList& other) const { return dex_flags_ < other.dex_flags_; }
bool operator>(const ApiList& other) const { return dex_flags_ > other.dex_flags_; }
- // Returns true if combining this ApiList with `other` will succeed.
+ // Returns true if combining this ApiList (using | operator) with `other` will succeed.
+ //
+ // b/253335210 - This returns true as the | operator will combine any two ApiLists.
bool CanCombineWith(const ApiList& other) const {
- const Value val1 = GetValue();
- const Value val2 = other.GetValue();
- return (val1 == val2) || (val1 == Value::kInvalid) || (val2 == Value::kInvalid);
+ UNUSED(other);
+ return true;
}
// Combine two ApiList instances.
@@ -275,8 +276,9 @@
// DomainApis are not mutually exclusive. Simply OR them.
const uint32_t domain_apis = GetDomainApis() | other.GetDomainApis();
- // Values are mutually exclusive. Check if `this` and `other` have the same Value
- // or if at most one is set.
+ // Values are mutually exclusive but the most accessible value is chosen.
+ // Check if `this` and `other` have the same Value, or if at most one is set and
+ // if so use the set value. Otherwise, use the value that is most accessible.
const Value val1 = GetValue();
const Value val2 = other.GetValue();
if (val1 == val2) {
@@ -285,6 +287,10 @@
return ApiList(val2, domain_apis);
} else if (val2 == Value::kInvalid) {
return ApiList(val1, domain_apis);
+ } else if (val1 < val2) {
+ return ApiList(val1, domain_apis);
+ } else if (val1 > val2) {
+ return ApiList(val2, domain_apis);
} else {
LOG(FATAL) << "Invalid combination of values " << Dumpable(ApiList(val1))
<< " and " << Dumpable(ApiList(val2));