/*
*
*
*
* Apache License
* Version 2.0, January 2004
* http://www.apache.org/licenses/
*
* TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
*
* 1. Definitions.
*
* "License" shall mean the terms and conditions for use, reproduction,
* and distribution as defined by Sections 1 through 9 of this document.
*
* "Licensor" shall mean the copyright owner or entity authorized by
* the copyright owner that is granting the License.
*
* "Legal Entity" shall mean the union of the acting entity and all
* other entities that control, are controlled by, or are under common
* control with that entity. For the purposes of this definition,
* "control" means (i) the power, direct or indirect, to cause the
* direction or management of such entity, whether by contract or
* otherwise, or (ii) ownership of fifty percent (50%) or more of the
* outstanding shares, or (iii) beneficial ownership of such entity.
*
* "You" (or "Your") shall mean an individual or Legal Entity
* exercising permissions granted by this License.
*
* "Source" form shall mean the preferred form for making modifications,
* including but not limited to software source code, documentation
* source, and configuration files.
*
* "Object" form shall mean any form resulting from mechanical
* transformation or translation of a Source form, including but
* not limited to compiled object code, generated documentation,
* and conversions to other media types.
*
* "Work" shall mean the work of authorship, whether in Source or
* Object form, made available under the License, as indicated by a
* copyright notice that is included in or attached to the work
* (an example is provided in the Appendix below).
*
* "Derivative Works" shall mean any work, whether in Source or Object
* form, that is based on (or derived from) the Work and for which the
* editorial revisions, annotations, elaborations, or other modifications
* represent, as a whole, an original work of authorship. For the purposes
* of this License, Derivative Works shall not include works that remain
* separable from, or merely link (or bind by name) to the interfaces of,
* the Work and Derivative Works thereof.
*
* "Contribution" shall mean any work of authorship, including
* the original version of the Work and any modifications or additions
* to that Work or Derivative Works thereof, that is intentionally
* submitted to Licensor for inclusion in the Work by the copyright owner
* or by an individual or Legal Entity authorized to submit on behalf of
* the copyright owner. For the purposes of this definition, "submitted"
* means any form of electronic, verbal, or written communication sent
* to the Licensor or its representatives, including but not limited to
* communication on electronic mailing lists, source code control systems,
* and issue tracking systems that are managed by, or on behalf of, the
* Licensor for the purpose of discussing and improving the Work, but
* excluding communication that is conspicuously marked or otherwise
* designated in writing by the copyright owner as "Not a Contribution."
*
* "Contributor" shall mean Licensor and any individual or Legal Entity
* on behalf of whom a Contribution has been received by Licensor and
* subsequently incorporated within the Work.
*
* 2. Grant of Copyright License. Subject to the terms and conditions of
* this License, each Contributor hereby grants to You a perpetual,
* worldwide, non-exclusive, no-charge, royalty-free, irrevocable
* copyright license to reproduce, prepare Derivative Works of,
* publicly display, publicly perform, sublicense, and distribute the
* Work and such Derivative Works in Source or Object form.
*
* 3. Grant of Patent License. Subject to the terms and conditions of
* this License, each Contributor hereby grants to You a perpetual,
* worldwide, non-exclusive, no-charge, royalty-free, irrevocable
* (except as stated in this section) patent license to make, have made,
* use, offer to sell, sell, import, and otherwise transfer the Work,
* where such license applies only to those patent claims licensable
* by such Contributor that are necessarily infringed by their
* Contribution(s) alone or by combination of their Contribution(s)
* with the Work to which such Contribution(s) was submitted. If You
* institute patent litigation against any entity (including a
* cross-claim or counterclaim in a lawsuit) alleging that the Work
* or a Contribution incorporated within the Work constitutes direct
* or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate
* as of the date such litigation is filed.
*
* 4. Redistribution. You may reproduce and distribute copies of the
* Work or Derivative Works thereof in any medium, with or without
* modifications, and in Source or Object form, provided that You
* meet the following conditions:
*
* (a) You must give any other recipients of the Work or
* Derivative Works a copy of this License; and
*
* (b) You must cause any modified files to carry prominent notices
* stating that You changed the files; and
*
* (c) You must retain, in the Source form of any Derivative Works
* that You distribute, all copyright, patent, trademark, and
* attribution notices from the Source form of the Work,
* excluding those notices that do not pertain to any part of
* the Derivative Works; and
*
* (d) If the Work includes a "NOTICE" text file as part of its
* distribution, then any Derivative Works that You distribute must
* include a readable copy of the attribution notices contained
* within such NOTICE file, excluding those notices that do not
* pertain to any part of the Derivative Works, in at least one
* of the following places: within a NOTICE text file distributed
* as part of the Derivative Works; within the Source form or
* documentation, if provided along with the Derivative Works; or,
* within a display generated by the Derivative Works, if and
* wherever such third-party notices normally appear. The contents
* of the NOTICE file are for informational purposes only and
* do not modify the License. You may add Your own attribution
* notices within Derivative Works that You distribute, alongside
* or as an addendum to the NOTICE text from the Work, provided
* that such additional attribution notices cannot be construed
* as modifying the License.
*
* You may add Your own copyright statement to Your modifications and
* may provide additional or different license terms and conditions
* for use, reproduction, or distribution of Your modifications, or
* for any such Derivative Works as a whole, provided Your use,
* reproduction, and distribution of the Work otherwise complies with
* the conditions stated in this License.
*
* 5. Submission of Contributions. Unless You explicitly state otherwise,
* any Contribution intentionally submitted for inclusion in the Work
* by You to the Licensor shall be under the terms and conditions of
* this License, without any additional terms or conditions.
* Notwithstanding the above, nothing herein shall supersede or modify
* the terms of any separate license agreement you may have executed
* with Licensor regarding such Contributions.
*
* 6. Trademarks. This License does not grant permission to use the trade
* names, trademarks, service marks, or product names of the Licensor,
* except as required for reasonable and customary use in describing the
* origin of the Work and reproducing the content of the NOTICE file.
*
* 7. Disclaimer of Warranty. Unless required by applicable law or
* agreed to in writing, Licensor provides the Work (and each
* Contributor provides its Contributions) on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied, including, without limitation, any warranties or conditions
* of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
* PARTICULAR PURPOSE. You are solely responsible for determining the
* appropriateness of using or redistributing the Work and assume any
* risks associated with Your exercise of permissions under this License.
*
* 8. Limitation of Liability. In no event and under no legal theory,
* whether in tort (including negligence), contract, or otherwise,
* unless required by applicable law (such as deliberate and grossly
* negligent acts) or agreed to in writing, shall any Contributor be
* liable to You for damages, including any direct, indirect, special,
* incidental, or consequential damages of any character arising as a
* result of this License or out of the use or inability to use the
* Work (including but not limited to damages for loss of goodwill,
* work stoppage, computer failure or malfunction, or any and all
* other commercial damages or losses), even if such Contributor
* has been advised of the possibility of such damages.
*
* 9. Accepting Warranty or Additional Liability. While redistributing
* the Work or Derivative Works thereof, You may choose to offer,
* and charge a fee for, acceptance of support, warranty, indemnity,
* or other liability obligations and/or rights consistent with this
* License. However, in accepting such obligations, You may act only
* on Your own behalf and on Your sole responsibility, not on behalf
* of any other Contributor, and only if You agree to indemnify,
* defend, and hold each Contributor harmless for any liability
* incurred by, or claims asserted against, such Contributor by reason
* of your accepting any such warranty or additional liability.
*
* END OF TERMS AND CONDITIONS
*
* APPENDIX: How to apply the Apache License to your work.
*
* To apply the Apache License to your work, attach the following
* boilerplate notice, with the fields enclosed by brackets "[]"
* replaced with your own identifying information. (Don't include
* the brackets!) The text should be enclosed in the appropriate
* comment syntax for the file format. We also recommend that a
* file or class name and description of purpose be included on the
* same "printed page" as the copyright notice for easier
* identification within third-party archives.
*
* Copyright 2016 Alibaba Group
*
* 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.taobao.android.builder.tasks.app.bundle;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.AndroidGradleOptions;
import com.android.build.gradle.internal.api.AppVariantOutputContext;
import com.android.build.gradle.internal.core.GradleVariantConfiguration;
import com.android.build.gradle.internal.dsl.AaptOptions;
import com.android.build.gradle.internal.dsl.DataBindingOptions;
import com.android.build.gradle.internal.incremental.FileType;
import com.android.build.gradle.internal.incremental.InstantRunBuildContext;
import com.android.build.gradle.internal.scope.ConventionMappingHelper;
import com.android.build.gradle.internal.scope.TaskConfigAction;
import com.android.build.gradle.internal.scope.VariantOutputScope;
import com.android.build.gradle.internal.tasks.IncrementalTask;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.android.build.gradle.internal.variant.SplitHandlingPolicy;
import com.android.builder.core.AaptPackageProcessBuilder;
import com.android.builder.core.AtlasBuilder;
import com.android.builder.core.VariantType;
import com.android.builder.model.AndroidLibrary;
import com.android.ide.common.process.LoggedProcessOutputHandler;
import com.android.ide.common.process.ProcessOutputHandler;
import com.google.common.base.Charsets;
import com.google.common.collect.Iterators;
import com.google.common.io.Files;
import com.taobao.android.builder.AtlasBuildContext;
import com.taobao.android.builder.dependency.model.AwbBundle;
import com.taobao.android.builder.tools.manifest.ManifestFileUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.gradle.api.GradleException;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.ParallelizableTask;
import org.gradle.api.tasks.StopExecutionException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
@ParallelizableTask
public class ProcessAwbAndroidResources extends IncrementalTask {
private File manifestFile;
private File instantRunManifestFile;
private File resDir;
private File assetsDir;
private File sourceOutputDir;
private File textSymbolOutputDir;
private File packageOutputFile;
private File proguardOutputFile;
private Collection<String> resourceConfigs;
private String preferredDensity;
private List<? extends AndroidLibrary> libraries;
private String packageForR;
private Collection<String> splits;
private boolean enforceUniquePackageName;
private VariantType type;
private boolean debuggable;
private boolean pseudoLocalesEnabled;
private AaptOptions aaptOptions;
private File mergeBlameLogFolder;
private InstantRunBuildContext instantRunBuildContext;
private File instantRunSupportDir;
private File buildInfoFile;
private File mainSymbolFile;
private String awbBundleName;
private String customPackageId;
private String sktPackageName;
private File shareResourceFile;
private File rtxtFile;
private File baselineFile;
@Override
protected void doFullTaskAction() throws IOException {
// we have to clean the source folder output in case the package name changed.
File srcOut = getSourceOutputDir();
if (srcOut != null) {
// FileUtils.emptyFolder(srcOut);
srcOut.delete();
srcOut.mkdirs();
}
getTextSymbolOutputDir().mkdirs();
getPackageOutputFile().getParentFile().mkdirs();
@Nullable File resOutBaseNameFile = getPackageOutputFile();
// If are in instant run mode and we have an instant run enabled manifest
File instantRunManifest = getInstantRunManifestFile();
File manifestFileToPackage = instantRunBuildContext.isInInstantRunMode() &&
instantRunManifest != null &&
instantRunManifest.exists() ? instantRunManifest : getManifestFile();
//增加awb模块编译所需要的额外参数
addAaptOptions();
AaptPackageProcessBuilder aaptPackageCommandBuilder = new AaptPackageProcessBuilder(
manifestFileToPackage,
getAaptOptions()).setAssetsFolder(getAssetsDir())
.setResFolder(getResDir())
.setLibraries(getLibraries())
.setPackageForR(getPackageForR())
.setSourceOutputDir(absolutePath(srcOut))
.setSymbolOutputDir(absolutePath(getTextSymbolOutputDir()))
.setResPackageOutput(absolutePath(resOutBaseNameFile))
.setProguardOutput(absolutePath(getProguardOutputFile()))
.setType(getType())
.setDebuggable(getDebuggable())
.setPseudoLocalesEnabled(getPseudoLocalesEnabled())
.setResourceConfigs(getResourceConfigs())
.setSplits(getSplits())
.setPreferredDensity(getPreferredDensity());
@NonNull AtlasBuilder builder = (AtlasBuilder) getBuilder();
// MergingLog mergingLog = new MergingLog(getMergeBlameLogFolder());
//
// ProcessOutputHandler processOutputHandler = new ParsingProcessOutputHandler(
// new ToolOutputParser(new AaptOutputParser(), getILogger()),
// builder.getErrorReporter());
ProcessOutputHandler processOutputHandler = new LoggedProcessOutputHandler(getILogger());
try {
builder.processAwbResources(aaptPackageCommandBuilder,
getEnforceUniquePackageName(),
processOutputHandler,
getMainSymbolFile());
if (resOutBaseNameFile != null) {
if (instantRunBuildContext.isInInstantRunMode()) {
instantRunBuildContext.addChangedFile(FileType.RESOURCES, resOutBaseNameFile);
// get the new manifest file CRC
JarFile jarFile = new JarFile(resOutBaseNameFile);
String currentIterationCRC = null;
try {
ZipEntry entry = jarFile.getEntry(SdkConstants.ANDROID_MANIFEST_XML);
if (entry != null) {
currentIterationCRC = String.valueOf(entry.getCrc());
}
} finally {
jarFile.close();
}
// check the manifest file binary format.
File crcFile = new File(instantRunSupportDir, "manifest.crc");
if (crcFile.exists() && currentIterationCRC != null) {
// compare its content with the new binary file crc.
String previousIterationCRC = Files.readFirstLine(crcFile, Charsets.UTF_8);
if (!currentIterationCRC.equals(previousIterationCRC)) {
instantRunBuildContext.close();
//instantRunBuildContext.setVerifierResult(InstantRunVerifierStatus
// .BINARY_MANIFEST_FILE_CHANGE);
}
}
// write the new manifest file CRC.
Files.createParentDirs(crcFile);
Files.write(currentIterationCRC, crcFile, Charsets.UTF_8);
}
}
} catch (Exception e) {
e.printStackTrace();
throw new GradleException("process res exception", e);
}
}
//增加特殊的命令参数
private void addAaptOptions() {
//BUGFIX , 直接访问属性的写法是访问不到的,动态类的属性名称
List<String> options = new ArrayList<String>();
String customPackageId = getCustomPackageId();
if (StringUtils.isNotBlank(customPackageId)) {
String[] split = customPackageId.split("\\.");
options.add("--forced-package-id");
options.add(split[0]);
if (split.length > 1) { // 使用小数点的后一位代表type id的偏移位置
options.add("--type-id-offset");
options.add(split[1]);
}
}
if (StringUtils.isNotBlank(getSktPackageName())) {
options.add("--main-package");
options.add(getSktPackageName());
}
if (null != getShareResourceFile() && getShareResourceFile().exists()) {
options.add("-I");
options.add(getShareResourceFile().getAbsolutePath());
}
//if (null != getBaselineFile()) {
// options.add("-B");
// options.add(getBaselineFile().getAbsolutePath());
//}
aaptOptions.additionalParameters(options.toArray(new String[0]));
}
private boolean isSplitPackage(File file, File resBaseName) {
if (file.getName().startsWith(resBaseName.getName())) {
for (String split : splits) {
if (file.getName().contains(split)) {
return true;
}
}
}
return false;
}
@Nullable
private static String absolutePath(@Nullable File file) {
return file == null ? null : file.getAbsolutePath();
}
public static class ConfigAction implements TaskConfigAction<ProcessAwbAndroidResources> {
private final VariantOutputScope scope;
private final File symbolLocation;
private final boolean generateResourcePackage;
private final AwbBundle awbBundle;
private final AtlasBuilder tAndroidBuilder;
private final AppVariantOutputContext appVariantOutputContext;
public ConfigAction(VariantOutputScope scope,
File symbolLocation,
boolean generateResourcePackage,
AwbBundle awbBundle,
AtlasBuilder tAndroidBuilder,
AppVariantOutputContext appVariantOutputContext) {
this.scope = scope;
this.symbolLocation = symbolLocation;
this.generateResourcePackage = generateResourcePackage;
this.awbBundle = awbBundle;
this.tAndroidBuilder = tAndroidBuilder;
this.appVariantOutputContext = appVariantOutputContext;
}
@NonNull
@Override
public String getName() {
return scope.getTaskName("process", "AwbResources[" + awbBundle.getName() + "]");
}
@NonNull
@Override
public Class<ProcessAwbAndroidResources> getType() {
return ProcessAwbAndroidResources.class;
}
@Override
public void execute(@NonNull ProcessAwbAndroidResources processResources) {
final BaseVariantOutputData variantOutputData = scope.getVariantOutputData();
final BaseVariantData<? extends BaseVariantOutputData> variantData = scope.getVariantScope()
.getVariantData();
final GradleVariantConfiguration config = variantData.getVariantConfiguration();
appVariantOutputContext.getAwbAndroidResourcesMap()
.put(awbBundle.getName(), processResources);
processResources.setAndroidBuilder(tAndroidBuilder);
processResources.setVariantName(config.getFullName());
if (variantData.getSplitHandlingPolicy() ==
SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY) {
Set<String> allFilters = new HashSet<String>();
allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.DENSITY));
allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.LANGUAGE));
processResources.splits = allFilters;
}
//设置AWB的resource处理所需要的特殊参数
ConventionMappingHelper.map(processResources, "mainSymbolFile", new Callable<File>() {
@Override
public File call() throws Exception {
return new File(variantOutputData.processResourcesTask.getTextSymbolOutputDir(),
"R.txt");
}
});
processResources.setAwbBundleName(awbBundle.getName());
//TODO
ConventionMappingHelper.map(processResources,
"customPackageId",
new Callable<String>() {
@Override
public String call() throws Exception {
String value = AtlasBuildContext.customPackageIdMaps
.get(awbBundle.getResolvedCoordinates()
.getGroupId() +
":" +
awbBundle.getResolvedCoordinates()
.getArtifactId());
if (org.apache.commons.lang.StringUtils.isEmpty(
value)) {
throw new GradleException("package id is empaty" +
awbBundle);
}
return value;
}
});
ConventionMappingHelper.map(processResources,
"shareResourceFile",
new Callable<File>() {
@Override
public File call() throws Exception {
return variantOutputData.processResourcesTask.getPackageOutputFile();
}
});
ConventionMappingHelper.map(processResources, "sktPackageName", new Callable<String>() {
@Override
public String call() throws Exception {
String packageName = ManifestFileUtils.getApplicationId(variantOutputData.manifestProcessorTask
.getManifestOutputFile());
if (null != packageName) {
return packageName;
} else {
return config.getOriginalApplicationId();
}
}
});
// only generate code if the density filter is null, and if we haven't generated
// it yet (if you have abi + density splits, then several abi output will have no
// densityFilter)
//TODO 先把这个if逻辑去掉,不知道有什么用处
// if (variantOutputData.getMainOutputFile()
// .getFilter(com.android.build.OutputFile.DENSITY) == null
// && variantData.generateRClassTask == null) {
// variantData.generateRClassTask = processResources;
processResources.enforceUniquePackageName = scope.getGlobalScope()
.getExtension()
.getEnforceUniquePackageName();
ConventionMappingHelper.map(processResources,
"libraries",
new Callable<List<? extends AndroidLibrary>>() {
@Override
public List<? extends AndroidLibrary> call() throws Exception {
return awbBundle.getAndroidLibraries();
}
});
ConventionMappingHelper.map(processResources, "packageForR", new Callable<String>() {
@Override
public String call() throws Exception {
return awbBundle.getPackageName();
}
});
ConventionMappingHelper.map(processResources, "rtxtFile", new Callable<File>() {
@Override
public File call() throws Exception {
return new File(awbBundle.getAndroidLibrary().getFolder(), "R.txt");
}
});
// TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?
processResources.setSourceOutputDir(appVariantOutputContext.getAwbRClassSourceOutputDir(
config,
awbBundle));
processResources.setTextSymbolOutputDir(symbolLocation);
//AWb暂时不做shrinkResource的工作
// if (config.getBuildType().isMinifyEnabled()) {
// if (config.getBuildType().isShrinkResources() && config.getUseJack()) {
// LoggingUtil.displayWarning(Logging.getLogger(getClass()),
// config.getGlobalScope().getProject(),
// "shrinkResources does not yet work with useJack=true");
// }
// processResources.setProguardOutputFile(
// config.getVariantScope().getProcessAndroidResourcesProguardOutputFile());
//
// } else if (config.getBuildType().isShrinkResources()) {
// LoggingUtil.displayWarning(Logging.getLogger(getClass()),
// config.getGlobalScope().getProject(),
// "To shrink resources you must also enable ProGuard");
// }
// }
ConventionMappingHelper.map(processResources, "manifestFile", new Callable<File>() {
@Override
public File call() throws Exception {
return awbBundle.getMergedManifest();
}
});
ConventionMappingHelper.map(processResources,
"instantRunManifestFile",
new Callable<File>() {
@Override
public File call() throws Exception {
return awbBundle.getMergedManifest();
}
});
ConventionMappingHelper.map(processResources, "resDir", new Callable<File>() {
@Override
public File call() throws Exception {
DataBindingOptions dataBindingOptions = appVariantOutputContext.getVariantContext()
.getAppExtension()
.getDataBinding();
File file = null;
if (null != dataBindingOptions && dataBindingOptions.isEnabled()) {
file = appVariantOutputContext.getVariantContext()
.getAwbLayoutFolderOutputForDataBinding(awbBundle);
} else {
file = appVariantOutputContext.getVariantContext()
.getMergeResources(awbBundle);
}
if (!file.exists()) {
file.mkdirs();
}
return file;
}
});
ConventionMappingHelper.map(processResources, "assetsDir", new Callable<File>() {
@Override
public File call() throws Exception {
return appVariantOutputContext.getVariantContext().getMergeAssets(awbBundle);
}
});
ConventionMappingHelper.map(processResources, "baselineFile", new Callable<File>() {
@Override
public File call() throws Exception {
File baseAwb = appVariantOutputContext.getVariantContext().apContext.getBaseAwb(
awbBundle.getAwbSoName());
return baseAwb;
}
});
if (generateResourcePackage) {
processResources.setPackageOutputFile(appVariantOutputContext.getAwbProcessResourcePackageOutputFile(
awbBundle));
}
processResources.setType(config.getType());
processResources.setDebuggable(config.getBuildType().isDebuggable());
AaptOptions aaptOptions = scope.getGlobalScope().getExtension().getAaptOptions();
AaptOptions cloneAaptOptions = new MyAaptOptions();
try {
BeanUtils.copyProperties(cloneAaptOptions, aaptOptions);
} catch (Throwable e) {
throw new StopExecutionException(e.getMessage());
}
processResources.setAaptOptions(cloneAaptOptions);
processResources.setPseudoLocalesEnabled(config.getBuildType()
.isPseudoLocalesEnabled());
ConventionMappingHelper.map(processResources,
"resourceConfigs",
new Callable<Collection<String>>() {
@Override
public Collection<String> call() throws Exception {
Collection<String> resConfigs = config.getMergedFlavor()
.getResourceConfigurations();
if (resConfigs.size() == 1 &&
Iterators.getOnlyElement(resConfigs.iterator())
.equals("auto")) {
if (scope.getGlobalScope()
.getAndroidBuilder()
.getTargetInfo()
.getBuildTools()
.getRevision()
.getMajor() >= 21) {
return variantData.discoverListOfResourceConfigsNotDensities();
} else {
return variantData.discoverListOfResourceConfigs();
}
}
return config.getMergedFlavor()
.getResourceConfigurations();
}
});
ConventionMappingHelper.map(processResources,
"preferredDensity",
new Callable<String>() {
@Override
@Nullable
public String call() throws Exception {
String variantFilter = variantOutputData.getMainOutputFile()
.getFilter(com.android.build.OutputFile.DENSITY);
if (variantFilter != null) {
return variantFilter;
}
return AndroidGradleOptions.getBuildTargetDensity(
scope.getGlobalScope().getProject());
}
});
processResources.setMergeBlameLogFolder(getResourceBlameLogDir(config));
processResources.instantRunSupportDir = getInstantRunSupportDir(config);
InstantRunBuildContext instantRunBuildContext = new InstantRunBuildContext();
instantRunBuildContext.setInstantRunMode(false);
processResources.instantRunBuildContext = instantRunBuildContext;
//processResources.buildInfoFile = InstantRunWrapperTask.ConfigAction.getTmpBuildInfoFile(
// scope.getVariantScope());
}
public File getInstantRunSupportDir(GradleVariantConfiguration config) {
return new File(scope.getGlobalScope().getIntermediatesDir(),
"/awb-instant-run-support/" +
config.getDirName() +
"/" +
awbBundle.getName());
}
public File getResourceBlameLogDir(GradleVariantConfiguration config) {
return new File(scope.getGlobalScope().getIntermediatesDir(),
"awb-blame/res/" +
config.getDirectorySegments() +
"/" +
awbBundle.getName());
}
}
@InputFile
public File getManifestFile() {
return manifestFile;
}
public void setManifestFile(File manifestFile) {
this.manifestFile = manifestFile;
}
// not an input, it's optional and should never changes independently of the main manifest file.
public File getInstantRunManifestFile() {
return instantRunManifestFile;
}
public void setInstantRunManifestFile(File manifestFile) {
this.instantRunManifestFile = manifestFile;
}
@NonNull
@InputDirectory
public File getResDir() {
return resDir;
}
public void setResDir(@NonNull File resDir) {
this.resDir = resDir;
}
@InputDirectory
@Optional
@Nullable
public File getAssetsDir() {
return assetsDir;
}
public void setAssetsDir(File assetsDir) {
this.assetsDir = assetsDir;
}
@OutputDirectory
@Optional
@Nullable
public File getSourceOutputDir() {
return sourceOutputDir;
}
public void setSourceOutputDir(File sourceOutputDir) {
this.sourceOutputDir = sourceOutputDir;
}
@OutputDirectory
@Optional
@Nullable
public File getTextSymbolOutputDir() {
return textSymbolOutputDir;
}
public void setTextSymbolOutputDir(File textSymbolOutputDir) {
this.textSymbolOutputDir = textSymbolOutputDir;
}
@OutputFile
@Optional
@Nullable
public File getPackageOutputFile() {
return packageOutputFile;
}
public void setPackageOutputFile(File packageOutputFile) {
this.packageOutputFile = packageOutputFile;
}
@OutputFile
@Optional
@Nullable
public File getProguardOutputFile() {
return proguardOutputFile;
}
public void setProguardOutputFile(File proguardOutputFile) {
this.proguardOutputFile = proguardOutputFile;
}
@Input
public Collection<String> getResourceConfigs() {
return resourceConfigs;
}
public void setResourceConfigs(Collection<String> resourceConfigs) {
this.resourceConfigs = resourceConfigs;
}
@Input
@Optional
@Nullable
public String getPreferredDensity() {
return preferredDensity;
}
public void setPreferredDensity(String preferredDensity) {
this.preferredDensity = preferredDensity;
}
@Input
String getBuildToolsVersion() {
return getBuildTools().getRevision().toString();
}
@Nested
@Optional
@Nullable
public List<? extends AndroidLibrary> getLibraries() {
return libraries;
}
public void setLibraries(List<? extends AndroidLibrary> libraries) {
this.libraries = libraries;
}
@Input
@Optional
@Nullable
public String getPackageForR() {
return packageForR;
}
public void setPackageForR(String packageForR) {
this.packageForR = packageForR;
}
@Input
@Optional
@Nullable
public Collection<String> getSplits() {
return splits;
}
public void setSplits(Collection<String> splits) {
this.splits = splits;
}
@Input
public boolean getEnforceUniquePackageName() {
return enforceUniquePackageName;
}
public void setEnforceUniquePackageName(boolean enforceUniquePackageName) {
this.enforceUniquePackageName = enforceUniquePackageName;
}
/**
* Does not change between incremental builds, so does not need to be @Input.
*/
public VariantType getType() {
return type;
}
public void setType(VariantType type) {
this.type = type;
}
@Input
public boolean getDebuggable() {
return debuggable;
}
public void setDebuggable(boolean debuggable) {
this.debuggable = debuggable;
}
@Input
public boolean getPseudoLocalesEnabled() {
return pseudoLocalesEnabled;
}
public void setPseudoLocalesEnabled(boolean pseudoLocalesEnabled) {
this.pseudoLocalesEnabled = pseudoLocalesEnabled;
}
@Nested
public AaptOptions getAaptOptions() {
return aaptOptions;
}
public void setAaptOptions(AaptOptions aaptOptions) {
this.aaptOptions = aaptOptions;
}
@Input
public File getMergeBlameLogFolder() {
return mergeBlameLogFolder;
}
public void setMergeBlameLogFolder(File mergeBlameLogFolder) {
this.mergeBlameLogFolder = mergeBlameLogFolder;
}
@InputFile
public File getMainSymbolFile() {
return mainSymbolFile;
}
public void setMainSymbolFile(File mainSymbolFile) {
this.mainSymbolFile = mainSymbolFile;
}
@Input
public String getAwbBundleName() {
return awbBundleName;
}
public void setAwbBundleName(String awbBundleName) {
this.awbBundleName = awbBundleName;
}
@Input
@Optional
public String getCustomPackageId() {
return customPackageId;
}
public void setCustomPackageId(String customPackageId) {
this.customPackageId = customPackageId;
}
@Input
public String getSktPackageName() {
return sktPackageName;
}
public void setSktPackageName(String sktPackageName) {
this.sktPackageName = sktPackageName;
}
@InputFile
public File getShareResourceFile() {
return shareResourceFile;
}
public void setShareResourceFile(File shareResourceFile) {
this.shareResourceFile = shareResourceFile;
}
@InputFile
@Optional
public File getRtxtFile() {
return rtxtFile;
}
@InputFile
@Optional
public File getBaselineFile() {
return baselineFile;
}
public void setBaselineFile(File baselineFile) {
this.baselineFile = baselineFile;
}
public static class MyAaptOptions extends AaptOptions {
@Override
public void useNewCruncher(boolean value) {
}
@Override
public void setUseNewCruncher(boolean value) {
}
}
}