Snap for 7196747 from a612d889239be8efb748a0dca9d36758f3894b82 to mainline-networkstack-release

Change-Id: I8f919424eb91dafcbd74df67e21522b92785f866
diff --git a/stats/stats_log_api_gen/java_writer.cpp b/stats/stats_log_api_gen/java_writer.cpp
index f4c937c..d971b56 100644
--- a/stats/stats_log_api_gen/java_writer.cpp
+++ b/stats/stats_log_api_gen/java_writer.cpp
@@ -97,7 +97,7 @@
 }
 
 static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
-                              const AtomDecl& attributionDecl, const bool supportQ) {
+                              const AtomDecl& attributionDecl, const int minApiLevel) {
     for (auto signatureInfoMapIt = signatureInfoMap.begin();
          signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
         // Print method signature.
@@ -123,7 +123,7 @@
 
         // Print method body.
         string indent("");
-        if (supportQ) {
+        if (minApiLevel == API_Q) {
             fprintf(out, "        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n");
             indent = "    ";
         }
@@ -256,7 +256,7 @@
         fprintf(out, "%s        StatsLog.write(builder.build());\n", indent.c_str());
 
         // Add support for writing using Q schema if this is not the default module.
-        if (supportQ) {
+        if (minApiLevel == API_Q) {
             fprintf(out, "        } else {\n");
             fprintf(out, "            QLogger.write(code");
             argIndex = 1;
@@ -286,7 +286,7 @@
 }
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
-                         const string& javaClass, const string& javaPackage, const bool supportQ,
+                         const string& javaClass, const string& javaPackage, const int minApiLevel,
                          const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
@@ -294,7 +294,7 @@
     fprintf(out, "package %s;\n", javaPackage.c_str());
     fprintf(out, "\n");
     fprintf(out, "\n");
-    if (supportQ) {
+    if (minApiLevel == API_Q) {
         fprintf(out, "import android.os.Build;\n");
         fprintf(out, "import android.os.SystemClock;\n");
     }
@@ -317,13 +317,13 @@
 
     // Print write methods.
     fprintf(out, "    // Write methods\n");
-    errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
+    errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, minApiLevel);
     errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
     if (supportWorkSource) {
         errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
     }
 
-    if (supportQ) {
+    if (minApiLevel == API_Q) {
         errors += write_java_q_logger_class(out, atoms.signatureInfoMap, attributionDecl);
     }
 
diff --git a/stats/stats_log_api_gen/java_writer.h b/stats/stats_log_api_gen/java_writer.h
index 8b3b505..ea3182c 100644
--- a/stats/stats_log_api_gen/java_writer.h
+++ b/stats/stats_log_api_gen/java_writer.h
@@ -31,7 +31,7 @@
 using namespace std;
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
-                         const string& javaClass, const string& javaPackage, const bool supportQ,
+                         const string& javaClass, const string& javaPackage, const int minApiLevel,
                          const bool supportWorkSource);
 
 }  // namespace stats_log_api_gen
diff --git a/stats/stats_log_api_gen/java_writer_q.cpp b/stats/stats_log_api_gen/java_writer_q.cpp
index d21e270..7ef622c 100644
--- a/stats/stats_log_api_gen/java_writer_q.cpp
+++ b/stats/stats_log_api_gen/java_writer_q.cpp
@@ -556,46 +556,5 @@
     }
 }
 
-// This method is called in main.cpp to generate StatsLog for modules that's
-// compatible with Q at compile-time.
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
-                                      const AtomDecl& attributionDecl, const string& javaClass,
-                                      const string& javaPackage, const bool supportWorkSource) {
-    // Print prelude
-    fprintf(out, "// This file is autogenerated\n");
-    fprintf(out, "\n");
-    fprintf(out, "package %s;\n", javaPackage.c_str());
-    fprintf(out, "\n");
-    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
-    fprintf(out, "\n");
-    fprintf(out, "import android.util.StatsLog;\n");
-    fprintf(out, "import android.os.SystemClock;\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "/**\n");
-    fprintf(out, " * Utility class for logging statistics events.\n");
-    fprintf(out, " */\n");
-    fprintf(out, "public class %s {\n", javaClass.c_str());
-
-    write_java_q_logging_constants(out, "    ");
-
-    write_java_atom_codes(out, atoms);
-
-    write_java_enum_values(out, atoms);
-
-    int errors = 0;
-    // Print write methods
-    fprintf(out, "    // Write methods\n");
-    errors += write_java_methods_q_schema(out, atoms.signatureInfoMap, attributionDecl, "    ");
-    errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
-    if (supportWorkSource) {
-        errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
-    }
-
-    fprintf(out, "}\n");
-
-    return errors;
-}
-
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/stats/stats_log_api_gen/java_writer_q.h b/stats/stats_log_api_gen/java_writer_q.h
index c511a84..f05cfbf 100644
--- a/stats/stats_log_api_gen/java_writer_q.h
+++ b/stats/stats_log_api_gen/java_writer_q.h
@@ -38,9 +38,5 @@
 void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl,
                                              const int requiredHelpers, const string& indent);
 
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
-                                      const AtomDecl& attributionDecl, const string& javaClass,
-                                      const string& javaPackage, const bool supportWorkSource);
-
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/stats/stats_log_api_gen/main.cpp b/stats/stats_log_api_gen/main.cpp
index 416dfdd..ca22140 100644
--- a/stats/stats_log_api_gen/main.cpp
+++ b/stats/stats_log_api_gen/main.cpp
@@ -45,15 +45,16 @@
     fprintf(stderr, "  --javaPackage PACKAGE             the package for the java file.\n");
     fprintf(stderr, "                                    required for java with module\n");
     fprintf(stderr, "  --javaClass CLASS    the class name of the java class.\n");
