diff options
| author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-10 09:06:53 +0000 |
|---|---|---|
| committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-10 09:06:53 +0000 |
| commit | af05d31dd14df47931440054328471ee39062dea (patch) | |
| tree | 488f9fad5730da262340f0a106de7c3c0387cff5 | |
| parent | 437a9ffd0c5c96a2171419194e8608f11ef64d2b (diff) | |
| parent | 017c7f9328abb6c72aec5aa425517c7c69c343b9 (diff) | |
| download | platform_packages_modules_SdkExtensions-main-cg-testing-release.tar.gz platform_packages_modules_SdkExtensions-main-cg-testing-release.tar.bz2 platform_packages_modules_SdkExtensions-main-cg-testing-release.zip | |
Snap for 7810574 from 017c7f9328abb6c72aec5aa425517c7c69c343b9 to main-cg-testing-releasemain-cg-testing-release
Change-Id: If7d9f93034ab2f4a885b752219c367ceb7646901
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | derive_classpath/derive_classpath.cpp | 98 | ||||
| -rw-r--r-- | derive_classpath/derive_classpath.h | 16 | ||||
| -rw-r--r-- | derive_classpath/derive_classpath_test.cpp | 70 | ||||
| -rw-r--r-- | derive_classpath/main.cpp | 60 | ||||
| -rw-r--r-- | derive_sdk/derive_sdk.cpp | 3 | ||||
| -rw-r--r-- | derive_sdk/derive_sdk_test.cpp | 4 | ||||
| -rw-r--r-- | framework/java/android/os/ext/SdkExtensions.java | 5 | ||||
| -rw-r--r-- | gen_sdk/extensions_db.textpb | 63 | ||||
| -rw-r--r-- | tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java | 7 | ||||
| -rw-r--r-- | tests/cts/Extensions/src/android/os/ext/cts/SdkExtensionsTest.java | 11 | ||||
| -rw-r--r-- | tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s12.xml | 2 | ||||
| -rw-r--r-- | tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s45.xml | 2 | ||||
| -rw-r--r-- | tests/e2e/Extensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java | 4 |
14 files changed, 262 insertions, 85 deletions
@@ -61,5 +61,3 @@ are the steps necessary to do that: * add a unit test to `derive_sdk_test.cpp` verifying the new extensions works - Make the `SdkExtensions.getExtensionVersion` API support the new extensions. - Extend the CTS test to verify the above two behaviors. -- Update `RollbackManagerServiceImpl#getExtensionVersions` to account for the - new extension version. diff --git a/derive_classpath/derive_classpath.cpp b/derive_classpath/derive_classpath.cpp index d379a40..0c9c361 100644 --- a/derive_classpath/derive_classpath.cpp +++ b/derive_classpath/derive_classpath.cpp @@ -34,34 +34,51 @@ using Classpaths = std::unordered_map<Classpath, Filepaths>; static const std::regex kBindMountedApex("^/apex/[^/]+@[0-9]+/"); static const std::regex kApexPathRegex("(/apex/[^/]+)/"); -// Defines the order of individual fragments to be merged for BOOTCLASSPATH: -// 1. Jars in ART module always come first; -// 2. Jars defined as part of /system/etc/classpaths; -// 3. Jars defined in all non-ART apexes that expose /apex/*/etc/classpaths fragments. -// -// Notes: -// - Relative order in the individual fragment files is not changed when merging. -// - If a fragment file is matched by multiple globs, the first one is used; i.e. ART module -// fragment is only parsed once, even if there is a "/apex/*/" pattern later. -// - If there are multiple files matched for a glob pattern with wildcards, the results are sorted -// by pathname (default glob behaviour); i.e. all fragment files are sorted within a single -// "pattern block". -static const std::vector<std::string> kBootclasspathFragmentGlobPatterns = { - // ART module is a special case and must come first before any other classpath entries. - "/apex/com.android.art/etc/classpaths/bootclasspath.pb", - "/system/etc/classpaths/bootclasspath.pb", - "/apex/*/etc/classpaths/bootclasspath.pb", -}; +std::vector<std::string> getBootclasspathFragmentGlobPatterns(const Args& args) { + // Defines the order of individual fragments to be merged for BOOTCLASSPATH: + // 1. Jars in ART module always come first; + // 2. Jars defined as part of /system/etc/classpaths; + // 3. Jars defined in all non-ART apexes that expose /apex/*/etc/classpaths fragments. + // + // Notes: + // - Relative order in the individual fragment files is not changed when merging. + // - If a fragment file is matched by multiple globs, the first one is used; i.e. ART module + // fragment is only parsed once, even if there is a "/apex/*/" pattern later. + // - If there are multiple files matched for a glob pattern with wildcards, the results are sorted + // by pathname (default glob behaviour); i.e. all fragment files are sorted within a single + // "pattern block". + std::vector<std::string> patterns = { + // ART module is a special case and must come first before any other classpath entries. + "/apex/com.android.art/etc/classpaths/bootclasspath.pb", + }; + if (args.system_bootclasspath_fragment.empty()) { + patterns.emplace_back("/system/etc/classpaths/bootclasspath.pb"); + } else { + // TODO: Avoid applying glob(3) expansion later to this path. Although the caller should not + // provide a path that contains '*', it can technically happen. Instead of checking the string + // format, we should just avoid the glob(3) for this string. + patterns.emplace_back(args.system_bootclasspath_fragment); + } + patterns.emplace_back("/apex/*/etc/classpaths/bootclasspath.pb"); + return patterns; +} -// Defines the order of individual fragments to be merged for SYSTEMSERVERCLASSPATH. -// -// ART system server jars are not special in this case, and are considered to be part of all the -// other apexes that may expose system server jars. -// -// All notes from kBootclasspathFragmentGlobPatterns apply here. -static const std::vector<std::string> kSystemserverclasspathFragmentGlobPatterns = { - "/system/etc/classpaths/systemserverclasspath.pb", - "/apex/*/etc/classpaths/systemserverclasspath.pb", +std::vector<std::string> getSystemserverclasspathFragmentGlobPatterns(const Args& args) { + // Defines the order of individual fragments to be merged for SYSTEMSERVERCLASSPATH. + // + // ART system server jars are not special in this case, and are considered to be part of all the + // other apexes that may expose system server jars. + // + // All notes from getBootclasspathFragmentGlobPatterns apply here. + std::vector<std::string> patterns; + if (args.system_systemserverclasspath_fragment.empty()) { + patterns.emplace_back("/system/etc/classpaths/systemserverclasspath.pb"); + } else { + // TODO: Avoid applying glob(3) expansion later to this path. See above. + patterns.emplace_back(args.system_systemserverclasspath_fragment); + } + patterns.emplace_back("/apex/*/etc/classpaths/systemserverclasspath.pb"); + return patterns; }; // Finds all classpath fragment files that match the glob pattern and appends them to `fragments`. @@ -149,15 +166,15 @@ std::string GetAllowedJarPathPrefix(const std::string& fragment_path) { } // Finds and parses all classpath fragments on device matching given glob patterns. -bool ParseFragments(const std::string& globPatternPrefix, Classpaths& classpaths, bool boot_jars) { +bool ParseFragments(const Args& args, Classpaths& classpaths, bool boot_jars) { LOG(INFO) << "ParseFragments for " << (boot_jars ? "bootclasspath" : "systemserverclasspath"); - auto glob_patterns = - boot_jars ? kBootclasspathFragmentGlobPatterns : kSystemserverclasspathFragmentGlobPatterns; + auto glob_patterns = boot_jars ? getBootclasspathFragmentGlobPatterns(args) + : getSystemserverclasspathFragmentGlobPatterns(args); Filepaths fragments; for (const auto& pattern : glob_patterns) { - if (!GlobClasspathFragments(&fragments, globPatternPrefix + pattern)) { + if (!GlobClasspathFragments(&fragments, args.glob_pattern_prefix + pattern)) { return false; } } @@ -188,33 +205,24 @@ bool ParseFragments(const std::string& globPatternPrefix, Classpaths& classpaths // Generates /data/system/environ/classpath exports file by globing and merging individual // classpaths.proto config fragments. The exports file is read by init.rc to setenv *CLASSPATH // environ variables at runtime. -bool GenerateClasspathExports(std::string_view output_path) { - // Outside of tests use actual config fragments. - return GenerateClasspathExports("", output_path); -} - -// Internal implementation of GenerateClasspathExports that allows putting config fragments in -// temporary directories. `globPatternPrefix` is appended to each glob pattern from -// kBootclasspathFragmentGlobPatterns and kSystemserverclasspathFragmentGlobPatterns, which allows -// adding mock configs in /data/local/tmp for example. -bool GenerateClasspathExports(const std::string& globPatternPrefix, std::string_view output_path) { +bool GenerateClasspathExports(const Args& args) { // Parse all known classpath fragments CHECK(android::modules::sdklevel::IsAtLeastS()) << "derive_classpath must only be run on Android 12 or above"; Classpaths classpaths; - if (!ParseFragments(globPatternPrefix, classpaths, /*boot_jars=*/true)) { + if (!ParseFragments(args, classpaths, /*boot_jars=*/true)) { LOG(ERROR) << "Failed to parse BOOTCLASSPATH fragments"; return false; } - if (!ParseFragments(globPatternPrefix, classpaths, /*boot_jars=*/false)) { + if (!ParseFragments(args, classpaths, /*boot_jars=*/false)) { LOG(ERROR) << "Failed to parse SYSTEMSERVERCLASSPATH fragments"; return false; } // Write export actions for init.rc - if (!WriteClasspathExports(classpaths, output_path)) { - PLOG(ERROR) << "Failed to write " << output_path; + if (!WriteClasspathExports(classpaths, args.output_path)) { + PLOG(ERROR) << "Failed to write " << args.output_path; return false; } return true; diff --git a/derive_classpath/derive_classpath.h b/derive_classpath/derive_classpath.h index a99e561..b0716f3 100644 --- a/derive_classpath/derive_classpath.h +++ b/derive_classpath/derive_classpath.h @@ -24,11 +24,19 @@ namespace derive_classpath { constexpr std::string_view kGeneratedClasspathExportsFilepath = "/data/system/environ/classpath"; -bool GenerateClasspathExports(std::string_view output_path = kGeneratedClasspathExportsFilepath); +struct Args { + std::string_view output_path; -// This must only be used in tests. -bool GenerateClasspathExports(const std::string& globPatternPrefix, - std::string_view output_path = kGeneratedClasspathExportsFilepath); + // Alternative *classpath.pb files if provided. + std::string system_bootclasspath_fragment; + std::string system_systemserverclasspath_fragment; + + // Test only. glob_pattern_prefix is appended to each glob pattern to allow adding mock configs in + // /data/local/tmp for example. + std::string glob_pattern_prefix; +}; + +bool GenerateClasspathExports(const Args& args); } // namespace derive_classpath } // namespace android diff --git a/derive_classpath/derive_classpath_test.cpp b/derive_classpath/derive_classpath_test.cpp index 97e2581..6e503f3 100644 --- a/derive_classpath/derive_classpath_test.cpp +++ b/derive_classpath/derive_classpath_test.cpp @@ -49,7 +49,7 @@ class DeriveClasspathTest : public ::testing::Test { ~DeriveClasspathTest() override { // Not really needed, as a test device will re-generate a proper classpath on reboot, // but it's better to leave it in a clean state after a test. - GenerateClasspathExports(); + GenerateClasspathExports(default_args_); } const std::string working_dir() { return std::string(temp_dir_.path); } @@ -115,7 +115,16 @@ class DeriveClasspathTest : public ::testing::Test { ASSERT_TRUE(android::base::WriteStringToFile(buf, fragment_path, true)); } - TemporaryDir temp_dir_; + const TemporaryDir temp_dir_; + + const Args default_args_ = { + .output_path = kGeneratedClasspathExportsFilepath, + }; + + const Args default_args_with_test_dir_ = { + .output_path = kGeneratedClasspathExportsFilepath, + .glob_pattern_prefix = temp_dir_.path, + }; }; using DeriveClasspathDeathTest = DeriveClasspathTest; @@ -123,7 +132,7 @@ using DeriveClasspathDeathTest = DeriveClasspathTest; // Check only known *CLASSPATH variables are exported. TEST_F(DeriveClasspathTest, DefaultNoUnknownClasspaths) { // Re-generate default on device classpaths - GenerateClasspathExports(); + GenerateClasspathExports(default_args_); const std::vector<std::string> exportLines = ParseExportsFile(); // The first three lines are tested above. @@ -138,7 +147,7 @@ TEST_F(DeriveClasspathTest, TempConfig) { AddJarToClasspath("/apex/com.android.baz", "/apex/com.android.baz/javalib/baz", SYSTEMSERVERCLASSPATH); - ASSERT_TRUE(GenerateClasspathExports(working_dir())); + ASSERT_TRUE(GenerateClasspathExports(default_args_with_test_dir_)); const std::vector<std::string> exportLines = ParseExportsFile(); @@ -160,7 +169,7 @@ TEST_F(DeriveClasspathTest, ModulesAreSorted) { AddJarToClasspath("/apex/com.android.bar", "/apex/com.android.bar/javalib/bar", BOOTCLASSPATH); AddJarToClasspath("/apex/com.android.baz", "/apex/com.android.baz/javalib/baz", BOOTCLASSPATH); - ASSERT_TRUE(GenerateClasspathExports(working_dir())); + ASSERT_TRUE(GenerateClasspathExports(default_args_with_test_dir_)); const std::vector<std::string> exportLines = ParseExportsFile(); const std::vector<std::string> splitExportLine = SplitClasspathExportLine(exportLines[0]); @@ -187,7 +196,11 @@ TEST_F(DeriveClasspathTest, CustomOutputLocation) { android::base::unique_fd fd(memfd_create("temp_file", MFD_CLOEXEC)); ASSERT_TRUE(fd.ok()) << "Unable to open temp-file"; const std::string file_name = android::base::StringPrintf("/proc/self/fd/%d", fd.get()); - ASSERT_TRUE(GenerateClasspathExports(working_dir(), file_name)); + Args args = { + .output_path = file_name, + .glob_pattern_prefix = working_dir(), + }; + ASSERT_TRUE(GenerateClasspathExports(args)); const std::vector<std::string> exportLines = ParseExportsFile(file_name.c_str()); const std::vector<std::string> splitExportLine = SplitClasspathExportLine(exportLines[0]); @@ -203,12 +216,50 @@ TEST_F(DeriveClasspathTest, CustomOutputLocation) { EXPECT_EQ(expectedJars, exportValue); } +// Test alternative .pb for bootclasspath and systemclasspath. +TEST_F(DeriveClasspathTest, CustomInputLocation) { + AddJarToClasspath("/other", "/other/bcp-jar", BOOTCLASSPATH); + AddJarToClasspath("/other", "/other/systemserver-jar", SYSTEMSERVERCLASSPATH); + AddJarToClasspath("/apex/com.android.art", "/apex/com.android.art/javalib/art", BOOTCLASSPATH); + AddJarToClasspath("/apex/com.android.foo", "/apex/com.android.foo/javalib/foo", BOOTCLASSPATH); + AddJarToClasspath("/apex/com.android.baz", "/apex/com.android.baz/javalib/baz", + SYSTEMSERVERCLASSPATH); + + Args args = default_args_with_test_dir_; + args.system_bootclasspath_fragment = "/other/etc/classpaths/bootclasspath.pb"; + args.system_systemserverclasspath_fragment = "/other/etc/classpaths/systemserverclasspath.pb"; + + ASSERT_TRUE(GenerateClasspathExports(args)); + + const std::vector<std::string> exportLines = ParseExportsFile(); + + std::vector<std::string> splitExportLine; + splitExportLine = SplitClasspathExportLine(exportLines[0]); + EXPECT_EQ("BOOTCLASSPATH", splitExportLine[1]); + const std::string expectedBcpJars( + "/apex/com.android.art/javalib/art" + ":/other/bcp-jar" + ":/apex/com.android.foo/javalib/foo"); + EXPECT_EQ(expectedBcpJars, splitExportLine[2]); + + splitExportLine = SplitClasspathExportLine(exportLines[2]); + EXPECT_EQ("SYSTEMSERVERCLASSPATH", splitExportLine[1]); + const std::string expectedSystemServerJars( + "/other/systemserver-jar" + ":/apex/com.android.baz/javalib/baz"); + EXPECT_EQ(expectedSystemServerJars, splitExportLine[2]); +} + // Test output location that can't be written to. TEST_F(DeriveClasspathTest, NonWriteableOutputLocation) { AddJarToClasspath("/apex/com.android.art", "/apex/com.android.art/javalib/art", BOOTCLASSPATH); AddJarToClasspath("/system", "/system/framework/jar", BOOTCLASSPATH); - ASSERT_FALSE(GenerateClasspathExports(working_dir(), "/system/non_writable_path")); + Args args = { + .output_path = "/system/non_writable_path", + .glob_pattern_prefix = working_dir(), + }; + ASSERT_FALSE(GenerateClasspathExports(args)); } // Test apexes only export their own jars. @@ -220,7 +271,8 @@ TEST_F(DeriveClasspathDeathTest, ApexJarsBelongToApex) { AddJarToClasspath("/apex/com.android.foo", "/apex/com.android.foo/javalib/foo", BOOTCLASSPATH); AddJarToClasspath("/apex/com.android.bar", "/apex/wrong/path/bar", BOOTCLASSPATH); - EXPECT_DEATH(GenerateClasspathExports(working_dir()), "must not export a jar.*wrong/path/bar"); + EXPECT_DEATH(GenerateClasspathExports(default_args_with_test_dir_), + "must not export a jar.*wrong/path/bar"); } // Test classpath fragments export jars for themselves. @@ -251,7 +303,7 @@ TEST_F(DeriveClasspathDeathTest, WrongClasspathInFragments) { ASSERT_EQ(0, system(cmd.c_str())); ASSERT_TRUE(android::base::WriteStringToFile(buf, fragment_path, true)); - EXPECT_DEATH(GenerateClasspathExports(working_dir()), + EXPECT_DEATH(GenerateClasspathExports(default_args_with_test_dir_), "must not export a jar for SYSTEMSERVERCLASSPATH"); } diff --git a/derive_classpath/main.cpp b/derive_classpath/main.cpp index b896eb9..8807cdb 100644 --- a/derive_classpath/main.cpp +++ b/derive_classpath/main.cpp @@ -15,22 +15,66 @@ */ #include <android-base/logging.h> +#include <android-base/strings.h> #include <cstdlib> #include <string_view> #include "derive_classpath.h" -int main(int argc, char** argv) { - std::string_view output_location; - if (argc == 1) { - output_location = android::derive_classpath::kGeneratedClasspathExportsFilepath; - } else if (argc == 2) { - output_location = argv[1]; +bool ArgumentMatches(std::string_view argument, std::string_view prefix, std::string_view* value) { + if (android::base::StartsWith(argument, prefix)) { + *value = argument.substr(prefix.size()); + return true; + } + return false; +} + +// Command line flags need to be considered as a de facto API since there may be callers outside +// of the SdkExtensions APEX, which needs to run on older Android versions. For example, otapreopt +// currently executes derive_classpath with a single output file. When changing the flags, make sure +// it won't break on older Android. +bool ParseArgs(android::derive_classpath::Args& args, int argc, char** argv) { + // Parse flags + std::vector<std::string_view> positional_args; + for (int i = 1; i < argc; ++i) { + const std::string_view arg = argv[i]; + std::string_view value; + if (ArgumentMatches(arg, "--bootclasspath-fragment=", &value)) { + if (!args.system_bootclasspath_fragment.empty()) { + LOG(ERROR) << "Duplicated flag --bootclasspath-fragment is specified"; + return false; + } + args.system_bootclasspath_fragment = value; + } else if (ArgumentMatches(arg, "--systemserverclasspath-fragment=", &value)) { + if (!args.system_bootclasspath_fragment.empty()) { + LOG(ERROR) << "Duplicated flag --systemserverclasspath-fragment is specified"; + return false; + } + args.system_systemserverclasspath_fragment = value; + } else { + positional_args.emplace_back(arg); + } + } + + // Handle positional args + if (positional_args.size() == 0) { + args.output_path = android::derive_classpath::kGeneratedClasspathExportsFilepath; + } else if (positional_args.size() == 1) { + args.output_path = positional_args[0]; } else { - LOG(ERROR) << "too many arguments " << argc; + LOG(ERROR) << "Unrecognized positional arguments: " + << android::base::Join(positional_args, ' '); + return false; + } + return true; +} + +int main(int argc, char** argv) { + android::derive_classpath::Args args; + if (!ParseArgs(args, argc, argv)) { return EXIT_FAILURE; } - if (!android::derive_classpath::GenerateClasspathExports(output_location)) { + if (!android::derive_classpath::GenerateClasspathExports(args)) { return EXIT_FAILURE; } return EXIT_SUCCESS; diff --git a/derive_sdk/derive_sdk.cpp b/derive_sdk/derive_sdk.cpp index 29cfca5..0b503de 100644 --- a/derive_sdk/derive_sdk.cpp +++ b/derive_sdk/derive_sdk.cpp @@ -41,6 +41,7 @@ static const std::unordered_map<std::string, SdkModule> kApexNameToModule = { {"com.android.media", SdkModule::MEDIA}, {"com.android.mediaprovider", SdkModule::MEDIA_PROVIDER}, {"com.android.permission", SdkModule::PERMISSIONS}, + {"com.android.scheduling", SdkModule::SCHEDULING}, {"com.android.sdkext", SdkModule::SDK_EXTENSIONS}, {"com.android.os.statsd", SdkModule::STATSD}, {"com.android.tethering", SdkModule::TETHERING}, @@ -51,7 +52,7 @@ static const std::unordered_set<SdkModule> kRModules = { SdkModule::PERMISSIONS, SdkModule::SDK_EXTENSIONS, SdkModule::STATSD, SdkModule::TETHERING, }; -static const std::unordered_set<SdkModule> kSModules = {SdkModule::ART}; +static const std::unordered_set<SdkModule> kSModules = {SdkModule::ART, SdkModule::SCHEDULING}; bool ReadDatabase(const std::string& db_path, ExtensionDatabase& db) { std::string contents; diff --git a/derive_sdk/derive_sdk_test.cpp b/derive_sdk/derive_sdk_test.cpp index 70d7dff..580544e 100644 --- a/derive_sdk/derive_sdk_test.cpp +++ b/derive_sdk/derive_sdk_test.cpp @@ -88,8 +88,8 @@ class DeriveSdkTest : public ::testing::Test { }; TEST_F(DeriveSdkTest, CurrentSystemImageValue) { - EXPECT_R(0); - EXPECT_S(0); + EXPECT_R(1); + EXPECT_S(1); } TEST_F(DeriveSdkTest, OneDessert_OneVersion_OneApex) { diff --git a/framework/java/android/os/ext/SdkExtensions.java b/framework/java/android/os/ext/SdkExtensions.java index f36a3f6..ac1929e 100644 --- a/framework/java/android/os/ext/SdkExtensions.java +++ b/framework/java/android/os/ext/SdkExtensions.java @@ -43,14 +43,11 @@ import java.util.Map; public class SdkExtensions { // S_VERSION_CODE is a separate field to simplify management across branches. - private static final int VERSION_CODE_S = VERSION_CODES.CUR_DEVELOPMENT; + private static final int VERSION_CODE_S = VERSION_CODES.S; private static final int R_EXTENSION_INT; private static final int S_EXTENSION_INT; private static final Map<Integer, Integer> ALL_EXTENSION_INTS; static { - // Note: when adding more extension versions, the logic that records current - // extension versions when saving a rollback must also be updated. - // At the time of writing this is in RollbackManagerServiceImpl#getExtensionVersions() R_EXTENSION_INT = SystemProperties.getInt("build.version.extensions.r", 0); S_EXTENSION_INT = SystemProperties.getInt("build.version.extensions.s", 0); Map<Integer, Integer> extensions = new HashMap<Integer, Integer>(); diff --git a/gen_sdk/extensions_db.textpb b/gen_sdk/extensions_db.textpb index e69de29..5d54a58 100644 --- a/gen_sdk/extensions_db.textpb +++ b/gen_sdk/extensions_db.textpb @@ -0,0 +1,63 @@ +versions { + version: 1 + requirements { + module: ART + version { + version: 1 + } + } + requirements { + module: CONSCRYPT + version { + version: 1 + } + } + requirements { + module: IPSEC + version { + version: 1 + } + } + requirements { + module: MEDIA + version { + version: 1 + } + } + requirements { + module: MEDIA_PROVIDER + version { + version: 1 + } + } + requirements { + module: PERMISSIONS + version { + version: 1 + } + } + requirements { + module: SCHEDULING + version { + version: 1 + } + } + requirements { + module: SDK_EXTENSIONS + version { + version: 1 + } + } + requirements { + module: STATSD + version { + version: 1 + } + } + requirements { + module: TETHERING + version { + version: 1 + } + } +} diff --git a/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java b/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java index 11d901f..93e7b2e 100644 --- a/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java +++ b/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java @@ -89,7 +89,6 @@ public class ClasspathsTest extends BaseHostJUnit4Test { "/apex/com.android.art/", "/system/", "/system_ext/", - "/apex/com.android.i18n/", "/apex/"); assertThat(jars) .prefixesMatch(expectedPrefixes) @@ -116,7 +115,7 @@ public class ClasspathsTest extends BaseHostJUnit4Test { assertThat(bootJars).containsAtLeastElementsIn(jars); ImmutableList<String> expectedPrefixes = ImmutableList.of( - "/apex/com.android.art/", "/system/", "/system_ext/", "/apex/com.android.i18n/"); + "/apex/com.android.art/", "/system/", "/system_ext/"); assertThat(jars) .prefixesMatch(expectedPrefixes) .inOrder(); @@ -201,6 +200,10 @@ public class ClasspathsTest extends BaseHostJUnit4Test { boolean ordered = true; int currentPrefixIndex = expected.isEmpty() ? -1 : 0; for (String jar : actual) { + if (ICU4J_JAR.equals(jar)) { + // TODO(b/191127295): ICU4j appears out of order, ignore it until fixed + continue; + } int prefixIndex = findFirstMatchingPrefix(jar, expected); if (prefixIndex == -1) { unexpectedJars.add(jar); diff --git a/tests/cts/Extensions/src/android/os/ext/cts/SdkExtensionsTest.java b/tests/cts/Extensions/src/android/os/ext/cts/SdkExtensionsTest.java index ea310c7..c3a42e8 100644 --- a/tests/cts/Extensions/src/android/os/ext/cts/SdkExtensionsTest.java +++ b/tests/cts/Extensions/src/android/os/ext/cts/SdkExtensionsTest.java @@ -38,7 +38,8 @@ public class SdkExtensionsTest extends TestCase { /** Verifies that getExtensionVersion only return existing versions */ public void testValidValues() throws Exception { - for (int sdk = Build.VERSION_CODES.R; sdk <= 1_000_000; sdk++) { + int firstUnassigned = Build.VERSION_CODES.S + 1; + for (int sdk = firstUnassigned; sdk <= 1_000_000; sdk++) { // No extension SDKs versions yet. assertEquals(0, SdkExtensions.getExtensionVersion(sdk)); } @@ -46,18 +47,20 @@ public class SdkExtensionsTest extends TestCase { /** Verifies that the public sysprops are set as expected */ public void testSystemProperties() throws Exception { - assertEquals("0", SystemProperties.get("build.version.extensions.r")); - String expectedS = SdkLevel.isAtLeastS() ? "0" : ""; + assertEquals("1", SystemProperties.get("build.version.extensions.r")); + String expectedS = SdkLevel.isAtLeastS() ? "1" : ""; assertEquals(expectedS, SystemProperties.get("build.version.extensions.s")); } public void testExtensionVersions() throws Exception { Map<Integer, Integer> versions = SdkExtensions.getAllExtensionVersions(); int expectedSize = 1; + assertEquals(1, (int) versions.get(Build.VERSION_CODES.R)); + if (SdkLevel.isAtLeastS()) { + assertEquals(1, (int) versions.get(Build.VERSION_CODES.S)); expectedSize++; } - assertEquals(0, (int) versions.get(Build.VERSION_CODES.R)); assertEquals(expectedSize, versions.size()); } diff --git a/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s12.xml b/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s12.xml index fc5995c..6331c66 100644 --- a/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s12.xml +++ b/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s12.xml @@ -18,7 +18,7 @@ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> <extension-sdk android:sdkVersion="30" android:minExtensionVersion="12" /> - <extension-sdk android:sdkVersion="10000" android:minExtensionVersion="12" /> + <extension-sdk android:sdkVersion="31" android:minExtensionVersion="12" /> </uses-sdk> <application android:hasCode="false"></application> diff --git a/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s45.xml b/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s45.xml index 478553c..e05772e 100644 --- a/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s45.xml +++ b/tests/e2e/Extensions/apps-with-reqs/AndroidManifest-s45.xml @@ -18,7 +18,7 @@ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> <extension-sdk android:sdkVersion="30" android:minExtensionVersion="45" /> - <extension-sdk android:sdkVersion="10000" android:minExtensionVersion="45" /> + <extension-sdk android:sdkVersion="31" android:minExtensionVersion="45" /> </uses-sdk> <application android:hasCode="false"></application> diff --git a/tests/e2e/Extensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java b/tests/e2e/Extensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java index e3f83c7..5a4839a 100644 --- a/tests/e2e/Extensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java +++ b/tests/e2e/Extensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java @@ -174,8 +174,8 @@ public class SdkExtensionsHostTest extends BaseHostJUnit4Test { } private void assertVersionDefault() throws Exception { - assertRVersionEquals(0); - assertSVersionEquals(0); + assertRVersionEquals(1); + assertSVersionEquals(1); assertTrue(broadcastForBoolean("MAKE_CALLS_DEFAULT", null)); } |
