Merge "aconfig: add single-exported-file parameter" into main
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 8588a72..6bd9416 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -33,6 +33,7 @@
pub allow_instrumentation: bool,
pub package_fingerprint: u64,
pub new_exported: bool,
+ pub single_exported_file: bool,
pub check_api_level: bool,
}
@@ -71,8 +72,15 @@
is_platform_container,
package_fingerprint: format!("0x{:X}L", config.package_fingerprint),
new_exported: config.new_exported,
+ single_exported_file: config.single_exported_file,
};
let mut template = TinyTemplate::new();
+ if library_exported && config.single_exported_file {
+ template.add_template(
+ "ExportedFlags.java",
+ include_str!("../../templates/ExportedFlags.java.template"),
+ )?;
+ }
template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
add_feature_flags_impl_template(&context, &mut template)?;
template.add_template(
@@ -89,18 +97,25 @@
)?;
let path: PathBuf = package.split('.').collect();
- [
+ let mut files = vec![
"Flags.java",
"FeatureFlags.java",
"FeatureFlagsImpl.java",
"CustomFeatureFlags.java",
"FakeFeatureFlagsImpl.java",
- ]
- .iter()
- .map(|file| {
- Ok(OutputFile { contents: template.render(file, &context)?.into(), path: path.join(file) })
- })
- .collect::<Result<Vec<OutputFile>>>()
+ ];
+ if library_exported && config.single_exported_file {
+ files.push("ExportedFlags.java");
+ }
+ files
+ .iter()
+ .map(|file| {
+ Ok(OutputFile {
+ contents: template.render(file, &context)?.into(),
+ path: path.join(file),
+ })
+ })
+ .collect::<Result<Vec<OutputFile>>>()
}
fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> {
@@ -138,6 +153,7 @@
pub is_platform_container: bool,
pub package_fingerprint: String,
pub new_exported: bool,
+ pub single_exported_file: bool,
}
#[derive(Serialize, Debug)]
@@ -259,7 +275,7 @@
(true, false, _) => {
template.add_template(
"FeatureFlagsImpl.java",
- include_str!("../../templates/FeatureFlagsImpl.java.template"),
+ include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
)?;
}
@@ -275,7 +291,7 @@
(false, _, false) => {
template.add_template(
"FeatureFlagsImpl.java",
- include_str!("../../templates/FeatureFlagsImpl.java.template"),
+ include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
)?;
}
};
@@ -592,6 +608,7 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
+ single_exported_file: false,
check_api_level: false,
};
let generated_files = generate_java_code(
@@ -752,6 +769,7 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
+ single_exported_file: false,
check_api_level: false,
};
let generated_files = generate_java_code(
@@ -956,6 +974,7 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: true,
+ single_exported_file: false,
check_api_level: false,
};
let generated_files = generate_java_code(
@@ -1022,7 +1041,7 @@
} catch (LinkageError e) {
// for mainline module running on older devices.
// This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
+ Log.w(TAG, e.toString());
}
isCached = true;
}
@@ -1150,6 +1169,7 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
+ single_exported_file: false,
check_api_level: false,
};
let generated_files = generate_java_code(
@@ -1277,6 +1297,7 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
+ single_exported_file: false,
check_api_level: false,
};
let generated_files = generate_java_code(
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index ab726aa..ea63c7a 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -219,6 +219,7 @@
codegen_mode: CodegenMode,
allow_instrumentation: bool,
new_exported: bool,
+ single_exported_file: bool,
check_api_level: bool,
) -> Result<Vec<OutputFile>> {
let parsed_flags = input.try_parse_flags()?;
@@ -237,6 +238,7 @@
allow_instrumentation,
package_fingerprint,
new_exported,
+ single_exported_file,
check_api_level,
};
generate_java_code(&package, modified_parsed_flags.into_iter(), config)
diff --git a/tools/aconfig/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs
index ef3b7ab..16b8272 100644
--- a/tools/aconfig/aconfig/src/main.rs
+++ b/tools/aconfig/aconfig/src/main.rs
@@ -158,11 +158,19 @@
.default_value("production"),
)
.arg(
+ Arg::new("single-exported-file")
+ .long("single-exported-file")
+ .value_parser(clap::value_parser!(bool))
+ .default_value("false"),
+ )
+ // TODO: b/395899938 - clean up flags for switching to new storage
+ .arg(
Arg::new("allow-instrumentation")
.long("allow-instrumentation")
.value_parser(clap::value_parser!(bool))
.default_value("false"),
)
+ // TODO: b/395899938 - clean up flags for switching to new storage
.arg(
Arg::new("new-exported")
.long("new-exported")
@@ -373,12 +381,15 @@
let allow_instrumentation =
get_required_arg::<bool>(sub_matches, "allow-instrumentation")?;
let new_exported = get_required_arg::<bool>(sub_matches, "new-exported")?;
+ let single_exported_file =
+ get_required_arg::<bool>(sub_matches, "single-exported-file")?;
let check_api_level = get_required_arg::<bool>(sub_matches, "check-api-level")?;
let generated_files = commands::create_java_lib(
cache,
*mode,
*allow_instrumentation,
*new_exported,
+ *single_exported_file,
*check_api_level,
)
.context("failed to create java lib")?;
diff --git a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
index b82b9cb..ef18367 100644
--- a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
@@ -11,7 +11,13 @@
import java.util.function.BiPredicate;
import java.util.function.Predicate;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public class CustomFeatureFlags implements FeatureFlags \{
private BiPredicate<String, Predicate<FeatureFlags>> mGetValueImpl;
diff --git a/tools/aconfig/aconfig/templates/ExportedFlags.java.template b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
new file mode 100644
index 0000000..4e36942
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
@@ -0,0 +1,49 @@
+package {package_name}; {#- CODEGEN FOR EXPORTED MODE FOR NEW STORAGE SINGLE EXPORTED FILE#}
+
+import android.os.Build;
+import android.os.flagging.AconfigPackage;
+import android.util.Log;
+public final class ExportedFlags \{
+{{ -for item in flag_elements}}
+ public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
+{{- endfor }}
+ private static final String TAG = "ExportedFlags";
+ private static volatile boolean isCached = false;
+{{ for flag in flag_elements }}
+ private static boolean {flag.method_name} = false;
+{{ -endfor }} {#- end flag_elements #}
+ private ExportedFlags() \{}
+
+ private void init() \{
+ try \{
+ AconfigPackage reader = AconfigPackage.load("{package_name}");
+ {{ -for namespace_with_flags in namespace_flags }}
+ {{ -for flag in namespace_with_flags.flags }}
+ {{ -if flag.finalized_sdk_present }}
+ {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+ {{ - else }} {#- else finalized_sdk_present #}
+ {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+ {{ -endif}} {#- end finalized_sdk_present#}
+ {{ -endfor }} {#- end namespace_with_flags.flags #}
+ {{ -endfor }} {#- end namespace_flags #}
+ } catch (Exception e) \{
+ // pass
+ Log.e(TAG, e.toString());
+ } catch (LinkageError e) \{
+ // for mainline module running on older devices.
+ // This should be replaces to version check, after the version bump.
+ Log.w(TAG, e.toString());
+ }
+ isCached = true;
+ }
+
+{{ -for flag in flag_elements }}
+ public static boolean {flag.method_name}() \{
+ if (!featureFlags.isCached) \{
+ featureFlags.init();
+ }
+ return featureFlags.{flag.method_name};
+ }
+{{ -endfor }}
+ private static ExportedFlags featureFlags = new ExportedFlags();
+}
diff --git a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
index 290d2c4..ed277ae 100644
--- a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
@@ -4,7 +4,13 @@
import java.util.Map;
import java.util.function.Predicate;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public class FakeFeatureFlagsImpl extends CustomFeatureFlags \{
private final Map<String, Boolean> mFlagMap = new HashMap<>();
private final FeatureFlags mDefaults;
diff --git a/tools/aconfig/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
index d2799b2..c8b9b7f 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
@@ -3,7 +3,16 @@
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
{{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public interface FeatureFlags \{
{{ for item in flag_elements }}
{{ -if not item.is_read_write }}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
new file mode 100644
index 0000000..44d5cc0
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
@@ -0,0 +1,68 @@
+package {package_name};
+{{ if not library_exported- }}
+// TODO(b/303773055): Remove the annotation after access issue is resolved.
+import android.compat.annotation.UnsupportedAppUsage;
+{{ -endif }} {#- end of not library_exported#}
+{{ -if runtime_lookup_required }}
+import android.os.Binder;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+{{ -endif }} {#- end of runtime_lookup_required#}
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ -if runtime_lookup_required }}
+{{ -for namespace_with_flags in namespace_flags }}
+ private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
+{{ -endfor- }}
+{{ for flag in flag_elements }}
+{{- if flag.is_read_write }}
+ private static boolean {flag.method_name} = {flag.default_value};
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+{{ for namespace_with_flags in namespace_flags }}
+ private void load_overrides_{namespace_with_flags.namespace}() \{
+ final long ident = Binder.clearCallingIdentity();
+ try \{
+ Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
+{{ -for flag in namespace_with_flags.flags }}
+{{ -if flag.is_read_write }}
+ {flag.method_name} =
+ properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+ } catch (NullPointerException e) \{
+ throw new RuntimeException(
+ "Cannot read value from namespace {namespace_with_flags.namespace} "
+ + "from DeviceConfig. It could be that the code using flag "
+ + "executed before SettingsProvider initialization. Please use "
+ + "fixed read-only flag by adding is_fixed_read_only: true in "
+ + "flag declaration.",
+ e
+ );
+ } catch (SecurityException e) \{
+ // for isolated process case, skip loading flag value from the storage, use the default
+ } finally \{
+ Binder.restoreCallingIdentity(ident);
+ }
+ {namespace_with_flags.namespace}_is_cached = true;
+}
+{{ endfor- }}
+{{ -endif }}{#- end of runtime_lookup_required #}
+{{ -for flag in flag_elements }}
+ @Override
+{{ -if not library_exported }}
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+{{ -endif }}{#- end of not library_exported #}
+ public boolean {flag.method_name}() \{
+{{ -if flag.is_read_write }}
+ if (!{flag.device_config_namespace}_is_cached) \{
+ load_overrides_{flag.device_config_namespace}();
+ }
+ return {flag.method_name};
+{{ -else }} {#- else is_read_write #}
+ return {flag.default_value};
+{{ -endif }}{#- end of is_read_write #}
+ }
+{{ endfor }}
+}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
index 8b60824..b843ec2 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
@@ -3,7 +3,16 @@
import android.os.Build;
import android.os.flagging.AconfigPackage;
import android.util.Log;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public final class FeatureFlagsImpl implements FeatureFlags \{
private static final String TAG = "FeatureFlagsImplExport";
private static volatile boolean isCached = false;
@@ -28,7 +37,7 @@
} catch (LinkageError e) \{
// for mainline module running on older devices.
// This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
+ Log.w(TAG, e.toString());
}
isCached = true;
}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
deleted file mode 100644
index ea2a2ee..0000000
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ /dev/null
@@ -1,248 +0,0 @@
-package {package_name};
-{{ -if not is_test_mode }}
-{{ -if allow_instrumentation }}
-{{ if not library_exported- }}{#- only new storage for prod mode #}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -if runtime_lookup_required }}
-import android.os.Build;
-{{ if is_platform_container }}
-import android.os.flagging.PlatformAconfigPackageInternal;
-{{ -else }} {#- else is_platform_container #}
-import android.os.flagging.AconfigPackageInternal;
-{{ -endif }} {#- end of is_platform_container#}
-import android.util.Log;
-{{ -endif }} {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
- private static final String TAG = "FeatureFlagsImpl";
- private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-
- private void init() \{
- try \{
-{{ if is_platform_container }}
- PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -else }} {#- else is_platform_container #}
- AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -endif }} {#- end of is_platform_container#}
- {{ -for namespace_with_flags in namespace_flags }}
- {{ -for flag in namespace_with_flags.flags }}
- {{ -if flag.is_read_write }}
- {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
- {{ -endif }} {#- is_read_write#}
- {{ -endfor }}
- {{ -endfor }}
- } catch (Exception e) \{
- Log.e(TAG, e.toString());
- } catch (LinkageError e) \{
- // for mainline module running on older devices.
- // This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
- }
- isCached = true;
- }
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
- if (!isCached) \{
- init();
- }
- return {flag.method_name};
-{{ -else }}{#- else is_read_write #}
- return {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
- }
-{{ endfor }}
-}
-{{ -else- }}{#- device config for exproted mode #}
-{{ -if new_exported }}
-import android.os.Build;
-import android.os.flagging.AconfigPackage;
-import android.util.Log;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
- private static final String TAG = "FeatureFlagsImplExport";
- private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
- private static boolean {flag.method_name} = false;
-{{ -endfor }}
- private void init() \{
- try \{
- AconfigPackage reader = AconfigPackage.load("{package_name}");
- {{ -for namespace_with_flags in namespace_flags }}
- {{ -for flag in namespace_with_flags.flags }}
- {{ -if flag.finalized_sdk_present }}
- {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
- {{ - else }} {#- else finalized_sdk_present #}
- {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
- {{ -endif}} {#- end of finalized_sdk_present#}
- {{ -endfor }}
- {{ -endfor }}
- } catch (Exception e) \{
- // pass
- Log.e(TAG, e.toString());
- } catch (LinkageError e) \{
- // for mainline module running on older devices.
- // This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
- }
- isCached = true;
- }
-{{ -for flag in flag_elements }}
- @Override
- public boolean {flag.method_name}() \{
- if (!isCached) \{
- init();
- }
- return {flag.method_name};
- }
-{{ endfor }}
-}
-{{ else }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -for namespace_with_flags in namespace_flags }}
- private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
- private void load_overrides_{namespace_with_flags.namespace}() \{
- final long ident = Binder.clearCallingIdentity();
- try \{
- Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
- {flag.method_name} =
- properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
- } catch (NullPointerException e) \{
- throw new RuntimeException(
- "Cannot read value from namespace {namespace_with_flags.namespace} "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- } catch (SecurityException e) \{
- // for isolated process case, skip loading flag value from the storage, use the default
- } finally \{
- Binder.restoreCallingIdentity(ident);
- }
- {namespace_with_flags.namespace}_is_cached = true;
- }
-{{ endfor- }}
-{{ -for flag in flag_elements }}
- @Override
- public boolean {flag.method_name}() \{
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
- }
- return {flag.method_name};
- }
-{{ endfor }}
-}
-{{ -endif- }} {#- end new_exported mode #}
-{{ -endif- }} {#- end exported mode #}
-{{ else }} {#- else for allow_instrumentation is not enabled #}
-{{ if not library_exported- }}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -endif }} {#- end of not library_exported#}
-
-{{ -if runtime_lookup_required }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-{{ -endif }} {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
-{{ -for namespace_with_flags in namespace_flags }}
- private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-
-{{ for flag in flag_elements }}
-{{- if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
- private void load_overrides_{namespace_with_flags.namespace}() \{
- final long ident = Binder.clearCallingIdentity();
- try \{
- Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
- {flag.method_name} =
- properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
- } catch (NullPointerException e) \{
- throw new RuntimeException(
- "Cannot read value from namespace {namespace_with_flags.namespace} "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- } finally \{
- Binder.restoreCallingIdentity(ident);
- }
- {namespace_with_flags.namespace}_is_cached = true;
-}
-{{ endfor- }}
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
- @Override
-{{ -if not library_exported }}
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
-{{ -endif }}{#- end of not library_exported #}
- public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
- }
- return {flag.method_name};
-{{ -else }} {#- else is_read_write #}
- return {flag.default_value};
-{{ -endif }}{#- end of is_read_write #}
- }
-{{ endfor }}
-}
-{{ endif}} {#- endif for allow_instrumentation #}
-{{ else }} {#- Generate only stub if in test mode #}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ for flag in flag_elements }}
- @Override
-{{ -if not library_exported }}
- @com.android.aconfig.annotations.AconfigFlagAccessor
-{{ -endif }}
- public boolean {flag.method_name}() \{
- throw new UnsupportedOperationException(
- "Method is not implemented.");
- }
-{{ endfor- }}
-}
-{{ endif }}
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index e2f70b9..8a92d33 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -3,7 +3,16 @@
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
{{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public final class Flags \{
{{ -for item in flag_elements}}
/** @hide */