-    fprintf(stderr, "                       Optional for Java with module.\n");
-    fprintf(stderr, "                       Default is \"StatsLogInternal\"\n");
-    fprintf(stderr, "  --supportQ           Include runtime support for Android Q.\n");
+    fprintf(stderr, "  --minApiLevel API_LEVEL           lowest API level to support.\n");
+    fprintf(stderr, "                                    Default is \"current\".\n");
     fprintf(stderr,
             "  --worksource         Include support for logging WorkSource "
             "objects.\n");
     fprintf(stderr,
-            "  --compileQ           Include compile-time support for Android Q "
-            "(Java only).\n");
+            "  --compileApiLevel API_LEVEL           specify which API level generated code is "
+            "compiled against. (Java only).\n");
+    fprintf(stderr,
+            "                                        Default is \"current\".\n");
 }
 
 /**
@@ -69,9 +70,9 @@
     string moduleName = DEFAULT_MODULE_NAME;
     string cppNamespace = DEFAULT_CPP_NAMESPACE;
     string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
-    bool supportQ = false;
     bool supportWorkSource = false;
-    bool compileQ = false;
+    int minApiLevel = API_LEVEL_CURRENT;
+    int compileApiLevel = API_LEVEL_CURRENT;
 
     int index = 1;
     while (index < argc) {
@@ -135,11 +136,27 @@
             }
             javaClass = argv[index];
         } else if (0 == strcmp("--supportQ", argv[index])) {
-            supportQ = true;
+            minApiLevel = API_Q;
         } else if (0 == strcmp("--worksource", argv[index])) {
             supportWorkSource = true;
-        } else if (0 == strcmp("--compileQ", argv[index])) {
-            compileQ = true;
+        } else if (0 == strcmp("--minApiLevel", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            if (0 != strcmp("current", argv[index])) {
+                minApiLevel = atoi(argv[index]);
+            }
+        } else if (0 == strcmp("--compileApiLevel", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            if (0 != strcmp("current", argv[index])) {
+                compileApiLevel = atoi(argv[index]);
+            }
         }
 
         index++;
@@ -149,17 +166,36 @@
         print_usage();
         return 1;
     }
-
-    if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) {
-        // Support for Q schema is not needed for default module.
-        fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
+    if (DEFAULT_MODULE_NAME == moduleName &&
+            (minApiLevel != API_LEVEL_CURRENT || compileApiLevel != API_LEVEL_CURRENT)) {
+        // Default module only supports current API level.
+        fprintf(stderr, "%s cannot support older API levels\n", moduleName.c_str());
         return 1;
     }
 
-    if (supportQ && compileQ) {
-        // Runtime Q support is redundant if compile-time Q support is required.
-        fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n");
-        return 1;
+    if (compileApiLevel < API_R) {
+        // Cannot compile against pre-R.
+        fprintf(stderr, "compileApiLevel must be %d or higher.\n", API_R);
+    }
+
+    if (minApiLevel < API_Q) {
+        // Cannot support pre-Q.
+        fprintf(stderr, "minApiLevel must be %d or higher.\n", API_Q);
+    }
+
+    if (minApiLevel == API_LEVEL_CURRENT) {
+        if (minApiLevel > compileApiLevel) {
+            // If minApiLevel is not specified, assume it is not higher than compileApiLevel.
+            minApiLevel = compileApiLevel;
+        }
+    } else {
+        if (minApiLevel > compileApiLevel) {
+            // If specified, minApiLevel should always be lower than compileApiLevel.
+            fprintf(stderr, "Invalid minApiLevel or compileApiLevel. If minApiLevel and"
+                    " compileApiLevel are specified, minApiLevel should not be higher"
+                    " than compileApiLevel.\n");
+            return 1;
+        }
     }
 
     // Collate the parameters
@@ -193,7 +229,7 @@
             return 1;
         }
         errorCount = android::stats_log_api_gen::write_stats_log_cpp(
-                out, atoms, attributionDecl, cppNamespace, cppHeaderImport, supportQ);
+                out, atoms, attributionDecl, cppNamespace, cppHeaderImport, minApiLevel);
         fclose(out);
     }
 
@@ -236,14 +272,9 @@
             return 1;
         }
 
-        if (compileQ) {
-            errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
-                    out, atoms, attributionDecl, javaClass, javaPackage, supportWorkSource);
-        } else {
-            errorCount = android::stats_log_api_gen::write_stats_log_java(
-                    out, atoms, attributionDecl, javaClass, javaPackage, supportQ,
-                    supportWorkSource);
-        }
+        errorCount = android::stats_log_api_gen::write_stats_log_java(
+                out, atoms, attributionDecl, javaClass, javaPackage, minApiLevel,
+                supportWorkSource);
 
         fclose(out);
     }
diff --git a/stats/stats_log_api_gen/native_writer.cpp b/stats/stats_log_api_gen/native_writer.cpp
index 0c6c009..c4ee75d 100644
--- a/stats/stats_log_api_gen/native_writer.cpp
+++ b/stats/stats_log_api_gen/native_writer.cpp
@@ -83,7 +83,8 @@
 }
 
 static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
-                                            const AtomDecl& attributionDecl, const bool supportQ) {
+                                            const AtomDecl& attributionDecl,
+                                            const int minApiLevel) {
     fprintf(out, "\n");
     for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin();
          signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) {
@@ -96,7 +97,7 @@
         write_native_method_signature(out, "int stats_write", signature, attributionDecl, " {");
 
         int argIndex = 1;
-        if (supportQ) {
+        if (minApiLevel == API_Q) {
             fprintf(out, "    StatsEventCompat event;\n");
             fprintf(out, "    event.setAtomId(code);\n");
             write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", "");
@@ -252,13 +253,13 @@
 
 int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
                         const string& cppNamespace, const string& importHeader,
-                        const bool supportQ) {
+                        const int minApiLevel) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
 
     fprintf(out, "#include <%s>\n", importHeader.c_str());
-    if (supportQ) {
+    if (minApiLevel == API_Q) {
         fprintf(out, "#include <StatsEventCompat.h>\n");
     } else {
         fprintf(out, "#include <stats_event.h>\n");
@@ -267,7 +268,7 @@
     fprintf(out, "\n");
     write_namespace(out, cppNamespace);
 
-    write_native_stats_write_methods(out, atoms, attributionDecl, supportQ);
+    write_native_stats_write_methods(out, atoms, attributionDecl, minApiLevel);
     write_native_stats_write_non_chained_methods(out, atoms, attributionDecl);
 
     // Print footer
diff --git a/stats/stats_log_api_gen/native_writer.h b/stats/stats_log_api_gen/native_writer.h
index 264d4db..0264703 100644
--- a/stats/stats_log_api_gen/native_writer.h
+++ b/stats/stats_log_api_gen/native_writer.h
@@ -28,7 +28,7 @@
 
 int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
                         const string& cppNamespace, const string& importHeader,
-                        const bool supportQ);
+                        const int minApiLevel);
 
 int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
                            const string& cppNamespace);
diff --git a/stats/stats_log_api_gen/utils.h b/stats/stats_log_api_gen/utils.h
index 73e0cb8..13228b5 100644
--- a/stats/stats_log_api_gen/utils.h
+++ b/stats/stats_log_api_gen/utils.h
@@ -33,6 +33,10 @@
 const string DEFAULT_CPP_NAMESPACE = "android,util";
 const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
 
+const int API_LEVEL_CURRENT = 10000;
+const int API_Q = 29;
+const int API_R = 30;
+
 const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
 const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
 const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04;