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

Commit 697c98e3 authored by Makoto Onuki's avatar Makoto Onuki Committed by Gerrit Code Review
Browse files

Merge "[ravenwood] Add a tool to convert text policy to annotations" into main

parents 2a9e272d 6434c030
Loading
Loading
Loading
Loading
+91 −0
Original line number Original line Diff line number Diff line
#!/bin/bash
# Copyright (C) 2024 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.

#
# Use "ravehleper pta" to create a shell script which:
# - Reads the text "policy" files
# - Convert to java annotations (using sed)
#

set -e


# Uncomment it to always build ravenhelper (slow)
# ${BUILD_CMD:-m} ravenhelper

# Get the target directory. Default to $ANDROID_BUILD_TOP.
TARGET_DIR="${TARGET_DIR:-${ANDROID_BUILD_TOP?\$ANDROID_BUILD_TOP must be set}}"

echo "Target dir=$TARGET_DIR"

cd "$TARGET_DIR"

# Add -v or -d as needed.
extra_args="$@"

OUT_SCRIPT="${OUT_SCRIPT:-/tmp/pta.sh}"

rm -f "$OUT_SCRIPT"

# If you want to run on other files, run this script with the following
# env vars predefined.

POLICIES="${POLICIES:-
frameworks/base/ravenwood/texts/ravenwood-common-policies.txt
frameworks/base/ravenwood/texts/ravenwood-framework-policies.txt
}"

SOURCES="${SOURCES:-
frameworks/base/core/java/
frameworks/base/graphics/java/
}"

AAC="${AAC:-frameworks/base/ravenwood/texts/ravenwood-annotation-allowed-classes.txt}"

with_flag() {
    local flag="$1"
    shift

    for arg in "$@"; do
        echo "$flag $arg"
    done
}

run() {
    echo "Running: $*"
    "$@"
}

run_pta() {
    local extra_args="$@"

    run ${RAVENHELPER_CMD:-ravenhelper pta} \
        --output-script $OUT_SCRIPT \
        --annotation-allowed-classes-file $AAC \
        $(with_flag --policy-override-file $POLICIES) \
        $(with_flag --src $SOURCES) \
        $extra_args

    if ! [[ -f $OUT_SCRIPT ]] ; then
        # no operations generated.
        exit 0
    fi

    echo
    echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT"
    return 0
}

run_pta "$extra_args"
 No newline at end of file
+5 −2
Original line number Original line Diff line number Diff line
# Ravenwood "policy" that should apply to all code.
# Ravenwood "policy" that should apply to all code.


# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
# which tries to convert policies to annotations.

# Keep all AIDL interfaces
# Keep all AIDL interfaces
class :aidl keepclass
class :aidl keepclass


@@ -13,8 +16,8 @@ class :sysprops keepclass
class :r keepclass
class :r keepclass


# Support APIs not available in standard JRE
# Support APIs not available in standard JRE
class java.io.FileDescriptor keep
class java.io.FileDescriptor  # no-pta
    method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$
    method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$
    method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$
    method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$
class java.util.LinkedHashMap keep
class java.util.LinkedHashMap  # no-pta
    method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest
    method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest
+38 −35
Original line number Original line Diff line number Diff line
# Ravenwood "policy" file for framework-minus-apex.
# Ravenwood "policy" file for framework-minus-apex.


# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
# which tries to convert policies to annotations.

# To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes.
# To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes.
# Note: The "rename" directive must use slashes (/) as a package name separator.
# Note: The "rename" directive must use slashes (/) as a package name separator.
rename com/.*/nano/   devicenano/
rename com/.*/nano/   devicenano/
rename android/.*/nano/   devicenano/
rename android/.*/nano/   devicenano/


# StatsD auto-generated
# StatsD auto-generated
class com.android.internal.util.FrameworkStatsLog keepclass
class com.android.internal.util.FrameworkStatsLog keepclass  # no-pta


