diff options
-rw-r--r-- | tools/lint/fix/soong_lint_fix.py | 57 | ||||
-rw-r--r-- | tools/lint/utils/Android.bp | 6 | ||||
-rw-r--r-- | tools/lint/utils/enforce_permission_counter.py | 82 |
3 files changed, 124 insertions, 21 deletions
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py index acc0ad043171..b42f9eec99d0 100644 --- a/tools/lint/fix/soong_lint_fix.py +++ b/tools/lint/fix/soong_lint_fix.py @@ -64,27 +64,27 @@ class SoongModule: class SoongLintFix: """ - This class creates a command line tool that will - apply lint fixes to the platform via the necessary - combination of soong and shell commands. + This class creates a command line tool that will apply lint fixes to the + platform via the necessary combination of soong and shell commands. - It breaks up these operations into a few "private" methods - that are intentionally exposed so experimental code can tweak behavior. + It breaks up these operations into a few "private" methods that are + intentionally exposed so experimental code can tweak behavior. - The entry point, `run`, will apply lint fixes using the - intermediate `suggested-fixes` directory that soong creates during its - invocation of lint. + The entry point, `run`, will apply lint fixes using the intermediate + `suggested-fixes` directory that soong creates during its invocation of + lint. Basic usage: ``` from soong_lint_fix import SoongLintFix - SoongLintFix().run() + opts = SoongLintFixOptions() + opts.parse_args(sys.argv) + SoongLintFix(opts).run() ``` """ - def __init__(self): - self._parser = _setup_parser() - self._args = None + def __init__(self, opts): + self._opts = opts self._kwargs = None self._modules = [] @@ -96,19 +96,18 @@ class SoongLintFix: self._find_modules() self._lint() - if not self._args.no_fix: + if not self._opts.no_fix: self._fix() - if self._args.print: + if self._opts.print: self._print() def _setup(self): - self._args = self._parser.parse_args() env = os.environ.copy() - if self._args.check: - env["ANDROID_LINT_CHECK"] = self._args.check - if self._args.lint_module: - env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._args.lint_module + if self._opts.check: + env["ANDROID_LINT_CHECK"] = self._opts.check + if self._opts.lint_module: + env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._opts.lint_module self._kwargs = { "env": env, @@ -131,7 +130,7 @@ class SoongLintFix: with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f: module_info = json.load(f) - for module_name in self._args.modules: + for module_name in self._opts.modules: module = SoongModule(module_name) module.find(module_info) self._modules.append(module) @@ -169,6 +168,20 @@ class SoongLintFix: print(f.read()) +class SoongLintFixOptions: + """Options for SoongLintFix""" + + def __init__(self): + self.modules = [] + self.check = None + self.lint_module = None + self.no_fix = False + self.print = False + + def parse_args(self, args=None): + _setup_parser().parse_args(args, self) + + def _setup_parser(): parser = argparse.ArgumentParser(description=""" This is a python script that applies lint fixes to the platform: @@ -199,4 +212,6 @@ def _setup_parser(): return parser if __name__ == "__main__": - SoongLintFix().run() + opts = SoongLintFixOptions() + opts.parse_args(sys.argv) + SoongLintFix(opts).run() diff --git a/tools/lint/utils/Android.bp b/tools/lint/utils/Android.bp index 75e8d6863c20..439c86d564c7 100644 --- a/tools/lint/utils/Android.bp +++ b/tools/lint/utils/Android.bp @@ -43,3 +43,9 @@ java_test_host { "AndroidUtilsLintChecker", ], } + +python_binary_host { + name: "enforce_permission_counter", + srcs: ["enforce_permission_counter.py"], + libs: ["soong_lint_fix"], +} diff --git a/tools/lint/utils/enforce_permission_counter.py b/tools/lint/utils/enforce_permission_counter.py new file mode 100644 index 000000000000..b5c2ffe9885e --- /dev/null +++ b/tools/lint/utils/enforce_permission_counter.py @@ -0,0 +1,82 @@ +# Copyright (C) 2023 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. + +import re + +import soong_lint_fix + +# Libraries that constitute system_server. +# It is non-trivial to keep in sync with services/Android.bp as some +# module are post-processed (e.g, services.core). +TARGETS = [ + "services.core.unboosted", + "services.accessibility", + "services.appprediction", + "services.appwidget", + "services.autofill", + "services.backup", + "services.companion", + "services.contentcapture", + "services.contentsuggestions", + "services.coverage", + "services.devicepolicy", + "services.midi", + "services.musicsearch", + "services.net", + "services.people", + "services.print", + "services.profcollect", + "services.restrictions", + "services.searchui", + "services.smartspace", + "services.systemcaptions", + "services.translation", + "services.texttospeech", + "services.usage", + "services.usb", + "services.voiceinteraction", + "services.wallpapereffectsgeneration", + "services.wifi", +] + + +class EnforcePermissionMigratedCounter: + """Wrapper around lint_fix to count the number of AIDL methods annotated.""" + def run(self): + opts = soong_lint_fix.SoongLintFixOptions() + opts.check = "AnnotatedAidlCounter" + opts.lint_module = "AndroidUtilsLintChecker" + opts.no_fix = True + opts.modules = TARGETS + + self.linter = soong_lint_fix.SoongLintFix(opts) + self.linter.run() + self.parse_lint_reports() + + def parse_lint_reports(self): + counts = { "unannotated": 0, "enforced": 0, "notRequired": 0 } + for module in self.linter._modules: + with open(module.lint_report, "r") as f: + content = f.read() + keys = dict(re.findall(r'(\w+)=(\d+)', content)) + for key in keys: + counts[key] += int(keys[key]) + print(counts) + total = sum(counts.values()) + annotated_percent = (1 - (counts["unannotated"] / total)) * 100 + print("Annotated methods = %.2f%%" % (annotated_percent)) + + +if __name__ == "__main__": + EnforcePermissionMigratedCounter().run() |