Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03e470ea authored by Thiébaud Weksteen's avatar Thiébaud Weksteen Committed by Gerrit Code Review
Browse files

Merge "Add reporting tool for migration to @EnforcePermission" into main

parents 6e51daa4 df4cd065
Loading
Loading
Loading
Loading
+36 −21
Original line number Diff line number Diff line
@@ -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()
+6 −0
Original line number Diff line number Diff line
@@ -43,3 +43,9 @@ java_test_host {
        "AndroidUtilsLintChecker",
    ],
}

python_binary_host {
    name: "enforce_permission_counter",
    srcs: ["enforce_permission_counter.py"],
    libs: ["soong_lint_fix"],
}
+82 −0
Original line number Diff line number Diff line
#  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()