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

Commit 6fa7a3c7 authored by Mark Punzalan's avatar Mark Punzalan
Browse files

[aapt2] Generate @FlaggedApi annotations

Like we currently do for @TestApi and @SystemApi, we look for
"@FlaggedApi" and its parameters in the comment above the resource.

Bug: 295328308
Test: Did the following:
1. Ran `atest aapt2_tests`
2. Ran `aapt2 link` on public-staging.xml with an added @FlaggedApi
   in the comment for the resource currently there. Verified the
   @FlaggedApi annotation is present in the generated R.java.
3. Ran `m framework-minus-apex` and it built successfully.
4. Modified the @FlaggedApi comment with an invalid value (e.g.,
   `Flags.FOO` which does not exist). The build failed. Since
   @FlaggedApi is a source-only annotation (i.e., not present in the
   R.class file), we want to verify it was actually used in the build.

Change-Id: I0739f888d40269915c0acea5650c386da1a1782e
parent c7f2ff98
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -49,16 +49,19 @@ struct AnnotationRule {
    kDeprecated = 0x01,
    kSystemApi = 0x02,
    kTestApi = 0x04,
    kFlaggedApi = 0x08,
  };

  StringPiece doc_str;
  uint32_t bit_mask;
  StringPiece annotation;
  bool preserve_params;
};

static std::array<AnnotationRule, 2> sAnnotationRules = {{
    {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi"},
    {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi"},
static std::array<AnnotationRule, 3> sAnnotationRules = {{
    {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi", true},
    {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi", false},
    {"@FlaggedApi", AnnotationRule::kFlaggedApi, "@android.annotation.FlaggedApi", true},
}};

void AnnotationProcessor::AppendCommentLine(std::string comment) {
@@ -73,12 +76,11 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) {
    std::string::size_type idx = comment.find(rule.doc_str.data());
    if (idx != std::string::npos) {
      // Captures all parameters associated with the specified annotation rule
      // by matching the first pair of parantheses after the rule.
      std::regex re(std::string(rule.doc_str) += "\\s*\\((.+)\\)");
      // by matching the first pair of parentheses after the rule.
      std::regex re(std::string(rule.doc_str).append(R"(\s*\((.+)\))"));
      std::smatch match_result;
      const bool is_match = std::regex_search(comment, match_result, re);
      // We currently only capture and preserve parameters for SystemApi.
      if (is_match && rule.bit_mask == AnnotationRule::kSystemApi) {
      if (is_match && rule.preserve_params) {
        annotation_parameter_map_[rule.bit_mask] = match_result[1].str();
        comment.erase(comment.begin() + match_result.position(),
                      comment.begin() + match_result.position() + match_result.length());
+30 −0
Original line number Diff line number Diff line
@@ -76,6 +76,36 @@ TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationParamsAndRemovesFromCommen
  EXPECT_THAT(annotations, HasSubstr("This is a system API"));
}

TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationAndRemovesFromComment) {
  AnnotationProcessor processor;
  processor.AppendComment("@FlaggedApi This is a flagged API");

  std::string annotations;
  StringOutputStream out(&annotations);
  Printer printer(&out);
  processor.Print(&printer);
  out.Flush();

  EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi"));
  EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
  EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
}

TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationParamsAndRemovesFromComment) {
  AnnotationProcessor processor;
  processor.AppendComment("@FlaggedApi (\"android.flags.my_flag\") This is a flagged API");

  std::string annotations;
  StringOutputStream out(&annotations);
  Printer printer(&out);
  processor.Print(&printer);
  out.Flush();

  EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi(\"android.flags.my_flag\")"));
  EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
  EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
}

TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) {
  AnnotationProcessor processor;
  processor.AppendComment("@TestApi This is a test API");