/* * Copyright 2014-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.android; import com.facebook.buck.model.UnflavoredBuildTarget; import com.facebook.buck.rules.coercer.BuildConfigFields; import com.google.common.collect.ImmutableList; /** Utilities for generating a {@code BuildConfig.java} file for Android. */ public class BuildConfigs { /** * Name of the boolean global variable provided by the standard Android tools to indicate whether * an app was built in debug mode or not. */ public static final String DEBUG_CONSTANT = "DEBUG"; /** * Name of a Buck-specific global variable that indicates whether an app was built using * exopackage. */ public static final String IS_EXO_CONSTANT = "IS_EXOPACKAGE"; /** Name of a global variable that includes the exopackage configuration as a bitmask. */ public static final String EXOPACKAGE_FLAGS = "EXOPACKAGE_FLAGS"; /** @see #getDefaultBuildConfigFields() */ private static final BuildConfigFields DEFAULT_BUILD_CONFIG_CONSTANTS = BuildConfigFields.fromFields( ImmutableList.of( // DEBUG is expected by the standard Android tools. BuildConfigFields.Field.of("boolean", DEBUG_CONSTANT, "true"), // IS_EXOPACKAGE is a value we use internally for checking whether exopackage is being // used. BuildConfigFields.Field.of("boolean", IS_EXO_CONSTANT, "false"), BuildConfigFields.Field.of("int", EXOPACKAGE_FLAGS, "0"))); /** Utility class: do not instantiate. */ private BuildConfigs() {} /** * Returns a list of fields (with values) that every {@code BuildConfig.java} should declare. The * default value of each constant may be overridden by the {@code userFields} passed to {@link * #generateBuildConfigDotJava(UnflavoredBuildTarget, String, boolean, BuildConfigFields)} when * generating a {@code BuildConfig.java}. */ public static BuildConfigFields getDefaultBuildConfigFields() { return DEFAULT_BUILD_CONFIG_CONSTANTS; } /** * Generates the source code for an Android {@code BuildConfig.java} file with the default set of * fields specified by {@link #getDefaultBuildConfigFields()}. */ public static String generateBuildConfigDotJava( UnflavoredBuildTarget source, String javaPackage) { return generateBuildConfigDotJava( source, javaPackage, /* useConstantExpressions */ false, BuildConfigFields.empty()); } /** * Generates the source code for an Android {@code BuildConfig.java} file with fields specified by * {@code userFields}. * * <p>The output will also contain a constant for every entry in the collection returned by {@link * #getDefaultBuildConfigFields()}. * * <p>If the name of a field in {@code userFields} matches one in the collection returned by * {@link #getDefaultBuildConfigFields()}, the value in the {@code userFields} map will be used. * * @param javaPackage The package for the Java class generated by this method. * @param useConstantExpressions If {@code true}, the value for each static final field in the * generated class will be declared as the literal value in {@code userFields}. The values of * such fields can be inlined by {@code javac}. * <p>If {@code false}, the value for each static final field in the generated class will be * declared as a non-constant expression that is guaranteed to evaluate to the same value in * {@code userFields}. This ensures that the generated {@code BuildConfig.java} can still be * used in Robolectric tests, but does not run the risk of its values being inlined by {@code * javac}. This is important if the generated {@code BuildConfig} class is going to be swapped * out by a different implementation by {@link AndroidBinary}. See {@link AndroidBuildConfig} * for details. * @param userFields represents the fields that should be declared in the generated {@code * BuildConfig} class. */ public static String generateBuildConfigDotJava( UnflavoredBuildTarget source, String javaPackage, boolean useConstantExpressions, BuildConfigFields userFields) { BuildConfigFields totalFields = getDefaultBuildConfigFields().putAll(userFields); return totalFields.generateBuildConfigDotJava(source, javaPackage, useConstantExpressions); } }