summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libartbase/base/hiddenapi_flags.h30
1 files changed, 29 insertions, 1 deletions
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h
index 9d0a18e78f..0d7938aca1 100644
--- a/libartbase/base/hiddenapi_flags.h
+++ b/libartbase/base/hiddenapi_flags.h
@@ -263,11 +263,37 @@ class ApiList {
bool operator<(const ApiList& other) const { return dex_flags_ < other.dex_flags_; }
bool operator>(const ApiList& other) const { return dex_flags_ > other.dex_flags_; }
+ // In order to correctly handle flagged changes from Unsupported to the Sdk, where both will be
+ // set when the flag is enabled, consider Sdk to take precedence over any form of unsupported.
+ // Note, this is not necessary in the inverse direction, because API flagging does not currently
+ // support API removal. Moving from the blocklist to unsupported is also a case we don't have to
+ // consider.
+ // If this is true, the conflict resolves to Value::kSdk.
+ static bool is_conflicting_flags_acceptable(Value x, Value y) {
+ const auto predicate_non_symmetric = [] (auto l, auto r) {
+ if (l != Value::kSdk) return false;
+ switch (r) {
+ case Value::kSdk:
+ case Value::kUnsupported:
+ case Value::kMaxTargetO:
+ case Value::kMaxTargetP:
+ case Value::kMaxTargetQ:
+ case Value::kMaxTargetR:
+ case Value::kMaxTargetS:
+ return true;
+ default:
+ return false;
+ }
+ };
+ return predicate_non_symmetric(x, y) || predicate_non_symmetric(y, x);
+ }
+
// Returns true if combining this ApiList with `other` will succeed.
bool CanCombineWith(const ApiList& other) const {
const Value val1 = GetValue();
const Value val2 = other.GetValue();
- return (val1 == val2) || (val1 == Value::kInvalid) || (val2 == Value::kInvalid);
+ return (val1 == val2) || (val1 == Value::kInvalid) || (val2 == Value::kInvalid) ||
+ is_conflicting_flags_acceptable(val1, val2);
}
// Combine two ApiList instances.
@@ -285,6 +311,8 @@ class ApiList {
return ApiList(val2, domain_apis);
} else if (val2 == Value::kInvalid) {
return ApiList(val1, domain_apis);
+ } else if (is_conflicting_flags_acceptable(val1, val2)) {
+ return ApiList(Value::kSdk, domain_apis);
} else {
LOG(FATAL) << "Invalid combination of values " << Dumpable(ApiList(val1))
<< " and " << Dumpable(ApiList(val2));