Distinguish # apex and # systemapi symbols

Previously, the symbol tag `# apex` was treated the same as `#
systemapi`. With this CL, they have different meanings.

`# systemapi`: APIs that are defined in the platform (the non-updatable
part), and are exposed to unbundled system components like APEX

`# apex`: APIs that are defined in the APEX and are exposed to the
platform or other APEXes

Bug: 239274367
Test: m
Change-Id: I0484ea349656dbbd337e5fe3a5970f0ad275b807
diff --git a/apex/apex_test.go b/apex/apex_test.go
index dbe9180..6abd8ff 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -949,8 +949,10 @@
 	// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
 	// ensureNotContains(t, mylib2Cflags, "-include ")
 
-	// Ensure that genstub is invoked with --apex
-	ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
+	// Ensure that genstub for platform-provided lib is invoked with --systemapi
+	ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+	// Ensure that genstub for apex-provided lib is invoked with --apex
+	ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
 
 	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
 		"lib64/mylib.so",
@@ -1134,8 +1136,8 @@
 	mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
 	ensureNotContains(t, mylib2Cflags, "-include ")
 
-	// Ensure that genstub is invoked with --apex
-	ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"])
+	// Ensure that genstub is invoked with --systemapi
+	ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
 
 	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
 		"lib64/mylib.so",
diff --git a/cc/library.go b/cc/library.go
index c445a42..e2d5ef6 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1032,9 +1032,19 @@
 			ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
 			return Objects{}
 		}
+		// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+		// systemapi, respectively. The former is for symbols defined in platform libraries
+		// and the latter is for symbols defined in APEXes.
+		var flag string
+		if ctx.Module().(android.ApexModule).NotInPlatform() {
+			flag = "--apex"
+		} else {
+			// TODO(b/239274367) drop --apex when #apex is replaced with #systemapi
+			// in the map.txt files of platform libraries
+			flag = "--systemapi --apex"
+		}
 		nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
-			android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion),
-			"--apex")
+			android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
 		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
 		library.versionScriptPath = android.OptionalPathForPath(
 			nativeAbiResult.versionScript)
diff --git a/cc/ndk_api_coverage_parser/__init__.py b/cc/ndk_api_coverage_parser/__init__.py
index 084736f..752f7d4 100755
--- a/cc/ndk_api_coverage_parser/__init__.py
+++ b/cc/ndk_api_coverage_parser/__init__.py
@@ -140,7 +140,7 @@
 
     with open(args.symbol_file) as symbol_file:
         try:
-            filt = Filter("", FUTURE_API_LEVEL, True, True)
+            filt = Filter("", FUTURE_API_LEVEL, True, True, True)
             versions = SymbolFileParser(symbol_file, api_map, filt).parse()
         except MultiplyDefinedSymbolError as ex:
             sys.exit('{}: error: {}'.format(args.symbol_file, ex))
diff --git a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
index 14aa198..7c6ef68 100644
--- a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
+++ b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
@@ -78,7 +78,7 @@
         """
             )
         )
-        filt = Filter("", FUTURE_API_LEVEL, True, True)
+        filt = Filter("", FUTURE_API_LEVEL, True, True, True)
         parser = SymbolFileParser(input_file, {}, filt)
         generator = nparser.XmlGenerator(io.StringIO())
         result = generator.convertToXml(parser.parse())
diff --git a/cc/ndkstubgen/__init__.py b/cc/ndkstubgen/__init__.py
index 2c9937c..f893d41 100755
--- a/cc/ndkstubgen/__init__.py
+++ b/cc/ndkstubgen/__init__.py
@@ -105,12 +105,12 @@
     parser.add_argument(
         '--apex',
         action='store_true',
-        help='Use the APEX variant. Note: equivalent to --system-api.')
+        help='Use the APEX variant.')
     parser.add_argument(
-        '--system-api',
+        '--systemapi',
         action='store_true',
-        dest='apex',
-        help='Use the SystemAPI variant. Note: equivalent to --apex.')
+        dest='systemapi',
+        help='Use the SystemAPI variant.')
 
     parser.add_argument('--api-map',
                         type=resolved_path,
@@ -147,7 +147,7 @@
         verbosity = 2
     logging.basicConfig(level=verbose_map[verbosity])
 
-    filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex)
+    filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi)
     with args.symbol_file.open() as symbol_file:
         try:
           versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index c5147d1..471a12f 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -78,12 +78,17 @@
     @property
     def has_mode_tags(self) -> bool:
         """Returns True if any mode tags (apex, llndk, etc) are set."""
-        return self.has_apex_tags or self.has_llndk_tags
+        return self.has_apex_tags or self.has_llndk_tags or self.has_systemapi_tags
 
     @property
     def has_apex_tags(self) -> bool:
         """Returns True if any APEX tags are set."""
-        return 'apex' in self.tags or 'systemapi' in self.tags
+        return 'apex' in self.tags
+
+    @property
+    def has_systemapi_tags(self) -> bool:
+        """Returns True if any APEX tags are set."""
+        return 'systemapi' in self.tags
 
     @property
     def has_llndk_tags(self) -> bool:
@@ -203,11 +208,12 @@
     symbol should be omitted or not
     """
 