# Exported to Mainline modules; cannot use annotations
# Exported to Mainline modules; cannot use annotations
class com.android.internal.util.FastXmlSerializer keepclass
class com.android.internal.util.FastXmlSerializer keepclass  # no-pta
class com.android.internal.util.FileRotator keepclass
class com.android.internal.util.FileRotator keepclass  # no-pta
class com.android.internal.util.HexDump keepclass
class com.android.internal.util.HexDump keepclass  # no-pta
class com.android.internal.util.IndentingPrintWriter keepclass
class com.android.internal.util.IndentingPrintWriter keepclass  # no-pta
class com.android.internal.util.LocalLog keepclass
class com.android.internal.util.LocalLog keepclass  # no-pta
class com.android.internal.util.MessageUtils keepclass
class com.android.internal.util.MessageUtils keepclass  # no-pta
class com.android.internal.util.TokenBucket keepclass
class com.android.internal.util.TokenBucket keepclass  # no-pta
class android.os.HandlerExecutor keepclass
class android.os.HandlerExecutor keepclass  # no-pta
class android.util.BackupUtils keepclass
class android.util.BackupUtils keepclass  # no-pta
class android.util.IndentingPrintWriter keepclass
class android.util.IndentingPrintWriter keepclass  # no-pta
class android.util.LocalLog keepclass
class android.util.LocalLog keepclass  # no-pta
class android.util.Pair keepclass
class android.util.Pair keepclass  # no-pta
class android.util.Rational keepclass
class android.util.Rational keepclass  # no-pta


# From modules-utils; cannot use annotations
# From modules-utils; cannot use annotations
class com.android.internal.util.Preconditions keepclass
class com.android.internal.util.Preconditions keepclass  # no-pta
class com.android.internal.logging.InstanceId keepclass
class com.android.internal.logging.InstanceId keepclass  # no-pta
class com.android.internal.logging.InstanceIdSequence keepclass
class com.android.internal.logging.InstanceIdSequence keepclass  # no-pta
class com.android.internal.logging.UiEvent keepclass
class com.android.internal.logging.UiEvent keepclass  # no-pta
class com.android.internal.logging.UiEventLogger keepclass
class com.android.internal.logging.UiEventLogger keepclass  # no-pta


# From modules-utils; cannot use annotations
# From modules-utils; cannot use annotations
class com.android.modules.utils.BinaryXmlPullParser keepclass
class com.android.modules.utils.BinaryXmlPullParser keepclass  # no-pta
class com.android.modules.utils.BinaryXmlSerializer keepclass
class com.android.modules.utils.BinaryXmlSerializer keepclass  # no-pta
class com.android.modules.utils.FastDataInput keepclass
class com.android.modules.utils.FastDataInput keepclass  # no-pta
class com.android.modules.utils.FastDataOutput keepclass
class com.android.modules.utils.FastDataOutput keepclass  # no-pta
class com.android.modules.utils.ModifiedUtf8 keepclass
class com.android.modules.utils.ModifiedUtf8 keepclass  # no-pta
class com.android.modules.utils.TypedXmlPullParser keepclass
class com.android.modules.utils.TypedXmlPullParser keepclass  # no-pta
class com.android.modules.utils.TypedXmlSerializer keepclass
class com.android.modules.utils.TypedXmlSerializer keepclass  # no-pta


# Uri
# Uri
class android.net.Uri keepclass
class android.net.Uri keepclass  # no-pta
class android.net.UriCodec keepclass
class android.net.UriCodec keepclass  # no-pta


# Telephony
# Telephony
class android.telephony.PinResult keepclass
class android.telephony.PinResult keepclass  # no-pta


# Just enough to support mocking, no further functionality
# Just enough to support mocking, no further functionality
class android.content.BroadcastReceiver keep
class android.content.BroadcastReceiver keep  # no-pta
    method <init> ()V keep
    method <init> ()V keep
