blob: 8e7269cc6020c3f7816ae63e8ca282f66464e07a [file] [log] [blame]
/*
* 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_