blob: a8301743aab3ad738a2aa6c885f3cde57b800114 [file] [log] [blame]
Nicolas Geoffray534a0a12018-03-24 20:02:25 +00001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_TOOLS_VERIDEX_HIDDEN_API_H_
18#define ART_TOOLS_VERIDEX_HIDDEN_API_H_
19
Artur Satayev7acb8462019-09-11 12:16:12 +010020#include "api_list_filter.h"
21
David Brazdildcfa89b2018-10-31 11:04:10 +000022#include "base/hiddenapi_flags.h"
Nicolas Geoffray2ebff052018-04-04 22:32:03 +010023#include "dex/method_reference.h"
Nicolas Geoffray11ed0272018-03-28 18:18:48 +010024
David Brazdil91690d32018-11-04 18:07:23 +000025#include <map>
Nicolas Geoffray11ed0272018-03-28 18:18:48 +010026#include <ostream>
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000027#include <string>
28
29namespace art {
30
31class DexFile;
32
Artur Satayev39c399a2019-09-13 16:09:09 +010033enum class SignatureSource {
34 UNKNOWN,
35 BOOT,
36 APP,
37};
38
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000039/**
40 * Helper class for logging if a method/field is in a hidden API list.
41 */
42class HiddenApi {
43 public:
Artur Satayev7acb8462019-09-11 12:16:12 +010044 HiddenApi(const char* flags_file, const ApiListFilter& api_list_filter);
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000045
David Brazdil47cd2722018-10-23 12:50:02 +010046 hiddenapi::ApiList GetApiList(const std::string& name) const {
David Brazdil91690d32018-11-04 18:07:23 +000047 auto it = api_list_.find(name);
David Brazdil90faceb2018-12-14 14:36:15 +000048 return (it == api_list_.end()) ? hiddenapi::ApiList() : it->second;
Nicolas Geoffray11ed0272018-03-28 18:18:48 +010049 }
50
Artur Satayev39c399a2019-09-13 16:09:09 +010051 bool ShouldReport(const std::string& signature) const {
52 return api_list_filter_.Matches(GetApiList(signature));
53 }
54
55 void AddSignatureSource(const std::string &signature, SignatureSource source) {
56 const auto type = GetApiClassName(signature);
57 auto it = source_.find(type);
58 if (it == source_.end() || it->second == SignatureSource::UNKNOWN) {
59 source_[type] = source;
60 } else if (it->second != source) {
61 LOG(WARNING) << type << "is present both in boot and in app.";
62 if (source == SignatureSource::BOOT) {
63 // Runtime resolves to boot type, so it takes precedence.
64 it->second = source;
65 }
66 } else {
67 // Already exists with the same source.
68 }
69 }
70
71 SignatureSource GetSignatureSource(const std::string& signature) const {
72 auto it = source_.find(GetApiClassName(signature));
73 return (it == source_.end()) ? SignatureSource::UNKNOWN : it->second;
74 }
75
76 bool IsInBoot(const std::string& signature) const {
77 return SignatureSource::BOOT == GetSignatureSource(signature);
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000078 }
79
80 static std::string GetApiMethodName(const DexFile& dex_file, uint32_t method_index);
81
82 static std::string GetApiFieldName(const DexFile& dex_file, uint32_t field_index);
83
Nicolas Geoffray2ebff052018-04-04 22:32:03 +010084 static std::string GetApiMethodName(MethodReference ref) {
85 return HiddenApi::GetApiMethodName(*ref.dex_file, ref.index);
86 }
87
Nicolas Geoffray4f6e5232018-04-18 12:54:04 +010088 static std::string ToInternalName(const std::string& str) {
89 std::string val = str;
90 std::replace(val.begin(), val.end(), '.', '/');
91 return "L" + val + ";";
92 }
93
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000094 private:
David Brazdil91690d32018-11-04 18:07:23 +000095 void AddSignatureToApiList(const std::string& signature, hiddenapi::ApiList membership);
Nicolas Geoffray534a0a12018-03-24 20:02:25 +000096
Artur Satayev39c399a2019-09-13 16:09:09 +010097 static std::string GetApiClassName(const std::string& signature) {
98 size_t pos = signature.find("->");
99 if (pos != std::string::npos) {
100 return signature.substr(0, pos);
101 }
102 return signature;
103 }
104
105 const ApiListFilter& api_list_filter_;
David Brazdil91690d32018-11-04 18:07:23 +0000106 std::map<std::string, hiddenapi::ApiList> api_list_;
Artur Satayev39c399a2019-09-13 16:09:09 +0100107 std::map<std::string, SignatureSource> source_;
Nicolas Geoffray534a0a12018-03-24 20:02:25 +0000108};
109
Nicolas Geoffray2ebff052018-04-04 22:32:03 +0100110struct HiddenApiStats {
111 uint32_t count = 0;
112 uint32_t reflection_count = 0;
113 uint32_t linking_count = 0;
Artur Satayev39c399a2019-09-13 16:09:09 +0100114 // Ensure enough space for kInvalid as well, and initialize all to zero
115 uint32_t api_counts[hiddenapi::ApiList::kValueSize] = {};
Nicolas Geoffray2ebff052018-04-04 22:32:03 +0100116};
117
Artur Satayev39c399a2019-09-13 16:09:09 +0100118
Nicolas Geoffray534a0a12018-03-24 20:02:25 +0000119} // namespace art
120
121#endif // ART_TOOLS_VERIDEX_HIDDEN_API_H_