Add support for @SystemApi annotation to aapt. (DO NOT MERGE)

When aapt sees @SystemApi in the XML comment associated with a resource,
it will now remove this tag from the comment (since is it not meaningful as
a Javadoc tag) and instead add an @android.annotation.SystemApi annotation
to the declared type or member.  This enables easy downstream processing of
this annotation from generated code.

Change-Id: If984908477648c0c90be52fdc955fbb891d99b28
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index e599643..f10904c 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -166,6 +166,35 @@
     ResTable_config mParams;
 };
 
+class AnnotationProcessor {
+public:
+    AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { }
+
+    void preprocessComment(String8& comment) {
+        if (comment.size() > 0) {
+            if (comment.contains("@deprecated")) {
+                mDeprecated = true;
+            }
+            if (comment.removeAll("@SystemApi")) {
+                mSystemApi = true;
+            }
+        }
+    }
+
+    void printAnnotations(FILE* fp, const char* indentStr) {
+        if (mDeprecated) {
+            fprintf(fp, "%s@Deprecated\n", indentStr);
+        }
+        if (mSystemApi) {
+            fprintf(fp, "%s@android.annotation.SystemApi\n", indentStr);
+        }
+    }
+
+private:
+    bool mDeprecated;
+    bool mSystemApi;
+};
+
 // ==========================================================================
 // ==========================================================================
 // ==========================================================================
@@ -1742,16 +1771,13 @@
 
         NA = idents.size();
 
-        bool deprecated = false;
-        
         String16 comment = symbols->getComment(realClassName);
+        AnnotationProcessor ann;
         fprintf(fp, "%s/** ", indentStr);
         if (comment.size() > 0) {
             String8 cmt(comment);
+            ann.preprocessComment(cmt);
             fprintf(fp, "%s\n", cmt.string());
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
         } else {
             fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string());
         }
@@ -1823,9 +1849,7 @@
         }
         fprintf(fp, "%s */\n", getIndentSpace(indent));
 
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", indentStr);
-        }
+        ann.printAnnotations(fp, indentStr);
         
         fprintf(fp,
                 "%spublic static final int[] %s = {\n"
@@ -1871,17 +1895,14 @@
                 //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
                 //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
                 const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-                
-                bool deprecated = false;
-                
+
+                AnnotationProcessor ann;
                 fprintf(fp, "%s/**\n", indentStr);
                 if (comment.size() > 0) {
                     String8 cmt(comment);
+                    ann.preprocessComment(cmt);
                     fprintf(fp, "%s  <p>\n%s  @attr description\n", indentStr, indentStr);
                     fprintf(fp, "%s  %s\n", indentStr, cmt.string());
-                    if (strstr(cmt.string(), "@deprecated") != NULL) {
-                        deprecated = true;
-                    }
                 } else {
                     fprintf(fp,
                             "%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\n"
@@ -1893,10 +1914,8 @@
                 }
                 if (typeComment.size() > 0) {
                     String8 cmt(typeComment);
+                    ann.preprocessComment(cmt);
                     fprintf(fp, "\n\n%s  %s\n", indentStr, cmt.string());
-                    if (strstr(cmt.string(), "@deprecated") != NULL) {
-                        deprecated = true;
-                    }
                 }
                 if (comment.size() > 0) {
                     if (pub) {
@@ -1915,9 +1934,7 @@
                         getSymbolPackage(name8, assets, pub).string(),
                         getSymbolName(name8).string());
                 fprintf(fp, "%s*/\n", indentStr);
-                if (deprecated) {
-                    fprintf(fp, "%s@Deprecated\n", indentStr);
-                }
+                ann.printAnnotations(fp, indentStr);
                 fprintf(fp,
                         "%spublic static final int %s_%s = %d;\n",
                         indentStr, nclassName.string(),
@@ -2056,16 +2073,14 @@
         String8 name8(sym.name);
         String16 comment(sym.comment);
         bool haveComment = false;
-        bool deprecated = false;
+        AnnotationProcessor ann;
         if (comment.size() > 0) {
             haveComment = true;
             String8 cmt(comment);
+            ann.preprocessComment(cmt);
             fprintf(fp,
                     "%s/** %s\n",
                     getIndentSpace(indent), cmt.string());
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
         } else if (sym.isPublic && !includePrivate) {
             sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
                 assets->getPackage().string(), className.string(),
@@ -2074,6 +2089,7 @@
         String16 typeComment(sym.typeComment);
         if (typeComment.size() > 0) {
             String8 cmt(typeComment);
+            ann.preprocessComment(cmt);
             if (!haveComment) {
                 haveComment = true;
                 fprintf(fp,
@@ -2082,16 +2098,11 @@
                 fprintf(fp,
                         "%s %s\n", getIndentSpace(indent), cmt.string());
             }
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
         }
         if (haveComment) {
             fprintf(fp,"%s */\n", getIndentSpace(indent));
         }
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
-        }
+        ann.printAnnotations(fp, getIndentSpace(indent));
         fprintf(fp, id_format,
                 getIndentSpace(indent),
                 flattenSymbol(name8).string(), (int)sym.int32Val);
@@ -2107,25 +2118,21 @@
         }
         String8 name8(sym.name);
         String16 comment(sym.comment);
-        bool deprecated = false;
+        AnnotationProcessor ann;
         if (comment.size() > 0) {
             String8 cmt(comment);
+            ann.preprocessComment(cmt);
             fprintf(fp,
                     "%s/** %s\n"
                      "%s */\n",
                     getIndentSpace(indent), cmt.string(),
                     getIndentSpace(indent));
-            if (strstr(cmt.string(), "@deprecated") != NULL) {
-                deprecated = true;
-            }
         } else if (sym.isPublic && !includePrivate) {
             sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
                 assets->getPackage().string(), className.string(),
                 String8(sym.name).string());
         }
-        if (deprecated) {
-            fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
-        }
+        ann.printAnnotations(fp, getIndentSpace(indent));
         fprintf(fp, "%spublic static final String %s=\"%s\";\n",
                 getIndentSpace(indent),
                 flattenSymbol(name8).string(), sym.stringVal.string());