class android.content.Context keep
class android.content.Context keep  # no-pta
    method <init> ()V keep
    method <init> ()V keep
    method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep
    method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep  # no-pta
class android.content.pm.PackageManager
class android.content.pm.PackageManager  # no-pta
    method <init> ()V keep
    method <init> ()V keep
class android.text.ClipboardManager keep
class android.text.ClipboardManager keep  # no-pta
    method <init> ()V keep
    method <init> ()V keep


# Just enough to allow ResourcesManager to run
# Just enough to allow ResourcesManager to run
class android.hardware.display.DisplayManagerGlobal keep
class android.hardware.display.DisplayManagerGlobal keep # no-pta
    method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
    method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
+12 −9
Original line number Original line Diff line number Diff line
# Ravenwood "policy" file for services.core.
# Ravenwood "policy" file for services.core.


# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
# which tries to convert policies to annotations.

# Auto-generated from XSD
# Auto-generated from XSD
class com.android.server.compat.config.Change keepclass
class com.android.server.compat.config.Change keepclass  # no-pta
class com.android.server.compat.config.Config keepclass
class com.android.server.compat.config.Config keepclass  # no-pta
class com.android.server.compat.config.XmlParser keepclass
class com.android.server.compat.config.XmlParser keepclass  # no-pta
class com.android.server.compat.overrides.ChangeOverrides keepclass
class com.android.server.compat.overrides.ChangeOverrides keepclass  # no-pta
class com.android.server.compat.overrides.OverrideValue keepclass
class com.android.server.compat.overrides.OverrideValue keepclass  # no-pta
class com.android.server.compat.overrides.Overrides keepclass
class com.android.server.compat.overrides.Overrides keepclass  # no-pta
class com.android.server.compat.overrides.RawOverrideValue keepclass
class com.android.server.compat.overrides.RawOverrideValue keepclass  # no-pta
class com.android.server.compat.overrides.XmlParser keepclass
class com.android.server.compat.overrides.XmlParser keepclass  # no-pta
class com.android.server.compat.overrides.XmlWriter keepclass
class com.android.server.compat.overrides.XmlWriter keepclass  # no-pta
 No newline at end of file
 No newline at end of file
+17 −10
Original line number Original line Diff line number Diff line
@@ -69,9 +69,9 @@ interface PolicyFileProcessor {
    fun onRename(pattern: Pattern, prefix: String)
    fun onRename(pattern: Pattern, prefix: String)


    /** "class" directive. */
    /** "class" directive. */
    fun onSimpleClassStart(className: String)
    fun onClassStart(className: String)
    fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason)
    fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason)
    fun onSimpleClassEnd(className: String)
    fun onClassEnd(className: String)


    fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason)
    fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason)
    fun onRedirectionClass(fromClassName: String, toClassName: String)
    fun onRedirectionClass(fromClassName: String, toClassName: String)
