1*9e94795aSAndroid Build Coastguard Workerpackage {package_name}; 2*9e94795aSAndroid Build Coastguard Worker{{ -if not is_test_mode }} 3*9e94795aSAndroid Build Coastguard Worker{{ -if allow_instrumentation }} 4*9e94795aSAndroid Build Coastguard Worker{{ if not library_exported- }}{#- only new storage for prod mode #} 5*9e94795aSAndroid Build Coastguard Worker// TODO(b/303773055): Remove the annotation after access issue is resolved. 6*9e94795aSAndroid Build Coastguard Workerimport android.compat.annotation.UnsupportedAppUsage; 7*9e94795aSAndroid Build Coastguard Worker{{ -if runtime_lookup_required }} 8*9e94795aSAndroid Build Coastguard Workerimport android.os.Build; 9*9e94795aSAndroid Build Coastguard Worker{{ if is_platform_container }} 10*9e94795aSAndroid Build Coastguard Workerimport android.os.flagging.PlatformAconfigPackageInternal; 11*9e94795aSAndroid Build Coastguard Worker{{ -else }} 12*9e94795aSAndroid Build Coastguard Workerimport android.os.flagging.AconfigPackageInternal; 13*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 14*9e94795aSAndroid Build Coastguard Workerimport android.util.Log; 15*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 16*9e94795aSAndroid Build Coastguard Worker/** @hide */ 17*9e94795aSAndroid Build Coastguard Workerpublic final class FeatureFlagsImpl implements FeatureFlags \{ 18*9e94795aSAndroid Build Coastguard Worker{{ -if runtime_lookup_required }} 19*9e94795aSAndroid Build Coastguard Worker private static final String TAG = "{package_name}.FeatureFlagsImpl"; 20*9e94795aSAndroid Build Coastguard Worker private static volatile boolean isCached = false; 21*9e94795aSAndroid Build Coastguard Worker{{ for flag in flag_elements }} 22*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 23*9e94795aSAndroid Build Coastguard Worker private static boolean {flag.method_name} = {flag.default_value}; 24*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 25*9e94795aSAndroid Build Coastguard Worker{{ -endfor }} 26*9e94795aSAndroid Build Coastguard Worker 27*9e94795aSAndroid Build Coastguard Worker private void init() \{ 28*9e94795aSAndroid Build Coastguard Worker try \{ 29*9e94795aSAndroid Build Coastguard Worker{{ if is_platform_container }} 30*9e94795aSAndroid Build Coastguard Worker PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint}); 31*9e94795aSAndroid Build Coastguard Worker{{ -else }} 32*9e94795aSAndroid Build Coastguard Worker AconfigPackageInternal reader = AconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint}); 33*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 34*9e94795aSAndroid Build Coastguard Worker {{ -for namespace_with_flags in namespace_flags }} 35*9e94795aSAndroid Build Coastguard Worker {{ -for flag in namespace_with_flags.flags }} 36*9e94795aSAndroid Build Coastguard Worker {{ -if flag.is_read_write }} 37*9e94795aSAndroid Build Coastguard Worker {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset}); 38*9e94795aSAndroid Build Coastguard Worker {{ -endif }} 39*9e94795aSAndroid Build Coastguard Worker {{ -endfor }} 40*9e94795aSAndroid Build Coastguard Worker {{ -endfor }} 41*9e94795aSAndroid Build Coastguard Worker } catch (Exception e) \{ 42*9e94795aSAndroid Build Coastguard Worker Log.e(TAG, e.toString()); 43*9e94795aSAndroid Build Coastguard Worker } catch (NoClassDefFoundError e) \{ 44*9e94795aSAndroid Build Coastguard Worker // for mainline module running on older devices. 45*9e94795aSAndroid Build Coastguard Worker // This should be replaces to version check, after the version bump. 46*9e94795aSAndroid Build Coastguard Worker Log.e(TAG, e.toString()); 47*9e94795aSAndroid Build Coastguard Worker } 48*9e94795aSAndroid Build Coastguard Worker isCached = true; 49*9e94795aSAndroid Build Coastguard Worker } 50*9e94795aSAndroid Build Coastguard Worker{{ -endif }}{#- end of runtime_lookup_required #} 51*9e94795aSAndroid Build Coastguard Worker{{ -for flag in flag_elements }} 52*9e94795aSAndroid Build Coastguard Worker @Override 53*9e94795aSAndroid Build Coastguard Worker @com.android.aconfig.annotations.AconfigFlagAccessor 54*9e94795aSAndroid Build Coastguard Worker @UnsupportedAppUsage 55*9e94795aSAndroid Build Coastguard Worker public boolean {flag.method_name}() \{ 56*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 57*9e94795aSAndroid Build Coastguard Worker if (!isCached) \{ 58*9e94795aSAndroid Build Coastguard Worker init(); 59*9e94795aSAndroid Build Coastguard Worker } 60*9e94795aSAndroid Build Coastguard Worker return {flag.method_name}; 61*9e94795aSAndroid Build Coastguard Worker{{ -else }} 62*9e94795aSAndroid Build Coastguard Worker return {flag.default_value}; 63*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 64*9e94795aSAndroid Build Coastguard Worker } 65*9e94795aSAndroid Build Coastguard Worker{{ endfor }} 66*9e94795aSAndroid Build Coastguard Worker} 67*9e94795aSAndroid Build Coastguard Worker{{ -else- }}{#- device config for exproted mode #} 68*9e94795aSAndroid Build Coastguard Workerimport android.os.Binder; 69*9e94795aSAndroid Build Coastguard Workerimport android.provider.DeviceConfig; 70*9e94795aSAndroid Build Coastguard Workerimport android.provider.DeviceConfig.Properties; 71*9e94795aSAndroid Build Coastguard Worker/** @hide */ 72*9e94795aSAndroid Build Coastguard Workerpublic final class FeatureFlagsImpl implements FeatureFlags \{ 73*9e94795aSAndroid Build Coastguard Worker{{ -for namespace_with_flags in namespace_flags }} 74*9e94795aSAndroid Build Coastguard Worker private static volatile boolean {namespace_with_flags.namespace}_is_cached = false; 75*9e94795aSAndroid Build Coastguard Worker{{ -endfor- }} 76*9e94795aSAndroid Build Coastguard Worker{{ for flag in flag_elements }} 77*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 78*9e94795aSAndroid Build Coastguard Worker private static boolean {flag.method_name} = {flag.default_value}; 79*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 80*9e94795aSAndroid Build Coastguard Worker{{ -endfor }} 81*9e94795aSAndroid Build Coastguard Worker{{ for namespace_with_flags in namespace_flags }} 82*9e94795aSAndroid Build Coastguard Worker private void load_overrides_{namespace_with_flags.namespace}() \{ 83*9e94795aSAndroid Build Coastguard Worker final long ident = Binder.clearCallingIdentity(); 84*9e94795aSAndroid Build Coastguard Worker try \{ 85*9e94795aSAndroid Build Coastguard Worker Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}"); 86*9e94795aSAndroid Build Coastguard Worker{{ -for flag in namespace_with_flags.flags }} 87*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 88*9e94795aSAndroid Build Coastguard Worker {flag.method_name} = 89*9e94795aSAndroid Build Coastguard Worker properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value}); 90*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 91*9e94795aSAndroid Build Coastguard Worker{{ -endfor }} 92*9e94795aSAndroid Build Coastguard Worker } catch (NullPointerException e) \{ 93*9e94795aSAndroid Build Coastguard Worker throw new RuntimeException( 94*9e94795aSAndroid Build Coastguard Worker "Cannot read value from namespace {namespace_with_flags.namespace} " 95*9e94795aSAndroid Build Coastguard Worker + "from DeviceConfig. It could be that the code using flag " 96*9e94795aSAndroid Build Coastguard Worker + "executed before SettingsProvider initialization. Please use " 97*9e94795aSAndroid Build Coastguard Worker + "fixed read-only flag by adding is_fixed_read_only: true in " 98*9e94795aSAndroid Build Coastguard Worker + "flag declaration.", 99*9e94795aSAndroid Build Coastguard Worker e 100*9e94795aSAndroid Build Coastguard Worker ); 101*9e94795aSAndroid Build Coastguard Worker } catch (SecurityException e) \{ 102*9e94795aSAndroid Build Coastguard Worker // for isolated process case, skip loading flag value from the storage, use the default 103*9e94795aSAndroid Build Coastguard Worker } finally \{ 104*9e94795aSAndroid Build Coastguard Worker Binder.restoreCallingIdentity(ident); 105*9e94795aSAndroid Build Coastguard Worker } 106*9e94795aSAndroid Build Coastguard Worker {namespace_with_flags.namespace}_is_cached = true; 107*9e94795aSAndroid Build Coastguard Worker } 108*9e94795aSAndroid Build Coastguard Worker{{ endfor- }} 109*9e94795aSAndroid Build Coastguard Worker{{ -for flag in flag_elements }} 110*9e94795aSAndroid Build Coastguard Worker @Override 111*9e94795aSAndroid Build Coastguard Worker public boolean {flag.method_name}() \{ 112*9e94795aSAndroid Build Coastguard Worker if (!{flag.device_config_namespace}_is_cached) \{ 113*9e94795aSAndroid Build Coastguard Worker load_overrides_{flag.device_config_namespace}(); 114*9e94795aSAndroid Build Coastguard Worker } 115*9e94795aSAndroid Build Coastguard Worker return {flag.method_name}; 116*9e94795aSAndroid Build Coastguard Worker } 117*9e94795aSAndroid Build Coastguard Worker{{ endfor }} 118*9e94795aSAndroid Build Coastguard Worker} 119*9e94795aSAndroid Build Coastguard Worker{{ -endif- }} {#- end exported mode #} 120*9e94795aSAndroid Build Coastguard Worker{{ else }} {#- else for allow_instrumentation is not enabled #} 121*9e94795aSAndroid Build Coastguard Worker{{ if not library_exported- }} 122*9e94795aSAndroid Build Coastguard Worker// TODO(b/303773055): Remove the annotation after access issue is resolved. 123*9e94795aSAndroid Build Coastguard Workerimport android.compat.annotation.UnsupportedAppUsage; 124*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 125*9e94795aSAndroid Build Coastguard Worker 126*9e94795aSAndroid Build Coastguard Worker{{ -if runtime_lookup_required }} 127*9e94795aSAndroid Build Coastguard Workerimport android.os.Binder; 128*9e94795aSAndroid Build Coastguard Workerimport android.provider.DeviceConfig; 129*9e94795aSAndroid Build Coastguard Workerimport android.provider.DeviceConfig.Properties; 130*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 131*9e94795aSAndroid Build Coastguard Worker/** @hide */ 132*9e94795aSAndroid Build Coastguard Workerpublic final class FeatureFlagsImpl implements FeatureFlags \{ 133*9e94795aSAndroid Build Coastguard Worker{{ -if runtime_lookup_required }} 134*9e94795aSAndroid Build Coastguard Worker{{ -for namespace_with_flags in namespace_flags }} 135*9e94795aSAndroid Build Coastguard Worker private static volatile boolean {namespace_with_flags.namespace}_is_cached = false; 136*9e94795aSAndroid Build Coastguard Worker{{ -endfor- }} 137*9e94795aSAndroid Build Coastguard Worker 138*9e94795aSAndroid Build Coastguard Worker{{ for flag in flag_elements }} 139*9e94795aSAndroid Build Coastguard Worker{{- if flag.is_read_write }} 140*9e94795aSAndroid Build Coastguard Worker private static boolean {flag.method_name} = {flag.default_value}; 141*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 142*9e94795aSAndroid Build Coastguard Worker{{ -endfor }} 143*9e94795aSAndroid Build Coastguard Worker{{ for namespace_with_flags in namespace_flags }} 144*9e94795aSAndroid Build Coastguard Worker private void load_overrides_{namespace_with_flags.namespace}() \{ 145*9e94795aSAndroid Build Coastguard Worker final long ident = Binder.clearCallingIdentity(); 146*9e94795aSAndroid Build Coastguard Worker try \{ 147*9e94795aSAndroid Build Coastguard Worker Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}"); 148*9e94795aSAndroid Build Coastguard Worker{{ -for flag in namespace_with_flags.flags }} 149*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 150*9e94795aSAndroid Build Coastguard Worker {flag.method_name} = 151*9e94795aSAndroid Build Coastguard Worker properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value}); 152*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 153*9e94795aSAndroid Build Coastguard Worker{{ -endfor }} 154*9e94795aSAndroid Build Coastguard Worker } catch (NullPointerException e) \{ 155*9e94795aSAndroid Build Coastguard Worker throw new RuntimeException( 156*9e94795aSAndroid Build Coastguard Worker "Cannot read value from namespace {namespace_with_flags.namespace} " 157*9e94795aSAndroid Build Coastguard Worker + "from DeviceConfig. It could be that the code using flag " 158*9e94795aSAndroid Build Coastguard Worker + "executed before SettingsProvider initialization. Please use " 159*9e94795aSAndroid Build Coastguard Worker + "fixed read-only flag by adding is_fixed_read_only: true in " 160*9e94795aSAndroid Build Coastguard Worker + "flag declaration.", 161*9e94795aSAndroid Build Coastguard Worker e 162*9e94795aSAndroid Build Coastguard Worker ); 163*9e94795aSAndroid Build Coastguard Worker } finally \{ 164*9e94795aSAndroid Build Coastguard Worker Binder.restoreCallingIdentity(ident); 165*9e94795aSAndroid Build Coastguard Worker } 166*9e94795aSAndroid Build Coastguard Worker {namespace_with_flags.namespace}_is_cached = true; 167*9e94795aSAndroid Build Coastguard Worker} 168*9e94795aSAndroid Build Coastguard Worker{{ endfor- }} 169*9e94795aSAndroid Build Coastguard Worker{{ -endif }}{#- end of runtime_lookup_required #} 170*9e94795aSAndroid Build Coastguard Worker{{ -for flag in flag_elements }} 171*9e94795aSAndroid Build Coastguard Worker @Override 172*9e94795aSAndroid Build Coastguard Worker{{ -if not library_exported }} 173*9e94795aSAndroid Build Coastguard Worker @com.android.aconfig.annotations.AconfigFlagAccessor 174*9e94795aSAndroid Build Coastguard Worker @UnsupportedAppUsage 175*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 176*9e94795aSAndroid Build Coastguard Worker public boolean {flag.method_name}() \{ 177*9e94795aSAndroid Build Coastguard Worker{{ -if flag.is_read_write }} 178*9e94795aSAndroid Build Coastguard Worker if (!{flag.device_config_namespace}_is_cached) \{ 179*9e94795aSAndroid Build Coastguard Worker load_overrides_{flag.device_config_namespace}(); 180*9e94795aSAndroid Build Coastguard Worker } 181*9e94795aSAndroid Build Coastguard Worker return {flag.method_name}; 182*9e94795aSAndroid Build Coastguard Worker{{ -else }} 183*9e94795aSAndroid Build Coastguard Worker return {flag.default_value}; 184*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 185*9e94795aSAndroid Build Coastguard Worker } 186*9e94795aSAndroid Build Coastguard Worker{{ endfor }} 187*9e94795aSAndroid Build Coastguard Worker} 188*9e94795aSAndroid Build Coastguard Worker{{ endif}} {#- endif for allow_instrumentation #} 189*9e94795aSAndroid Build Coastguard Worker{{ else }} {#- Generate only stub if in test mode #} 190*9e94795aSAndroid Build Coastguard Worker/** @hide */ 191*9e94795aSAndroid Build Coastguard Workerpublic final class FeatureFlagsImpl implements FeatureFlags \{ 192*9e94795aSAndroid Build Coastguard Worker{{ for flag in flag_elements }} 193*9e94795aSAndroid Build Coastguard Worker @Override 194*9e94795aSAndroid Build Coastguard Worker{{ -if not library_exported }} 195*9e94795aSAndroid Build Coastguard Worker @com.android.aconfig.annotations.AconfigFlagAccessor 196*9e94795aSAndroid Build Coastguard Worker{{ -endif }} 197*9e94795aSAndroid Build Coastguard Worker public boolean {flag.method_name}() \{ 198*9e94795aSAndroid Build Coastguard Worker throw new UnsupportedOperationException( 199*9e94795aSAndroid Build Coastguard Worker "Method is not implemented."); 200*9e94795aSAndroid Build Coastguard Worker } 201*9e94795aSAndroid Build Coastguard Worker{{ endfor- }} 202*9e94795aSAndroid Build Coastguard Worker} 203*9e94795aSAndroid Build Coastguard Worker{{ endif }} 204