xref: /aosp_15_r20/art/tools/veridex/hidden_api.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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 #include "hidden_api.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <fstream>
20*795d594fSAndroid Build Coastguard Worker #include <sstream>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "android-base/strings.h"
23*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker namespace art {
26*795d594fSAndroid Build Coastguard Worker 
HiddenApi(const char * filename,const ApiListFilter & api_list_filter)27*795d594fSAndroid Build Coastguard Worker HiddenApi::HiddenApi(const char* filename, const ApiListFilter& api_list_filter)
28*795d594fSAndroid Build Coastguard Worker     : api_list_filter_(api_list_filter) {
29*795d594fSAndroid Build Coastguard Worker   CHECK(filename != nullptr);
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker   std::ifstream in(filename);
32*795d594fSAndroid Build Coastguard Worker   bool errors = false;
33*795d594fSAndroid Build Coastguard Worker   for (std::string str; std::getline(in, str);) {
34*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> values = android::base::Split(str, ",");
35*795d594fSAndroid Build Coastguard Worker     const std::string& signature = values[0];
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker     hiddenapi::ApiList membership;
38*795d594fSAndroid Build Coastguard Worker     bool success = hiddenapi::ApiList::FromNames(values.begin() + 1, values.end(), &membership);
39*795d594fSAndroid Build Coastguard Worker     if (!success) {
40*795d594fSAndroid Build Coastguard Worker       LOG(ERROR) << "Unknown ApiList flag: " << str;
41*795d594fSAndroid Build Coastguard Worker       errors = true;
42*795d594fSAndroid Build Coastguard Worker       continue;
43*795d594fSAndroid Build Coastguard Worker     } else if (!membership.IsValid()) {
44*795d594fSAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid ApiList: " << membership;
45*795d594fSAndroid Build Coastguard Worker       errors = true;
46*795d594fSAndroid Build Coastguard Worker       continue;
47*795d594fSAndroid Build Coastguard Worker     }
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker     AddSignatureToApiList(signature, membership);
50*795d594fSAndroid Build Coastguard Worker     size_t pos = signature.find("->");
51*795d594fSAndroid Build Coastguard Worker     if (pos != std::string::npos) {
52*795d594fSAndroid Build Coastguard Worker       // Add the class name.
53*795d594fSAndroid Build Coastguard Worker       AddSignatureToApiList(signature.substr(0, pos), membership);
54*795d594fSAndroid Build Coastguard Worker       pos = signature.find('(');
55*795d594fSAndroid Build Coastguard Worker       if (pos != std::string::npos) {
56*795d594fSAndroid Build Coastguard Worker         // Add the class->method name (so stripping the signature).
57*795d594fSAndroid Build Coastguard Worker         AddSignatureToApiList(signature.substr(0, pos), membership);
58*795d594fSAndroid Build Coastguard Worker       }
59*795d594fSAndroid Build Coastguard Worker       pos = signature.find(':');
60*795d594fSAndroid Build Coastguard Worker       if (pos != std::string::npos) {
61*795d594fSAndroid Build Coastguard Worker         // Add the class->field name (so stripping the type).
62*795d594fSAndroid Build Coastguard Worker         AddSignatureToApiList(signature.substr(0, pos), membership);
63*795d594fSAndroid Build Coastguard Worker       }
64*795d594fSAndroid Build Coastguard Worker     }
65*795d594fSAndroid Build Coastguard Worker   }
66*795d594fSAndroid Build Coastguard Worker   CHECK(!errors) << "Errors encountered while parsing file " << filename;
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker 
AddSignatureToApiList(const std::string & signature,hiddenapi::ApiList membership)69*795d594fSAndroid Build Coastguard Worker void HiddenApi::AddSignatureToApiList(const std::string& signature, hiddenapi::ApiList membership) {
70*795d594fSAndroid Build Coastguard Worker   auto it = api_list_.find(signature);
71*795d594fSAndroid Build Coastguard Worker   if (it == api_list_.end()) {
72*795d594fSAndroid Build Coastguard Worker     // Does not exist yet. Add it to list.
73*795d594fSAndroid Build Coastguard Worker     api_list_.emplace(signature, membership);
74*795d594fSAndroid Build Coastguard Worker   } else if (membership.GetMaxAllowedSdkVersion() < it->second.GetMaxAllowedSdkVersion()) {
75*795d594fSAndroid Build Coastguard Worker     // Already exist but `membership` is more restrictive.
76*795d594fSAndroid Build Coastguard Worker     it->second = membership;
77*795d594fSAndroid Build Coastguard Worker   } else {
78*795d594fSAndroid Build Coastguard Worker     // Already exists and `membership` is equally or less restrictive.
79*795d594fSAndroid Build Coastguard Worker   }
80*795d594fSAndroid Build Coastguard Worker }
81*795d594fSAndroid Build Coastguard Worker 
GetApiMethodName(const DexFile & dex_file,uint32_t method_index)82*795d594fSAndroid Build Coastguard Worker std::string HiddenApi::GetApiMethodName(const DexFile& dex_file, uint32_t method_index) {
83*795d594fSAndroid Build Coastguard Worker   std::stringstream ss;
84*795d594fSAndroid Build Coastguard Worker   const dex::MethodId& method_id = dex_file.GetMethodId(method_index);
85*795d594fSAndroid Build Coastguard Worker   ss << dex_file.GetTypeDescriptorView(method_id.class_idx_)
86*795d594fSAndroid Build Coastguard Worker      << "->"
87*795d594fSAndroid Build Coastguard Worker      << dex_file.GetMethodName(method_id)
88*795d594fSAndroid Build Coastguard Worker      << dex_file.GetMethodSignature(method_id).ToString();
89*795d594fSAndroid Build Coastguard Worker   return ss.str();
90*795d594fSAndroid Build Coastguard Worker }
91*795d594fSAndroid Build Coastguard Worker 
GetApiFieldName(const DexFile & dex_file,uint32_t field_index)92*795d594fSAndroid Build Coastguard Worker std::string HiddenApi::GetApiFieldName(const DexFile& dex_file, uint32_t field_index) {
93*795d594fSAndroid Build Coastguard Worker   std::stringstream ss;
94*795d594fSAndroid Build Coastguard Worker   const dex::FieldId& field_id = dex_file.GetFieldId(field_index);
95*795d594fSAndroid Build Coastguard Worker   ss << dex_file.GetTypeDescriptorView(field_id.class_idx_)
96*795d594fSAndroid Build Coastguard Worker      << "->"
97*795d594fSAndroid Build Coastguard Worker      << dex_file.GetFieldName(field_id)
98*795d594fSAndroid Build Coastguard Worker      << ":"
99*795d594fSAndroid Build Coastguard Worker      << dex_file.GetFieldTypeDescriptor(field_id);
100*795d594fSAndroid Build Coastguard Worker   return ss.str();
101*795d594fSAndroid Build Coastguard Worker }
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker }  // namespace art
104