@@ -162,10 +162,10 @@ class TextFileFilterPolicyBuilder(
            )
            )
        }
        }


        override fun onSimpleClassStart(className: String) {
        override fun onClassStart(className: String) {
        }
        }


        override fun onSimpleClassEnd(className: String) {
        override fun onClassEnd(className: String) {
        }
        }


        override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) {
        override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) {
@@ -273,20 +273,23 @@ class TextFileFilterPolicyParser {
    private var rFilePolicy: FilterPolicyWithReason? = null
    private var rFilePolicy: FilterPolicyWithReason? = null


    /** Name of the file that's currently being processed.  */
    /** Name of the file that's currently being processed.  */
    var filename: String? = null
    var filename: String = ""
        private set
        private set


    /** 1-based line number in the current file */
    /** 1-based line number in the current file */
    var lineNumber = -1
    var lineNumber = -1
        private set
        private set


    /** Current line */
    var currentLineText = ""
        private set

    /**
    /**
     * Parse a given "policy" file.
     * Parse a given "policy" file.
     */
     */
    fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) {
    fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) {
        filename = inputName
        filename = inputName


        log.i("Parsing text policy file $inputName ...")
        this.processor = processor
        this.processor = processor
        BufferedReader(reader).use { rd ->
        BufferedReader(reader).use { rd ->
            lineNumber = 0
            lineNumber = 0
@@ -297,6 +300,7 @@ class TextFileFilterPolicyParser {
                        break
                        break
                    }
                    }
                    lineNumber++
                    lineNumber++
                    currentLineText = line
                    line = normalizeTextLine(line) // Remove comment and trim.
                    line = normalizeTextLine(line) // Remove comment and trim.
                    if (line.isEmpty()) {
                    if (line.isEmpty()) {
                        continue
                        continue
@@ -312,7 +316,7 @@ class TextFileFilterPolicyParser {


    private fun finishLastClass() {
    private fun finishLastClass() {
        currentClassName?.let { className ->
        currentClassName?.let { className ->
            processor.onSimpleClassEnd(className)
            processor.onClassEnd(className)
            currentClassName = null
            currentClassName = null
        }
        }
    }
    }
@@ -416,7 +420,7 @@ class TextFileFilterPolicyParser {
        if (fields.size <= 1) {
        if (fields.size <= 1) {
            throw ParseException("Class ('c') expects 1 or 2 fields.")
            throw ParseException("Class ('c') expects 1 or 2 fields.")
        }
        }
        val className = fields[1]
        val className = fields[1].toHumanReadableClassName()


        // superClass is set when the class name starts with a "*".
        // superClass is set when the class name starts with a "*".
        val superClass = resolveExtendingClass(className)
        val superClass = resolveExtendingClass(className)
@@ -436,6 +440,8 @@ class TextFileFilterPolicyParser {
            // It's a redirection class.
            // It's a redirection class.
            val toClass = policyStr.substring(1)
            val toClass = policyStr.substring(1)


            currentClassName = className
            processor.onClassStart(className)
            processor.onRedirectionClass(className, toClass)
            processor.onRedirectionClass(className, toClass)
        } else if (policyStr.startsWith("~")) {
        } else if (policyStr.startsWith("~")) {
            if (classType != SpecialClass.NotSpecial) {
            if (classType != SpecialClass.NotSpecial) {
@@ -447,6 +453,8 @@ class TextFileFilterPolicyParser {
            // It's a class-load hook
            // It's a class-load hook
            val callback = policyStr.substring(1)
            val callback = policyStr.substring(1)


            currentClassName = className
            processor.onClassStart(className)
            processor.onClassLoadHook(className, callback)
            processor.onClassLoadHook(className, callback)
        } else {
        } else {
            // Special case: if it's a class directive with no policy, then it encloses
            // Special case: if it's a class directive with no policy, then it encloses
@@ -455,7 +463,6 @@ class TextFileFilterPolicyParser {
            if (policyStr == "") {
            if (policyStr == "") {
                if (classType == SpecialClass.NotSpecial && superClass == null) {
                if (classType == SpecialClass.NotSpecial && superClass == null) {
                    currentClassName = className
                    currentClassName = className
                    processor.onSimpleClassStart(className)
                    return
                    return
                }
                }
                throw ParseException("Special class or subclass directive must have a policy")
                throw ParseException("Special class or subclass directive must have a policy")
@@ -471,7 +478,7 @@ class TextFileFilterPolicyParser {
                    // TODO: Duplicate check, etc
                    // TODO: Duplicate check, etc
                    if (superClass == null) {
                    if (superClass == null) {
                        currentClassName = className
                        currentClassName = className
                        processor.onSimpleClassStart(className)
                        processor.onClassStart(className)
                        processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON))
                        processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON))
                    } else {
                    } else {
                        processor.onSubClassPolicy(
                        processor.onSubClassPolicy(
Loading