Merge "fix RE for metalava actions" into main
diff --git a/core/config.mk b/core/config.mk
index a26ad67..90cc33c 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -813,7 +813,11 @@
requirements :=
# Set default value of KEEP_VNDK.
-KEEP_VNDK ?= true
+ifeq ($(RELEASE_DEPRECATE_VNDK),true)
+ KEEP_VNDK ?= false
+else
+ KEEP_VNDK ?= true
+endif
# BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED can be true only if early-mount of
# partitions is supported. But the early-mount must be supported for full
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index e2fadb0..1ad9053 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -58,7 +58,6 @@
"libaconfig_protos",
"libanyhow",
"libclap",
- "libitertools",
"libprotobuf",
"libserde",
"libserde_json",
diff --git a/tools/aconfig/Cargo.toml b/tools/aconfig/Cargo.toml
index 2edf4b8..941b30d 100644
--- a/tools/aconfig/Cargo.toml
+++ b/tools/aconfig/Cargo.toml
@@ -11,7 +11,6 @@
[dependencies]
anyhow = "1.0.69"
clap = { version = "4.1.8", features = ["derive"] }
-itertools = "0.10.5"
paste = "1.0.11"
protobuf = "3.2.0"
serde = { version = "1.0.152", features = ["derive"] }
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index 954eccc..05ee0d7 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -15,7 +15,6 @@
*/
use anyhow::Result;
-use itertools::Itertools;
use serde::Serialize;
use std::collections::BTreeSet;
use std::path::PathBuf;
@@ -35,18 +34,12 @@
{
let flag_elements: Vec<FlagElement> =
parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect();
- let namespace_set: BTreeSet<String> = flag_elements
- .iter()
- .unique_by(|f| &f.device_config_namespace)
- .map(|f| f.device_config_namespace.clone())
- .collect();
let properties_set: BTreeSet<String> =
flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect();
let is_read_write = flag_elements.iter().any(|elem| elem.is_read_write);
let is_test_mode = codegen_mode == CodegenMode::Test;
let context = Context {
flag_elements,
- namespace_set,
is_test_mode,
is_read_write,
properties_set,
@@ -82,7 +75,6 @@
#[derive(Serialize)]
struct Context {
pub flag_elements: Vec<FlagElement>,
- pub namespace_set: BTreeSet<String>,
pub is_test_mode: bool,
pub is_read_write: bool,
pub properties_set: BTreeSet<String>,
@@ -297,31 +289,7 @@
import android.provider.DeviceConfig.Properties;
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags {
- private static boolean aconfig_test_is_cached = false;
- private static boolean disabledRw = false;
- private static boolean enabledRw = true;
-
-
- private void load_overrides_aconfig_test() {
- try {
- Properties properties = DeviceConfig.getProperties("aconfig_test");
- disabledRw =
- properties.getBoolean("com.android.aconfig.test.disabled_rw", false);
- enabledRw =
- properties.getBoolean("com.android.aconfig.test.enabled_rw", true);
- } catch (NullPointerException e) {
- throw new RuntimeException(
- "Cannot read value from namespace aconfig_test "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- }
- aconfig_test_is_cached = true;
- }
-
+ private Properties mPropertiesAconfigTest;
@Override
@UnsupportedAppUsage
public boolean disabledRo() {
@@ -330,10 +298,18 @@
@Override
@UnsupportedAppUsage
public boolean disabledRw() {
- if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ if (mPropertiesAconfigTest == null) {
+ mPropertiesAconfigTest =
+ getProperties(
+ "aconfig_test",
+ "com.android.aconfig.test.disabled_rw"
+ );
}
- return disabledRw;
+ return mPropertiesAconfigTest
+ .getBoolean(
+ "com.android.aconfig.test.disabled_rw",
+ false
+ );
}
@Override
@UnsupportedAppUsage
@@ -348,10 +324,36 @@
@Override
@UnsupportedAppUsage
public boolean enabledRw() {
- if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ if (mPropertiesAconfigTest == null) {
+ mPropertiesAconfigTest =
+ getProperties(
+ "aconfig_test",
+ "com.android.aconfig.test.enabled_rw"
+ );
}
- return enabledRw;
+ return mPropertiesAconfigTest
+ .getBoolean(
+ "com.android.aconfig.test.enabled_rw",
+ true
+ );
+ }
+ private Properties getProperties(
+ String namespace,
+ String flagName) {
+ Properties properties = null;
+ try {
+ properties = DeviceConfig.getProperties(namespace);
+ } catch (NullPointerException e) {
+ throw new RuntimeException(
+ "Cannot read value of flag " + flagName + " from DeviceConfig. "
+ + "It could be that the code using flag executed "
+ + "before SettingsProvider initialization. "
+ + "Please use fixed read-only flag by adding "
+ + "is_fixed_read_only: true in flag declaration.",
+ e
+ );
+ }
+ return properties;
}
}
"#;
diff --git a/tools/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/templates/FeatureFlagsImpl.java.template
index 87d567c..ff089df 100644
--- a/tools/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/templates/FeatureFlagsImpl.java.template
@@ -8,41 +8,10 @@
{{ endif }}
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
-{{- if is_read_write }}
-{{- for namespace in namespace_set }}
- private static boolean {namespace}_is_cached = false;
-{{- endfor- }}
-
-{{ for flag in flag_elements }}
-{{- if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{- endif- }}
+{{ if is_read_write- }}
+{{ for properties in properties_set }}
+ private Properties {properties};
{{ endfor }}
-
-{{ for namespace in namespace_set }}
- private void load_overrides_{namespace}() \{
- try \{
- Properties properties = DeviceConfig.getProperties("{namespace}");
-
- {{- for flag in flag_elements }}
- {{- if flag.is_read_write }}
- {flag.method_name} =
- properties.getBoolean("{flag.device_config_flag}", {flag.default_value});
- {{- endif- }}
- {{ endfor }}
- } catch (NullPointerException e) \{
- throw new RuntimeException(
- "Cannot read value from namespace {namespace} "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- }
- {namespace}_is_cached = true;
- }
-{{ endfor- }}
{{ endif- }}
{{ for flag in flag_elements }}
@@ -50,15 +19,45 @@
@UnsupportedAppUsage
public boolean {flag.method_name}() \{
{{ -if flag.is_read_write }}
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
+ if ({flag.properties} == null) \{
+ {flag.properties} =
+ getProperties(
+ "{flag.device_config_namespace}",
+ "{flag.device_config_flag}"
+ );
}
- return {flag.method_name};
+ return {flag.properties}
+ .getBoolean(
+ "{flag.device_config_flag}",
+ {flag.default_value}
+ );
{{ else }}
return {flag.default_value};
{{ endif- }}
}
{{ endfor }}
+
+{{ -if is_read_write }}
+ private Properties getProperties(
+ String namespace,
+ String flagName) \{
+ Properties properties = null;
+ try \{
+ properties = DeviceConfig.getProperties(namespace);
+ } catch (NullPointerException e) \{
+ throw new RuntimeException(
+ "Cannot read value of flag " + flagName + " from DeviceConfig. "
+ + "It could be that the code using flag executed "
+ + "before SettingsProvider initialization. "
+ + "Please use fixed read-only flag by adding "
+ + "is_fixed_read_only: true in flag declaration.",
+ e
+ );
+ }
+
+ return properties;
+ }
+{{ endif- }}
}
{{ else }}
{#- Generate only stub if in test mode #}
@@ -71,6 +70,6 @@
throw new UnsupportedOperationException(
"Method is not implemented.");
}
-{{ endfor- }}
+{{ endfor }}
}
{{ endif }}
diff --git a/tools/metadata/OWNERS b/tools/metadata/OWNERS
new file mode 100644
index 0000000..03bcdf1
--- /dev/null
+++ b/tools/metadata/OWNERS
@@ -0,0 +1,4 @@
+dariofreni@google.com
+joeo@google.com
+ronish@google.com
+caditya@google.com
diff --git a/tools/metadata/generator.go b/tools/metadata/generator.go
index 8e82f7f..eb87755 100644
--- a/tools/metadata/generator.go
+++ b/tools/metadata/generator.go
@@ -73,7 +73,7 @@
return string(data)
}
-func processProtobuf(
+func processTestSpecProtobuf(
filePath string, ownershipMetadataMap *sync.Map, keyLocks *keyToLocksMap,
errCh chan error, wg *sync.WaitGroup,
) {
@@ -130,10 +130,11 @@
func main() {
inputFile := flag.String("inputFile", "", "Input file path")
outputFile := flag.String("outputFile", "", "Output file path")
+ rule := flag.String("rule", "", "Metadata rule (Hint: test_spec or code_metadata)")
flag.Parse()
- if *inputFile == "" || *outputFile == "" {
- fmt.Println("Usage: metadata -inputFile <input file path> -outputFile <output file path>")
+ if *inputFile == "" || *outputFile == "" || *rule == "" {
+ fmt.Println("Usage: metadata -rule <rule> -inputFile <input file path> -outputFile <output file path>")
os.Exit(1)
}
@@ -144,26 +145,33 @@
errCh := make(chan error, len(filePaths))
var wg sync.WaitGroup
- for _, filePath := range filePaths {
- wg.Add(1)
- go processProtobuf(filePath, ownershipMetadataMap, keyLocks, errCh, &wg)
+ switch *rule {
+ case "test_spec":
+ for _, filePath := range filePaths {
+ wg.Add(1)
+ go processTestSpecProtobuf(filePath, ownershipMetadataMap, keyLocks, errCh, &wg)
+ }
+
+ wg.Wait()
+ close(errCh)
+
+ for err := range errCh {
+ log.Fatal(err)
+ }
+
+ allKeys := getSortedKeys(ownershipMetadataMap)
+ var allMetadata []*test_spec_proto.TestSpec_OwnershipMetadata
+
+ for _, key := range allKeys {
+ value, _ := ownershipMetadataMap.Load(key)
+ metadataList := value.([]*test_spec_proto.TestSpec_OwnershipMetadata)
+ allMetadata = append(allMetadata, metadataList...)
+ }
+
+ writeOutput(*outputFile, allMetadata)
+ break
+ case "code_metadata":
+ default:
+ log.Fatalf("No specific processing implemented for rule '%s'.\n", *rule)
}
-
- wg.Wait()
- close(errCh)
-
- for err := range errCh {
- log.Fatal(err)
- }
-
- allKeys := getSortedKeys(ownershipMetadataMap)
- var allMetadata []*test_spec_proto.TestSpec_OwnershipMetadata
-
- for _, key := range allKeys {
- value, _ := ownershipMetadataMap.Load(key)
- metadataList := value.([]*test_spec_proto.TestSpec_OwnershipMetadata)
- allMetadata = append(allMetadata, metadataList...)
- }
-
- writeOutput(*outputFile, allMetadata)
}
diff --git a/tools/metadata/testdata/metadata_test.go b/tools/metadata/testdata/metadata_test.go
index 0cb80c3..03c4f29 100644
--- a/tools/metadata/testdata/metadata_test.go
+++ b/tools/metadata/testdata/metadata_test.go
@@ -10,7 +10,7 @@
func TestMetadata(t *testing.T) {
cmd := exec.Command(
- "metadata", "-inputFile", "./inputFiles.txt", "-outputFile",
+ "metadata", "-rule", "test_spec", "-inputFile", "./inputFiles.txt", "-outputFile",
"./generatedOutputFile.txt",
)
stderr, err := cmd.CombinedOutput()
@@ -40,7 +40,7 @@
func TestMetadataNegativeCase(t *testing.T) {
cmd := exec.Command(
- "metadata", "-inputFile", "./inputFilesNegativeCase.txt", "-outputFile",
+ "metadata", "-rule", "test_spec", "-inputFile", "./inputFilesNegativeCase.txt", "-outputFile",
"./generatedOutputFileNegativeCase.txt",
)
stderr, err := cmd.CombinedOutput()
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 2a7d23b..8ce6083 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -39,18 +39,23 @@
import threading
import time
import zipfile
+
+from typing import Iterable, Callable
from dataclasses import dataclass
-from genericpath import isdir
from hashlib import sha1, sha256
import images
-import rangelib
import sparse_img
from blockimgdiff import BlockImageDiff
logger = logging.getLogger(__name__)
+@dataclass
+class OptionHandler:
+ extra_long_opts: Iterable[str]
+ handler: Callable
+
class Options(object):
def __init__(self):
@@ -2793,12 +2798,19 @@
def ParseOptions(argv,
docstring,
extra_opts="", extra_long_opts=(),
- extra_option_handler=None):
+ extra_option_handler: Iterable[OptionHandler] = None):
"""Parse the options in argv and return any arguments that aren't
flags. docstring is the calling module's docstring, to be displayed
for errors and -h. extra_opts and extra_long_opts are for flags
defined by the caller, which are processed by passing them to
extra_option_handler."""
+ extra_long_opts = list(extra_long_opts)
+ if not isinstance(extra_option_handler, Iterable):
+ extra_option_handler = [extra_option_handler]
+
+ for handler in extra_option_handler:
+ if isinstance(handler, OptionHandler):
+ extra_long_opts.extend(handler.extra_long_opts)
try:
opts, args = getopt.getopt(
@@ -2860,8 +2872,19 @@
elif o in ("--logfile",):
OPTIONS.logfile = a
else:
- if extra_option_handler is None or not extra_option_handler(o, a):
- assert False, "unknown option \"%s\"" % (o,)
+ if extra_option_handler is None:
+ raise ValueError("unknown option \"%s\"" % (o,))
+ success = False
+ for handler in extra_option_handler:
+ if isinstance(handler, OptionHandler):
+ if handler.handler(o, a):
+ success = True
+ break
+ elif handler(o, a):
+ success = True
+ if not success:
+ raise ValueError("unknown option \"%s\"" % (o,))
+
if OPTIONS.search_path:
os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") +
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index de0e187..fa4ed09 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -265,7 +265,6 @@
import os
import os.path
import re
-import shlex
import shutil
import subprocess
import sys
@@ -274,6 +273,7 @@
import care_map_pb2
import common
import ota_utils
+import payload_signer
from ota_utils import (VABC_COMPRESSION_PARAM_SUPPORT, FinalizeMetadata, GetPackageMetadata,
PayloadGenerator, SECURITY_PATCH_LEVEL_PROP_NAME, ExtractTargetFiles, CopyTargetFilesDir)
from common import DoesInputFileContain, IsSparseImage
@@ -308,9 +308,6 @@
OPTIONS.cache_size = None
OPTIONS.stash_threshold = 0.8
OPTIONS.log_diff = None
-OPTIONS.payload_signer = None
-OPTIONS.payload_signer_args = []
-OPTIONS.payload_signer_maximum_signature_size = None
OPTIONS.extracted_input = None
OPTIONS.skip_postinstall = False
OPTIONS.skip_compatibility_check = False
@@ -1125,9 +1122,7 @@
def main(argv):
def option_handler(o, a):
- if o in ("-k", "--package_key"):
- OPTIONS.package_key = a
- elif o in ("-i", "--incremental_from"):
+ if o in ("-i", "--incremental_from"):
OPTIONS.incremental_source = a
elif o == "--full_radio":
OPTIONS.full_radio = True
@@ -1172,17 +1167,6 @@
"a float" % (a, o))
elif o == "--log_diff":
OPTIONS.log_diff = a
- elif o == "--payload_signer":
- OPTIONS.payload_signer = a
- elif o == "--payload_signer_args":
- OPTIONS.payload_signer_args = shlex.split(a)
- elif o == "--payload_signer_maximum_signature_size":
- OPTIONS.payload_signer_maximum_signature_size = a
- elif o == "--payload_signer_key_size":
- # TODO(Xunchang) remove this option after cleaning up the callers.
- logger.warning("The option '--payload_signer_key_size' is deprecated."
- " Use '--payload_signer_maximum_signature_size' instead.")
- OPTIONS.payload_signer_maximum_signature_size = a
elif o == "--extracted_input_target_files":
OPTIONS.extracted_input = a
elif o == "--skip_postinstall":
@@ -1258,7 +1242,6 @@
args = common.ParseOptions(argv, __doc__,
extra_opts="b:k:i:d:e:t:2o:",
extra_long_opts=[
- "package_key=",
"incremental_from=",
"full_radio",
"full_bootloader",
@@ -1277,10 +1260,6 @@
"verify",
"stash_threshold=",
"log_diff=",
- "payload_signer=",
- "payload_signer_args=",
- "payload_signer_maximum_signature_size=",
- "payload_signer_key_size=",
"extracted_input_target_files=",
"skip_postinstall",
"retrofit_dynamic_partitions",
@@ -1304,7 +1283,7 @@
"vabc_compression_param=",
"security_patch_level=",
"max_threads=",
- ], extra_option_handler=option_handler)
+ ], extra_option_handler=[option_handler, payload_signer.signer_options])
common.InitLogging()
if len(args) != 2:
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 6ca9d64..0a6ff39 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -37,7 +37,6 @@
OPTIONS.wipe_user_data = False
OPTIONS.downgrade = False
OPTIONS.key_passwords = {}
-OPTIONS.package_key = None
OPTIONS.incremental_source = None
OPTIONS.retrofit_dynamic_partitions = False
OPTIONS.output_metadata_path = None
diff --git a/tools/releasetools/payload_signer.py b/tools/releasetools/payload_signer.py
index bbd2896..a5d09e1 100644
--- a/tools/releasetools/payload_signer.py
+++ b/tools/releasetools/payload_signer.py
@@ -16,10 +16,51 @@
import common
import logging
-from common import OPTIONS
+import shlex
+from common import OPTIONS, OptionHandler
logger = logging.getLogger(__name__)
+OPTIONS.payload_signer = None
+OPTIONS.payload_signer_args = []
+OPTIONS.payload_signer_maximum_signature_size = None
+OPTIONS.package_key = None
+
+
+class SignerOptions(OptionHandler):
+
+ @staticmethod
+ def ParseOptions(o, a):
+ if o in ("-k", "--package_key"):
+ OPTIONS.package_key = a
+ elif o == "--payload_signer":
+ OPTIONS.payload_signer = a
+ elif o == "--payload_signer_args":
+ OPTIONS.payload_signer_args = shlex.split(a)
+ elif o == "--payload_signer_maximum_signature_size":
+ OPTIONS.payload_signer_maximum_signature_size = a
+ elif o == "--payload_signer_key_size":
+ # TODO(xunchang) remove this option after cleaning up the callers.
+ logger.warning("The option '--payload_signer_key_size' is deprecated."
+ " Use '--payload_signer_maximum_signature_size' instead.")
+ OPTIONS.payload_signer_maximum_signature_size = a
+ else:
+ return False
+ return True
+
+ def __init__(self):
+ super().__init__(
+ ["payload_signer=",
+ "package_key=",
+ "payload_signer_args=",
+ "payload_signer_maximum_signature_size=",
+ "payload_signer_key_size="],
+ SignerOptions.ParseOptions
+ )
+
+
+signer_options = SignerOptions()
+
class PayloadSigner(object):
"""A class that wraps the payload signing works.