Add is_exported field to aconfig.proto

When a flag is exported, it can be read by code built in other containers. By
default flags are not exported. Set this to true if your flag is gating
a public API which may be called from other containers (typically, a
flag used in @FlaggedAPI annotations).

Test: atest aconfig.test
Bug: 311152500
Change-Id: I53e3ed18b96c1518f04172d5933ef96b41ccda7e
diff --git a/tools/aconfig/protos/aconfig.proto b/tools/aconfig/protos/aconfig.proto
index d5e2868..9e193ec 100644
--- a/tools/aconfig/protos/aconfig.proto
+++ b/tools/aconfig/protos/aconfig.proto
@@ -40,6 +40,7 @@
   optional string description = 3;
   repeated string bug = 4;
   optional bool is_fixed_read_only = 5;
+  optional bool is_exported = 6;
 };
 
 message flag_declarations {
@@ -77,6 +78,8 @@
   optional flag_permission permission = 7;
   repeated tracepoint trace = 8;
   optional bool is_fixed_read_only = 9;
+  optional bool is_exported = 10;
+
 }
 
 message parsed_flags {
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index c8c7975..ff0df1f 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -98,6 +98,7 @@
             };
             parsed_flag.set_permission(flag_permission);
             parsed_flag.set_is_fixed_read_only(flag_declaration.is_fixed_read_only());
+            parsed_flag.set_is_exported(flag_declaration.is_exported());
             let mut tracepoint = ProtoTracepoint::new();
             tracepoint.set_source(input.source.clone());
             tracepoint.set_state(DEFAULT_FLAG_STATE);
diff --git a/tools/aconfig/src/protos.rs b/tools/aconfig/src/protos.rs
index d3b5b37..a5a5342 100644
--- a/tools/aconfig/src/protos.rs
+++ b/tools/aconfig/src/protos.rs
@@ -308,6 +308,7 @@
     namespace: "first_ns"
     description: "This is the description of the first flag."
     bug: "123"
+    is_exported: true
 }
 flag {
     name: "second"
@@ -326,12 +327,14 @@
         assert_eq!(first.description(), "This is the description of the first flag.");
         assert_eq!(first.bug, vec!["123"]);
         assert!(!first.is_fixed_read_only());
+        assert!(first.is_exported());
         let second = flag_declarations.flag.iter().find(|pf| pf.name() == "second").unwrap();
         assert_eq!(second.name(), "second");
         assert_eq!(second.namespace(), "second_ns");
         assert_eq!(second.description(), "This is the description of the second flag.");
         assert_eq!(second.bug, vec!["abc"]);
         assert!(second.is_fixed_read_only());
+        assert!(!second.is_exported());
 
         // bad input: missing package in flag declarations
         let error = flag_declarations::try_from_text_proto(
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index bb3d1f0..31c67b3 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -42,6 +42,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -57,6 +58,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: true
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -77,6 +79,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -97,6 +100,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: true
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -122,6 +126,7 @@
     permission: READ_ONLY
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 parsed_flag {
   package: "com.android.aconfig.test"
@@ -142,6 +147,7 @@
     permission: READ_WRITE
   }
   is_fixed_read_only: false
+  is_exported: false
 }
 "#;
 
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index 8527e93..b49b665 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -39,6 +39,7 @@
     namespace: "aconfig_test"
     description: "This flag is DISABLED + READ_WRITE"
     bug: "456"
+    is_exported: true
 }
 
 # This flag's final value calculated from: