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

Commit 68ee6d66 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

[aapt2] Fix the autoshifting sdk version <36

The old code used to update the parsed config's sdk version to
be at least Baklava (36) the same way we do it for other
components - assuming we need to make the whole configuration
target the first SDK release with the feature support.

This caused typos (e.g. 30.1) to be 'autocorrected' to 36.1
instead of letting the developer know about the typo. Given that
any version with minor set and sdkVersion <36 is just not valid,
it's safe to return an error instead at all times.

Bug: 438788698
Flag: EXEMPT host tools don't support flags
Test: atest aapt2_tests libandroidfw_tests
Change-Id: I890e3b1f2047f45030b865ed036221ff6d2a3e83
parent fe39dfe3
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -888,7 +888,7 @@ bool ConfigDescription::Parse(StringPiece str, ConfigDescription* out) {
  return false;

success:
  if (out != NULL) {
  if (out != nullptr) {
    ApplyVersionForCompatibility(&config);
    *out = config;
  }
@@ -898,12 +898,10 @@ success:
void ConfigDescription::ApplyVersionForCompatibility(
    ConfigDescription* config) {
  uint16_t min_sdk = 0;
  if (config->minorVersion != 0) {
    min_sdk = SDK_BAKLAVA;
  } else if (config->grammaticalInflection != 0) {
  if (config->grammaticalInflection != 0) {
    min_sdk = SDK_U;
  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
                == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) ==
                 ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
             config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
             config->colorMode & ResTable_config::MASK_HDR) {
    min_sdk = SDK_O;
@@ -911,8 +909,7 @@ void ConfigDescription::ApplyVersionForCompatibility(
    min_sdk = SDK_MARSHMALLOW;
  } else if (config->density == ResTable_config::DENSITY_ANY) {
    min_sdk = SDK_LOLLIPOP;
  } else if (config->smallestScreenWidthDp !=
                 ResTable_config::SCREENWIDTH_ANY ||
  } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
             config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
             config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
    min_sdk = SDK_HONEYCOMB_MR2;
@@ -931,13 +928,13 @@ void ConfigDescription::ApplyVersionForCompatibility(

  if (min_sdk > config->sdkVersion) {
    config->sdkVersion = min_sdk;
    config->minorVersion = 0;
  }
}

ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
  ConfigDescription copy = *this;
  copy.sdkVersion = 0;
  copy.minorVersion = 0;
  copy.version = 0;
  return copy;
}

+2 −2
Original line number Diff line number Diff line
@@ -235,9 +235,9 @@ TEST(ConfigDescriptionTest, ParseValidVersionQualifier) {
  EXPECT_STREQ("v19876.23450", config.toString());

  EXPECT_TRUE(TestParse("v34.1", &config));
  EXPECT_EQ(SDK_BAKLAVA, config.sdkVersion);
  EXPECT_EQ(34, config.sdkVersion);
  EXPECT_EQ(1, config.minorVersion);
  EXPECT_STREQ(StringPrintf("v%d.1", SDK_BAKLAVA).c_str(), config.toString());
  EXPECT_STREQ("v34.1", config.toString());
}

}  // namespace android
+12 −5
Original line number Diff line number Diff line
@@ -789,7 +789,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
  auto file_iterator  = inputs->Iterator();
  while (file_iterator->HasNext()) {
    auto file = file_iterator->Next();
    std::string path = file->GetSource().path;
    const std::string& path = file->GetSource().path;

    // Skip hidden input files
    if (file::IsHidden(path)) {
@@ -806,13 +806,22 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
    ResourcePathData path_data;
    if (auto maybe_path_data = ExtractResourcePathData(
        path, inputs->GetDirSeparator(), &err_str, options)) {
      path_data = maybe_path_data.value();
      path_data = std::move(maybe_path_data.value());
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource()) << err_str);
      error = true;
      continue;
    }

    if (path_data.config.minorVersion != 0 && path_data.config.sdkVersion < SDK_BAKLAVA) {
      context->GetDiagnostics()->Error(
          android::DiagMessage(file->GetSource())
          << "SDK version in '" << path_data.config
          << "' is not valid: minor versions are only available since v" << SDK_BAKLAVA);
      error = true;
      continue;
    }

    // Determine how to compile the file based on its type.
    auto compile_func = &CompileFile;
    if (path_data.resource_dir == "values" && path_data.extension == "xml") {
@@ -820,7 +829,6 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
      // We use a different extension (not necessary anymore, but avoids altering the existing
      // build system logic).
      path_data.extension = "arsc";

    } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) {
      if (*type != ResourceType::kRaw) {
        if (*type == ResourceType::kXml || path_data.extension == "xml") {
@@ -839,8 +847,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*

    // Treat periods as a reserved character that should not be present in a file name
    // Legacy support for AAPT which did not reserve periods
    if (compile_func != &CompileFile && !options.legacy_mode
        && std::count(path_data.name.begin(), path_data.name.end(), '.') != 0) {
    if (compile_func != &CompileFile && !options.legacy_mode && path_data.name.contains('.')) {
      error = true;
      context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                       << "file name cannot contain '.' other than for"
+36 −0
Original line number Diff line number Diff line
@@ -111,6 +111,42 @@ TEST_F(CompilerTest, MultiplePeriods) {
  ASSERT_EQ(::android::base::utf8::unlink(path5_out.c_str()), 0);
}

template <bool result>
static void VerifyCompile(IAaptContext* context, const std::string& src_path,
                          const std::string& out_dir, const std::string& out_file) {
  constexpr int expected_result_compile = result ? 0 : 1;
  constexpr int expected_result_unlink = result ? 0 : -1;
  StdErrDiagnostics diag;
  const std::string out_path = BuildPath({out_dir, out_file});
  ::android::base::utf8::unlink(out_path.c_str());
  ASSERT_EQ(TestCompile(src_path, out_dir, /** legacy */ false, diag), expected_result_compile);
  ASSERT_EQ(::android::base::utf8::unlink(out_path.c_str()), expected_result_unlink);
}

TEST_F(CompilerTest, MinorVersion) {
  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
  const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
                                         "integration-tests", "CompileTest", "versions.res"});
  const std::string kOutDir = testing::TempDir();

  VerifyCompile<true>(context.get(), BuildPath({kResDir, "values", "values.xml"}), kOutDir,
                      "values_values.arsc.flat");
  VerifyCompile<true>(context.get(), BuildPath({kResDir, "values-v20", "values.xml"}), kOutDir,
                      "values-v20_values.arsc.flat");
  VerifyCompile<false>(context.get(), BuildPath({kResDir, "values-v20.2", "values.xml"}), kOutDir,
                       "values-v20.2_values.arsc.flat");
  VerifyCompile<true>(context.get(), BuildPath({kResDir, "values-v36.3", "values.xml"}), kOutDir,
                      "values-v36.3_values.arsc.flat");
  VerifyCompile<true>(context.get(), BuildPath({kResDir, "drawable", "image.png"}), kOutDir,
                      "drawable_image.png.flat");
  VerifyCompile<true>(context.get(), BuildPath({kResDir, "drawable-v30", "image.png"}), kOutDir,
                      "drawable-v30_image.png.flat");
  VerifyCompile<false>(context.get(), BuildPath({kResDir, "drawable-v30.1", "image.png"}), kOutDir,
                       "drawable-v30.1_image.png.flat");
  VerifyCompile<true>(context.get(), BuildPath({kResDir, "drawable-v37.1", "image.png"}), kOutDir,
                      "drawable-v37.1_image.png.flat");
}

TEST_F(CompilerTest, DirInput) {
  StdErrDiagnostics diag;
  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+103 B
Loading image diff...
Loading