diff options
Diffstat (limited to 'libartbase/base/hiddenapi_flags.h')
-rw-r--r-- | libartbase/base/hiddenapi_flags.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h new file mode 100644 index 0000000000..8e7269cc60 --- /dev/null +++ b/libartbase/base/hiddenapi_flags.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_ +#define ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_ + +#include "sdk_version.h" + +#include "android-base/logging.h" + +namespace art { +namespace hiddenapi { + +/* + * This class represents the information whether a field/method is in + * public API (whitelist) or if it isn't, apps targeting which SDK + * versions are allowed to access it. + */ +class ApiList { + private: + using IntValueType = uint32_t; + + enum class Value : IntValueType { + // Values independent of target SDK version of app + kWhitelist = 0, + kGreylist = 1, + kBlacklist = 2, + + // Values dependent on target SDK version of app. Put these last as + // their list will be extended in future releases. + // The max release code implicitly includes all maintenance releases, + // e.g. GreylistMaxO is accessible to targetSdkVersion <= 27 (O_MR1). + kGreylistMaxO = 3, + + // Special values + kInvalid = static_cast<uint32_t>(-1), + kMinValue = kWhitelist, + kMaxValue = kGreylistMaxO, + }; + + static constexpr const char* kNames[] = { + "whitelist", + "greylist", + "blacklist", + "greylist-max-o", + }; + + static constexpr SdkVersion kMaxSdkVersions[] { + /* whitelist */ SdkVersion::kMax, + /* greylist */ SdkVersion::kMax, + /* blacklist */ SdkVersion::kMin, + /* greylist-max-o */ SdkVersion::kO_MR1, + }; + + static ApiList MinValue() { return ApiList(Value::kMinValue); } + static ApiList MaxValue() { return ApiList(Value::kMaxValue); } + + explicit ApiList(Value value) : value_(value) {} + + const Value value_; + + public: + static ApiList Whitelist() { return ApiList(Value::kWhitelist); } + static ApiList Greylist() { return ApiList(Value::kGreylist); } + static ApiList Blacklist() { return ApiList(Value::kBlacklist); } + static ApiList GreylistMaxO() { return ApiList(Value::kGreylistMaxO); } + static ApiList Invalid() { return ApiList(Value::kInvalid); } + + // Decodes ApiList from dex hiddenapi flags. + static ApiList FromDexFlags(uint32_t dex_flags) { + if (MinValue().GetIntValue() <= dex_flags && dex_flags <= MaxValue().GetIntValue()) { + return ApiList(static_cast<Value>(dex_flags)); + } + return Invalid(); + } + + // Returns the ApiList with a given name. + static ApiList FromName(const std::string& str) { + for (IntValueType i = MinValue().GetIntValue(); i <= MaxValue().GetIntValue(); i++) { + ApiList current = ApiList(static_cast<Value>(i)); + if (str == current.GetName()) { + return current; + } + } + return Invalid(); + } + + bool operator==(const ApiList other) const { return value_ == other.value_; } + bool operator!=(const ApiList other) const { return !(*this == other); } + + bool IsValid() const { return *this != Invalid(); } + + IntValueType GetIntValue() const { + DCHECK(IsValid()); + return static_cast<IntValueType>(value_); + } + + const char* GetName() const { return kNames[GetIntValue()]; } + + SdkVersion GetMaxAllowedSdkVersion() const { return kMaxSdkVersions[GetIntValue()]; } + + static constexpr size_t kValueCount = static_cast<size_t>(Value::kMaxValue) + 1; +}; + +inline std::ostream& operator<<(std::ostream& os, ApiList value) { + os << value.GetName(); + return os; +} + +inline bool AreValidDexFlags(uint32_t dex_flags) { + return ApiList::FromDexFlags(dex_flags).IsValid(); +} + +} // namespace hiddenapi +} // namespace art + + +#endif // ART_LIBARTBASE_BASE_HIDDENAPI_FLAGS_H_ |