-    def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False):
+    def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi: bool = False):
         self.arch = arch
         self.api = api
         self.llndk = llndk
         self.apex = apex
+        self.systemapi = systemapi
 
     def _should_omit_tags(self, tags: Tags) -> bool:
         """Returns True if the tagged object should be omitted.
@@ -219,12 +225,13 @@
         # default behavior because all NDK symbols are implicitly available to
         # APEX and LLNDK.
         if tags.has_mode_tags:
-            if not self.apex and not self.llndk:
-                return True
-            if self.apex and not tags.has_apex_tags:
-                return True
-            if self.llndk and not tags.has_llndk_tags:
-                return True
+            if self.apex and tags.has_apex_tags:
+                return False
+            if self.llndk and tags.has_llndk_tags:
+                return False
+            if self.systemapi and tags.has_systemapi_tags:
+                return False
+            return True
         if not symbol_in_arch(tags, self.arch):
             return True
         if not symbol_in_api(tags, self.arch, self.api):
diff --git a/cc/symbolfile/test_symbolfile.py b/cc/symbolfile/test_symbolfile.py
index 0060a74..e17a8d0 100644
--- a/cc/symbolfile/test_symbolfile.py
+++ b/cc/symbolfile/test_symbolfile.py
@@ -246,24 +246,30 @@
         v = self.version
         v_apex = copy(v)
         v_apex.tags = Tags.from_strs(['apex'])
+        v_systemapi = copy(v)
+        v_systemapi.tags = Tags.from_strs(['systemapi'])
 
         self.assertOmit(f, v_apex)
 
         f.apex = True
         self.assertInclude(f, v)
         self.assertInclude(f, v_apex)
+        self.assertOmit(f, v_systemapi)
 
     def test_omit_systemapi(self) -> None:
         f = self.filter
         v = self.version
+        v_apex = copy(v)
+        v_apex.tags = Tags.from_strs(['apex'])
         v_systemapi = copy(v)
         v_systemapi.tags = Tags.from_strs(['systemapi'])
 
         self.assertOmit(f, v_systemapi)
 
-        f.apex = True
+        f.systemapi = True
         self.assertInclude(f, v)
         self.assertInclude(f, v_systemapi)
+        self.assertOmit(f, v_apex)
 
     def test_omit_arch(self) -> None:
         f_arm = self.filter
@@ -321,22 +327,38 @@
 
         s_none = Symbol('foo', Tags())
         s_apex = Symbol('foo', Tags.from_strs(['apex']))
+        s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
 
         self.assertOmit(f_none, s_apex)
         self.assertInclude(f_apex, s_none)
         self.assertInclude(f_apex, s_apex)
+        self.assertOmit(f_apex, s_systemapi)
 
     def test_omit_systemapi(self) -> None:
         f_none = self.filter
         f_systemapi = copy(f_none)
-        f_systemapi.apex = True
+        f_systemapi.systemapi = True
 
         s_none = Symbol('foo', Tags())
+        s_apex = Symbol('foo', Tags.from_strs(['apex']))
         s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
 
         self.assertOmit(f_none, s_systemapi)
         self.assertInclude(f_systemapi, s_none)
         self.assertInclude(f_systemapi, s_systemapi)
+        self.assertOmit(f_systemapi, s_apex)
+
+    def test_omit_apex_and_systemapi(self) -> None:
+        f = self.filter
+        f.systemapi = True
+        f.apex = True
+
+        s_none = Symbol('foo', Tags())
+        s_apex = Symbol('foo', Tags.from_strs(['apex']))
+        s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
+        self.assertInclude(f, s_none)
+        self.assertInclude(f, s_apex)
+        self.assertInclude(f, s_systemapi)
 
     def test_omit_arch(self) -> None:
         f_arm = self.filter