1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_TOOLS_VERIDEX_HIDDEN_API_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_TOOLS_VERIDEX_HIDDEN_API_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "api_list_filter.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "base/hiddenapi_flags.h" 23*795d594fSAndroid Build Coastguard Worker #include "dex/method_reference.h" 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker #include <map> 26*795d594fSAndroid Build Coastguard Worker #include <ostream> 27*795d594fSAndroid Build Coastguard Worker #include <string> 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker namespace art { 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker class DexFile; 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker enum class SignatureSource { 34*795d594fSAndroid Build Coastguard Worker UNKNOWN, 35*795d594fSAndroid Build Coastguard Worker BOOT, 36*795d594fSAndroid Build Coastguard Worker APP, 37*795d594fSAndroid Build Coastguard Worker }; 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker /** 40*795d594fSAndroid Build Coastguard Worker * Helper class for logging if a method/field is in a hidden API list. 41*795d594fSAndroid Build Coastguard Worker */ 42*795d594fSAndroid Build Coastguard Worker class HiddenApi { 43*795d594fSAndroid Build Coastguard Worker public: 44*795d594fSAndroid Build Coastguard Worker HiddenApi(const char* flags_file, const ApiListFilter& api_list_filter); 45*795d594fSAndroid Build Coastguard Worker GetApiList(const std::string & name)46*795d594fSAndroid Build Coastguard Worker hiddenapi::ApiList GetApiList(const std::string& name) const { 47*795d594fSAndroid Build Coastguard Worker auto it = api_list_.find(name); 48*795d594fSAndroid Build Coastguard Worker return (it == api_list_.end()) ? hiddenapi::ApiList() : it->second; 49*795d594fSAndroid Build Coastguard Worker } 50*795d594fSAndroid Build Coastguard Worker ShouldReport(const std::string & signature)51*795d594fSAndroid Build Coastguard Worker bool ShouldReport(const std::string& signature) const { 52*795d594fSAndroid Build Coastguard Worker return api_list_filter_.Matches(GetApiList(signature)); 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker AddSignatureSource(const std::string & signature,SignatureSource source)55*795d594fSAndroid Build Coastguard Worker void AddSignatureSource(const std::string &signature, SignatureSource source) { 56*795d594fSAndroid Build Coastguard Worker const auto type = GetApiClassName(signature); 57*795d594fSAndroid Build Coastguard Worker auto it = source_.find(type); 58*795d594fSAndroid Build Coastguard Worker if (it == source_.end() || it->second == SignatureSource::UNKNOWN) { 59*795d594fSAndroid Build Coastguard Worker source_[type] = source; 60*795d594fSAndroid Build Coastguard Worker } else if (it->second != source) { 61*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << type << "is present both in boot and in app."; 62*795d594fSAndroid Build Coastguard Worker if (source == SignatureSource::BOOT) { 63*795d594fSAndroid Build Coastguard Worker // Runtime resolves to boot type, so it takes precedence. 64*795d594fSAndroid Build Coastguard Worker it->second = source; 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker } else { 67*795d594fSAndroid Build Coastguard Worker // Already exists with the same source. 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker GetSignatureSource(const std::string & signature)71*795d594fSAndroid Build Coastguard Worker SignatureSource GetSignatureSource(const std::string& signature) const { 72*795d594fSAndroid Build Coastguard Worker auto it = source_.find(GetApiClassName(signature)); 73*795d594fSAndroid Build Coastguard Worker return (it == source_.end()) ? SignatureSource::UNKNOWN : it->second; 74*795d594fSAndroid Build Coastguard Worker } 75*795d594fSAndroid Build Coastguard Worker IsInBoot(const std::string & signature)76*795d594fSAndroid Build Coastguard Worker bool IsInBoot(const std::string& signature) const { 77*795d594fSAndroid Build Coastguard Worker return SignatureSource::BOOT == GetSignatureSource(signature); 78*795d594fSAndroid Build Coastguard Worker } 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker static std::string GetApiMethodName(const DexFile& dex_file, uint32_t method_index); 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker static std::string GetApiFieldName(const DexFile& dex_file, uint32_t field_index); 83*795d594fSAndroid Build Coastguard Worker GetApiMethodName(MethodReference ref)84*795d594fSAndroid Build Coastguard Worker static std::string GetApiMethodName(MethodReference ref) { 85*795d594fSAndroid Build Coastguard Worker return HiddenApi::GetApiMethodName(*ref.dex_file, ref.index); 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker ToInternalName(const std::string & str)88*795d594fSAndroid Build Coastguard Worker static std::string ToInternalName(const std::string& str) { 89*795d594fSAndroid Build Coastguard Worker std::string val = str; 90*795d594fSAndroid Build Coastguard Worker std::replace(val.begin(), val.end(), '.', '/'); 91*795d594fSAndroid Build Coastguard Worker return "L" + val + ";"; 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker private: 95*795d594fSAndroid Build Coastguard Worker void AddSignatureToApiList(const std::string& signature, hiddenapi::ApiList membership); 96*795d594fSAndroid Build Coastguard Worker GetApiClassName(const std::string & signature)97*795d594fSAndroid Build Coastguard Worker static std::string GetApiClassName(const std::string& signature) { 98*795d594fSAndroid Build Coastguard Worker size_t pos = signature.find("->"); 99*795d594fSAndroid Build Coastguard Worker if (pos != std::string::npos) { 100*795d594fSAndroid Build Coastguard Worker return signature.substr(0, pos); 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker return signature; 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker const ApiListFilter& api_list_filter_; 106*795d594fSAndroid Build Coastguard Worker std::map<std::string, hiddenapi::ApiList> api_list_; 107*795d594fSAndroid Build Coastguard Worker std::map<std::string, SignatureSource> source_; 108*795d594fSAndroid Build Coastguard Worker }; 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker struct HiddenApiStats { 111*795d594fSAndroid Build Coastguard Worker uint32_t count = 0; 112*795d594fSAndroid Build Coastguard Worker uint32_t reflection_count = 0; 113*795d594fSAndroid Build Coastguard Worker uint32_t linking_count = 0; 114*795d594fSAndroid Build Coastguard Worker // Ensure enough space for kInvalid as well, and initialize all to zero 115*795d594fSAndroid Build Coastguard Worker uint32_t api_counts[hiddenapi::ApiList::kValueSize] = {}; 116*795d594fSAndroid Build Coastguard Worker }; 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker } // namespace art 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker #endif // ART_TOOLS_VERIDEX_HIDDEN_API_H_ 122