Merge "Remove legacy layoutlib API code" into studio-master-dev
diff --git a/.gitignore b/.gitignore
index cc9acf2..f99b0d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
.idea/workspace.xml
.idea/dictionaries/tnorbye.xml
.idea/g3plugins.project.settings.xml
+.idea/google-java-format.xml
misc/distrib_plugins/build
misc/distrib_plugins/buildSrc/build
misc/distrib_plugins/buildSrc/out
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 46bfc6f..a0922e5 100755
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -4,8 +4,6 @@
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="LINE_SEPARATOR" value=" " />
- <option name="FIELD_NAME_PREFIX" value="m" />
- <option name="STATIC_FIELD_NAME_PREFIX" value="m" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
@@ -15,20 +13,6 @@
<value>
<package name="" withSubpackages="true" static="true" />
<emptyLine />
- <package name="com" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="junit" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="net" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="org" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="android" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="java" withSubpackages="true" static="false" />
- <emptyLine />
- <package name="javax" withSubpackages="true" static="false" />
- <emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
</value>
@@ -137,6 +121,8 @@
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
+ <option name="METHOD_ANNOTATION_WRAP" value="1" />
+ <option name="FIELD_ANNOTATION_WRAP" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="JSON">
@@ -147,4 +133,4 @@
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
-</project>
+</project>
\ No newline at end of file
diff --git a/.idea/libraries/uast.xml b/.idea/libraries/uast.xml
index 76e3b53..70d3a17 100644
--- a/.idea/libraries/uast.xml
+++ b/.idea/libraries/uast.xml
@@ -1,9 +1,9 @@
<component name="libraryTable">
<library name="uast">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/../../prebuilts/tools/common/m2/repository/com/android/tools/external/com-intellij/uast/145.597.3/uast-145.597.3.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/tools/common/uast/uast-145.597.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
-</component>
+</component>
\ No newline at end of file
diff --git a/annotations/BUILD b/annotations/BUILD
index 5c4f5c6..5a3c7dd 100644
--- a/annotations/BUILD
+++ b/annotations/BUILD
@@ -3,7 +3,6 @@
iml_module(
name = "studio.android-annotations",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
)
diff --git a/apkparser/BUILD b/apkparser/BUILD
index 60a0253..2e12112 100644
--- a/apkparser/BUILD
+++ b/apkparser/BUILD
@@ -3,11 +3,11 @@
iml_module(
name = "studio.binary-resources",
srcs = ["binary-resources/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["binary-resources/testResources"],
test_srcs = ["binary-resources/javatests"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:jsr305",
"//tools/idea/.idea/libraries:guava-tools",
diff --git a/apkparser/binary-resources/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java b/apkparser/binary-resources/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java
index fd7e8bc..1829ba2 100644
--- a/apkparser/binary-resources/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java
+++ b/apkparser/binary-resources/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java
@@ -571,11 +571,11 @@
@Override
public int hashCode() {
return Objects
- .hash(size, mcc, mnc, language, region, orientation, touchscreen, density, keyboard, navigation, inputFlags, screenWidth,
+ .hash(size, mcc, mnc, Arrays.hashCode(language), Arrays.hashCode(region), orientation, touchscreen, density, keyboard, navigation, inputFlags, screenWidth,
screenHeight,
- sdkVersion, minorVersion, screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, screenHeightDp, localeScript,
- localeVariant,
- screenLayout2, unknown);
+ sdkVersion, minorVersion, screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, screenHeightDp, Arrays.hashCode(localeScript),
+ Arrays.hashCode(localeVariant),
+ screenLayout2, Arrays.hashCode(unknown));
}
@Override
diff --git a/asset-studio/BUILD b/asset-studio/BUILD
index ce84d6c..c246fc1 100644
--- a/asset-studio/BUILD
+++ b/asset-studio/BUILD
@@ -3,14 +3,15 @@
iml_module(
name = "studio.assetstudio",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/base/common:studio.common",
"//tools/base/layoutlib-api:studio.layoutlib-api",
],
+ # do not sort: must match IML order
deps = [
"//tools/base/common:studio.common[module]",
"//tools/base/layoutlib-api:studio.layoutlib-api[module]",
diff --git a/bazel/BUILD b/bazel/BUILD
index 50f5ec4..6209a4a 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -21,30 +21,30 @@
# making it unsuitable for bazel or any other reasonable tool.
# TODO: Update and use the prebuilts dependency
deps = [
- "//tools:idea/lib/groovy-all-2.4.6",
":utils",
+ "//tools:idea/lib/groovy-all-2.4.6",
],
)
java_binary(
name = "groovy_stub_gen",
- runtime_deps = [":groovy-compiler"],
main_class = "com.android.tools.groovy.GroovyStubGenerator",
visibility = ["//visibility:public"],
+ runtime_deps = [":groovy-compiler"],
)
java_binary(
name = "groovyc",
- runtime_deps = [":groovy-compiler"],
main_class = "com.android.tools.groovy.GroovyCompiler",
visibility = ["//visibility:public"],
+ runtime_deps = [":groovy-compiler"],
)
java_binary(
name = "unzipper",
main_class = "com.android.tools.utils.Unzipper",
- runtime_deps = [":utils"],
visibility = ["//visibility:public"],
+ runtime_deps = [":utils"],
)
genrule(
@@ -63,8 +63,8 @@
"kotlin-reflect.jar",
],
cmd = "$(location :unzipper) $< " +
- "Kotlin/kotlinc/lib/kotlin-runtime.jar:$(@D)/kotlin-runtime.jar " +
- "Kotlin/kotlinc/lib/kotlin-reflect.jar:$(@D)/kotlin-reflect.jar",
+ "Kotlin/kotlinc/lib/kotlin-runtime.jar:$(@D)/kotlin-runtime.jar " +
+ "Kotlin/kotlinc/lib/kotlin-reflect.jar:$(@D)/kotlin-reflect.jar",
tools = [":unzipper"],
visibility = ["//visibility:public"],
)
@@ -73,24 +73,24 @@
name = "kotlinc",
srcs = ["src/com/android/tools/kotlin/KotlinCompiler.java"],
main_class = "com.android.tools.kotlin.KotlinCompiler",
+ visibility = ["//visibility:public"],
+ runtime_deps = [":kotlin-runtime"],
deps = [
":kotlin-compiler",
":utils",
],
- runtime_deps = [":kotlin-runtime"],
- visibility = ["//visibility:public"],
)
java_binary(
name = "formc",
srcs = ["src/com/android/tools/form/FormCompiler.java"],
main_class = "com.android.tools.form.FormCompiler",
+ visibility = ["//visibility:public"],
+ runtime_deps = [":kotlin-runtime"],
deps = [
":formc-deps",
":utils",
],
- runtime_deps = [":kotlin-runtime"],
- visibility = ["//visibility:public"],
)
java_import(
@@ -113,8 +113,8 @@
":utils",
"//tools/base/third_party:com.google.guava_guava",
"//tools/base/third_party:org.apache.maven_maven-aether-provider",
- "//tools/base/third_party:org.eclipse.aether_aether-transport-http",
"//tools/base/third_party:org.eclipse.aether_aether-connector-basic",
+ "//tools/base/third_party:org.eclipse.aether_aether-transport-http",
],
)
@@ -129,9 +129,6 @@
# See README.md
java_binary(
name = "third_party_build_generator",
- main_class = "com.android.tools.maven.ThirdPartyBuildGenerator",
- visibility = ["//visibility:public"],
- runtime_deps = [":maven"],
args = [
"com.android.tools.external.com-intellij:uast:145.597.3",
"com.android.tools.external.lombok:lombok-ast:0.2.3",
@@ -168,6 +165,9 @@
"org.easymock:easymock:3.3",
"org.mockito:mockito-all:1.9.5",
],
+ main_class = "com.android.tools.maven.ThirdPartyBuildGenerator",
+ visibility = ["//visibility:public"],
+ runtime_deps = [":maven"],
)
# See README.md
@@ -181,6 +181,7 @@
java_binary(
name = "jarjar",
main_class = "com.tonicsystems.jarjar.Main",
+ visibility = ["//visibility:public"],
runtime_deps = [
"//prebuilts/tools/common/m2/repository/net/sf/jopt-simple/jopt-simple/4.9:jar",
"//prebuilts/tools/common/m2/repository/org/anarres/jarjar/jarjar-command/1.0.0:jar",
@@ -189,7 +190,6 @@
"//prebuilts/tools/common/m2/repository/org/ow2/asm/asm/5.0.4:jar",
"//prebuilts/tools/common/m2/repository/org/slf4j/slf4j-api/1.7.7:jar",
],
- visibility = ["//visibility:public"],
)
config_setting(
diff --git a/bazel/README.md b/bazel/README.md
index 3475757..2cbbc25 100644
--- a/bazel/README.md
+++ b/bazel/README.md
@@ -1,41 +1,169 @@
-# Bazel utilities
+# How to Bazel
-This package contains code related to our Bazel setup: support for compiling IntelliJ
-forms, Kotlin, custom macros, BUILD files generators etc.
+This directory contains the core files to run studio-master-dev tests using
+bazel.
-## BUILD files generators
+## Running bazel
-There are three `java_binaries` here that can be used to manage dependecies in
-prebuilts. Please note that these tools don't format the BUILD files, so you
-should run `buildifer` over the newly created files afterwards.
+Bazel has the concept of a _workspace_: the root of all your source files. For
+us, it is where we `repo init` our source tree. For google3 vets, this is the
+"google3" directory. In this document we assume the current directory to be the
+workspace, but note that bazel can be run from anywhere in the tree.
-### `third_party_build_generator`
+Bazel is checked-in at `tools/base/bazel/bazel`. To make things easy you might
+want to link it like this (assuming `~/bin` is in `$PATH`)
-Used to generate `//tools/base/third_party/BUILD`. Computes effective versions of
-all necessary dependencies and creates a `java_library` rule for each one of
-them. It will also download missing jars into `//prebuilts/tools/common/m2/repository`.
+```shell
+ln -s <workspace>/tools/base/bazel ~/bin/bazel
+```
-Can be invoked by running `bazel run //tools/base/bazel:third_party_build_generator`.
+Then no matter where you are in the workspace, bazel will find the right,
+platform specific, binary and run it.
+
+## Running all the tests
+
+The command to run all the bazel tests run by the PSQ is:
+
+```shell
+bazel test $(<tools/base/bazel/test_targets)
+```
+
+To run all the tests found in `tools/base`:
+
+```shell
+bazel test //tools/base/...
+```
+
+To run all the tests in the IntelliJ Android plugin:
+
+```
+bazel test //tools/adt/idea:android_tests
+```
+
+To build Studio without running the tests:
+
+```
+bazel build //tools/adt/idea/...
+```
+
+To run a single test:
+
+```
+bazel test //tools/adt/idea:android_tests --test_filter=AndroidLayoutDomTest
+```
+
+To debug a single test, which will open remote debugging:
+
+```
+bazel test //tools/adt/idea:android_tests --test_filter=AndroidLayoutDomTest --java_debug
+```
+
+## BUILD files
+
+BUILD files define a package with a set build and test rules. In order to
+support Android Studio we created a new kind of rule, that matches an IntelliJ
+module: the `iml_module` rule.
+
+> Note that we modify these BUILD files manually, so whenever you make a change
+> to an `.iml` file, its corresponding BUILD file will have to be changed.
+
+### iml_module
+
+```
+iml_module(name, srcs, test_srcs, exclude, resources, test_resources, deps, test_runtime_deps,
+visibility, exports,javacopts, test_data, test_timeout, test_class, test_shard_count, tags)
+```
+
+This rule will generate the targets:
+
+* _name_: The production library for this module.
+* _name_\_testlib: The test library for this module.
+* _name_\_tests: The test target to run this module's tests.
+
+#### Example
+
+```
+iml_module(
+ name = "android",
+ srcs = ["src/main/java"],
+ resources = ["src/main/resources"],
+ test_data = glob(["testData/**"]),
+ test_resources = ["src/test/resources"],
+ test_srcs = ["src/test/java"],
+ deps = [
+ "//a/module/only/needed/in/tests:name[module, test]",
+ "//a/standard/java/dependency:dep",
+ "//path/to/libs:junit-4.12[test]",
+ "//path/to/module:name[module]",
+ ],
+)
+```
+
+Attribute | Description
+---------------- | -----------
+`name` | The name of the rule (usually matching Studio's module name).
+`srcs` | A list of directories containing the sources. .java, .groovy, .kotlin and .form files are supported.
+`resources` | A list directories with the production resources.
+`deps` | A tag-enhanced list of dependencies, of the form `//label[tag1,tag2,...]`. Supported tags are: `module`, for iml_module dependencies, and `test` for test only dependencies.
+`test_srcs` | A list of directories with the test sources.
+`test_resources` | A list of directories with the test resources.
+`test_data` | A list of files needed to run the test.
+
+> A major difference with actual iml modules is that in bazel we must specify
+> the files needed to run the tests. These files are known as _runfiles_ and are
+> specified via the `test_data` attribute. This is essential to determining
+> which test targets need to be run when an arbitrary file has changed.
+
+## Circular Dependencies
+
+_Just don't_. IntelliJ has support for circular dependencies of modules, but we
+do not use it in our code base.
+
+## Additional tools
+
+There are several other tools in this package that can be used to manage
+dependencies in prebuilts.
+
+### third\_party\_build\_generator
+
+Used to generate `//tools/base/third_party/BUILD`. Computes effective versions
+of all necessary dependencies and creates a `java_library` rule for each one of
+them. It will also download missing jars into
+`//prebuilts/tools/common/m2/repository`.
+
+Invoked by running:
+
+```
+bazel run //tools/base/bazel:third_party_build_generator
+```
The dependencies we need are specified in the BUILD file in this package.
-### `add_dependency`
+### add\_dependency
Can be used to download one or more Maven artifacts into prebuilts, including
all transitive dependencies.
-
-Invoked by running
-`bazel run //tools/base/bazel:add_dependency com.example:foo:1.0`.
+
+Invoked by running:
+
+```
+bazel run //tools/base/bazel:add_dependency com.example:foo:1.0
+```
You can also use it to download protoc binaries, like this:
-`bazel run //tools/base/bazel:add_dependency com.google.protobuf:protoc:exe:linux-x86_64:3.0.0`
+```
+bazel run //tools/base/bazel:add_dependency com.google.protobuf:protoc:exe:linux-x86_64:3.0.0
+```
-### `java_import_generator`
+### java\_import\_generator
-Creates a BUILD file for every POM file in the prebuilts maven repo. Both of
-the binaries above do the same, but this can be useful if prebuilts was
-modified using Gradle's `cloneArtifacts` tasks or manually.
+Creates a BUILD file for every POM file in the prebuilts maven repo. Both of the
+binaries above do the same, but this can be useful if prebuilts was modified
+using Gradle's `cloneArtifacts` tasks or manually.
-Invoked by running
-`bazel run //tools/base/bazel:java_import_generator`.
+Invoked by running:
+
+```
+bazel run //tools/base/bazel:java_import_generator
+```
diff --git a/bazel/gradle_projects b/bazel/gradle_projects
index a76663f..b5710db 100644
--- a/bazel/gradle_projects
+++ b/bazel/gradle_projects
@@ -19,7 +19,6 @@
lint/
misc/
ninepatch/
-perflib/
pixelprobe/
repository/
rpclib/
diff --git a/bazel/plugin/bazel.iml b/bazel/plugin/bazel.iml
index 1efa186..49dfa77 100644
--- a/bazel/plugin/bazel.iml
+++ b/bazel/plugin/bazel.iml
@@ -7,7 +7,7 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
- <orderEntry type="jdk" jdkName="IntelliJ IDEA Community Edition IC-145.971.21" jdkType="IDEA JDK" />
+ <orderEntry type="jdk" jdkName="IntelliJ Platform Plugin SDK" jdkType="IDEA JDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
diff --git a/bazel/plugin/src/com/android/tools/bazel/BazelModule.java b/bazel/plugin/src/com/android/tools/bazel/BazelModule.java
index 2235cfc..a067fb9 100644
--- a/bazel/plugin/src/com/android/tools/bazel/BazelModule.java
+++ b/bazel/plugin/src/com/android/tools/bazel/BazelModule.java
@@ -26,8 +26,10 @@
import java.io.File;
import java.util.Collections;
+import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
+import java.util.function.Function;
/**
* A collection of modules with cyclic dependencies that form a strongly connected component.
@@ -45,11 +47,14 @@
modules.add(module);
}
+ private static final Function<Module, Integer> GET_NUM_ORDER_ENTRIES =
+ module -> ModuleRootManager.getInstance(module).getOrderEntries().length;
+ private static final Comparator<Module> BY_NUM_ORDER_ENTRIES =
+ (m1, m2) -> GET_NUM_ORDER_ENTRIES.apply(m1) - GET_NUM_ORDER_ENTRIES.apply(m2);
+
public String getName() {
- for (Module module : modules) {
- return (isSingle() ? "" : "MM_") + module.getName();
- }
- return "";
+ return modules.stream().max(BY_NUM_ORDER_ENTRIES).get().getName()
+ + (isSingle() ? "" : "_and_others");
}
public boolean isSingle() {
diff --git a/bazel/plugin/src/com/android/tools/bazel/model/BazelRule.java b/bazel/plugin/src/com/android/tools/bazel/model/BazelRule.java
index 46f79fa..22f85f4 100644
--- a/bazel/plugin/src/com/android/tools/bazel/model/BazelRule.java
+++ b/bazel/plugin/src/com/android/tools/bazel/model/BazelRule.java
@@ -17,14 +17,11 @@
package com.android.tools.bazel.model;
import com.android.tools.bazel.parser.ast.*;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.io.IOException;
-import java.util.Collection;
import java.util.Set;
-import java.util.stream.Collectors;
public abstract class BazelRule {
@@ -110,38 +107,4 @@
pkg.getBuildFile().addStatementBefore(loadStatement, functionCall);
return loadStatement;
}
-
- /**
- * Sets the argument of the given call expression named {@code name} to be {@code values}.
- */
- protected final void setArgument(CallStatement rule, String name, Collection<?> values) {
- if (!values.isEmpty()) {
- ListExpression list = ListExpression.build(values.stream().map(Object::toString).collect(Collectors.toList()));
- list.setSingleLine(values.size() <= 1);
- rule.getCall().setArgument(name, list);
- }
- }
-
- /**
- * Ensures an element is in the a list in the given call expression.
- */
- protected void addElementToList(CallStatement call, String attribute, String element) {
- Expression expression = call.getCall().getArgument(attribute);
- ListExpression list;
- if (expression == null) {
- list = ListExpression.build(ImmutableList.of());
- call.getCall().setArgument(attribute, list);
- } else if (expression instanceof BinaryExpression
- && (((BinaryExpression)expression).getLeft() instanceof ListExpression)) {
- list = (ListExpression) ((BinaryExpression) expression).getLeft();
- } else if (expression instanceof ListExpression) {
- list = (ListExpression) expression;
- } else {
- list = ListExpression.build(ImmutableList.of());
- BinaryExpression plus = new BinaryExpression(list, new Token("+", Token.Kind.PLUS), expression);
- call.getCall().setArgument(attribute, plus);
- }
- list.addIfNew(LiteralExpression.string(element));
- list.setSingleLine(list.size() <= 1);
- }
}
diff --git a/bazel/plugin/src/com/android/tools/bazel/model/ImlModule.java b/bazel/plugin/src/com/android/tools/bazel/model/ImlModule.java
index 0b42630..8ff612f 100644
--- a/bazel/plugin/src/com/android/tools/bazel/model/ImlModule.java
+++ b/bazel/plugin/src/com/android/tools/bazel/model/ImlModule.java
@@ -16,6 +16,7 @@
package com.android.tools.bazel.model;
+import com.android.tools.bazel.parser.ast.CallExpression;
import com.android.tools.bazel.parser.ast.CallStatement;
import com.google.common.collect.ImmutableList;
@@ -37,23 +38,30 @@
@Override
public void update() throws IOException {
- CallStatement call = getCallStatement("iml_module", name);
- if (getLoad(call) == null) {
- addLoad("//tools/base/bazel:bazel.bzl", call);
+ CallStatement statement = getCallStatement("iml_module", name);
+ if (getLoad(statement) == null) {
+ addLoad("//tools/base/bazel:bazel.bzl", statement);
}
- setArgument(call, "srcs", sources);
- setArgument(call, "test_srcs", testSources);
- setArgument(call, "exclude", exclude);
- setArgument(call, "resources", resources);
- setArgument(call, "test_resources", testResources);
- setArgument(call, "deps", tagDependencies(dependencies));
- setArgument(call, "exports", exported);
- if (!call.isFromFile()) {
- setArgument(call, "javacopts", ImmutableList.of("-extra_checks:off"));
- setArgument(call, "visibility", ImmutableList.of("//visibility:public"));
+ CallExpression call = statement.getCall();
+ call.setArgument("srcs", sources);
+ call.setArgument("test_srcs", testSources);
+ call.setArgument("exclude", exclude);
+ call.setArgument("resources", resources);
+ call.setArgument("test_resources", testResources);
+ call.setArgument("deps", tagDependencies(dependencies));
+ call.setArgument("exports", exported);
+ if (!statement.isFromFile()) {
+ call.setArgument("javacopts", ImmutableList.of("-extra_checks:off"));
+ call.setArgument("visibility", ImmutableList.of("//visibility:public"));
}
- addElementToList(call, "tags", "managed");
+ String reason = "must match IML order";
+ call.setDoNotSort("srcs", reason);
+ call.setDoNotSort("resources", reason);
+ call.setDoNotSort("exports", reason);
+ call.setDoNotSort("deps", reason);
+
+ call.addElementToList("tags", "managed");
}
private List<String> tagDependencies(Set<BazelRule> dependencies) {
diff --git a/bazel/plugin/src/com/android/tools/bazel/model/JavaImport.java b/bazel/plugin/src/com/android/tools/bazel/model/JavaImport.java
index f218173..88dea5e 100644
--- a/bazel/plugin/src/com/android/tools/bazel/model/JavaImport.java
+++ b/bazel/plugin/src/com/android/tools/bazel/model/JavaImport.java
@@ -16,6 +16,7 @@
package com.android.tools.bazel.model;
+import com.android.tools.bazel.parser.ast.CallExpression;
import com.android.tools.bazel.parser.ast.CallStatement;
import com.google.common.collect.ImmutableList;
@@ -32,11 +33,12 @@
@Override
public void update() throws IOException {
- CallStatement call = getCallStatement("java_import", name);
+ CallStatement statement = getCallStatement("java_import", name);
+ CallExpression call = statement.getCall();
- setArgument(call, "jars", jars);
- setArgument(call, "visibility", ImmutableList.of("//visibility:public"));
- addElementToList(call, "tags", "managed");
+ call.setArgument("jars", jars);
+ call.setArgument("visibility", ImmutableList.of("//visibility:public"));
+ call.addElementToList("tags", "managed");
}
public void addJar(String jar) {
diff --git a/bazel/plugin/src/com/android/tools/bazel/model/JavaLibrary.java b/bazel/plugin/src/com/android/tools/bazel/model/JavaLibrary.java
index d1c7e1d..d1cf332 100644
--- a/bazel/plugin/src/com/android/tools/bazel/model/JavaLibrary.java
+++ b/bazel/plugin/src/com/android/tools/bazel/model/JavaLibrary.java
@@ -16,6 +16,7 @@
package com.android.tools.bazel.model;
+import com.android.tools.bazel.parser.ast.CallExpression;
import com.android.tools.bazel.parser.ast.CallStatement;
import com.google.common.collect.ImmutableList;
@@ -32,12 +33,13 @@
@Override
public void update() throws IOException {
- CallStatement call = getCallStatement("java_library", name);
+ CallStatement statement = getCallStatement("java_library", name);
+ CallExpression call = statement.getCall();
- setArgument(call, "runtime_deps", dependencies);
- setArgument(call, "exports", exported);
- setArgument(call, "visibility", ImmutableList.of("//visibility:public"));
- addElementToList(call, "tags", "managed");
+ call.setArgument("runtime_deps", dependencies);
+ call.setArgument("exports", exported);
+ call.setArgument("visibility", ImmutableList.of("//visibility:public"));
+ call.addElementToList("tags", "managed");
}
}
diff --git a/bazel/plugin/src/com/android/tools/bazel/parser/BuildParser.java b/bazel/plugin/src/com/android/tools/bazel/parser/BuildParser.java
index 4014e7e..0794db9 100644
--- a/bazel/plugin/src/com/android/tools/bazel/parser/BuildParser.java
+++ b/bazel/plugin/src/com/android/tools/bazel/parser/BuildParser.java
@@ -143,10 +143,9 @@
* IDENT = EXPRESSION
*/
private Statement parseStatement() {
- TokenizerToken ident = token;
- consume(Kind.IDENT);
+ TokenizerToken ident = consume(Kind.IDENT);
while (token.kind == Kind.NEWLINE) consume();
- Statement statement = null;
+ Statement statement;
switch (token.kind) {
case LPAREN:
int startLine = token.getLine();
@@ -164,6 +163,7 @@
break;
default:
System.err.println("Unexpected statement token: " + token);
+ statement = null;
}
return statement;
diff --git a/bazel/plugin/src/com/android/tools/bazel/parser/ast/Argument.java b/bazel/plugin/src/com/android/tools/bazel/parser/ast/Argument.java
index a20d7bd..9744cab 100644
--- a/bazel/plugin/src/com/android/tools/bazel/parser/ast/Argument.java
+++ b/bazel/plugin/src/com/android/tools/bazel/parser/ast/Argument.java
@@ -83,6 +83,15 @@
this.expression = expression;
}
+ /** Adds a comment for buildifier not to sort this argument for {@code reason}. */
+ public void setDoNotSort(String reason) {
+ if (preComments.stream().noneMatch(s -> s.toLowerCase().contains("do not sort"))
+ && expression instanceof ListExpression
+ && ((ListExpression) expression).size() > 1) {
+ preComments.add(String.format("# do not sort: %s\n", reason));
+ }
+ }
+
@Override
public int compareTo(Argument that) {
int priority = this.getSortPriority() - that.getSortPriority();
diff --git a/bazel/plugin/src/com/android/tools/bazel/parser/ast/CallExpression.java b/bazel/plugin/src/com/android/tools/bazel/parser/ast/CallExpression.java
index 95ad9d4..15b0ec3 100644
--- a/bazel/plugin/src/com/android/tools/bazel/parser/ast/CallExpression.java
+++ b/bazel/plugin/src/com/android/tools/bazel/parser/ast/CallExpression.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableList;
import java.io.PrintWriter;
+import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -137,6 +138,15 @@
return new CallExpression(Token.ident(ident), list, Token.NONE);
}
+ public final void setArgument(String name, Collection<?> values) {
+ if (!values.isEmpty()) {
+ ListExpression list = ListExpression.build(
+ values.stream().map(Object::toString).collect(Collectors.toList()));
+ list.setSingleLine(values.size() <= 1);
+ setArgument(name, list);
+ }
+ }
+
public void setArgument(String name, Expression expression) {
Argument arg = getNamedArgument(name);
if (arg == null) {
@@ -154,4 +164,33 @@
return arg.getExpression();
}
}
+
+ /** Adds a comment for buildifier not to sort {@code argumentName} for {@code reason}. */
+ public void setDoNotSort(String argumentName, String reason) {
+ Argument argument = getNamedArgument(argumentName);
+ if (argument != null) {
+ argument.setDoNotSort(reason);
+ }
+ }
+
+ /** Ensures {@code element} is in the list {@code attribute}. */
+ public void addElementToList(String attribute, String element) {
+ Expression expression = getArgument(attribute);
+ ListExpression list;
+ if (expression == null) {
+ list = ListExpression.build(ImmutableList.of());
+ setArgument(attribute, list);
+ } else if (expression instanceof BinaryExpression
+ && (((BinaryExpression)expression).getLeft() instanceof ListExpression)) {
+ list = (ListExpression) ((BinaryExpression) expression).getLeft();
+ } else if (expression instanceof ListExpression) {
+ list = (ListExpression) expression;
+ } else {
+ list = ListExpression.build(ImmutableList.of());
+ BinaryExpression plus = new BinaryExpression(list, new Token("+", Token.Kind.PLUS), expression);
+ setArgument(attribute, plus);
+ }
+ list.addIfNew(LiteralExpression.string(element));
+ list.setSingleLine(list.size() <= 1);
+ }
}
diff --git a/bazel/sdk/README.md b/bazel/sdk/README.md
index 3ab2452..56f6e89 100644
--- a/bazel/sdk/README.md
+++ b/bazel/sdk/README.md
@@ -134,7 +134,8 @@
```
$ cd /path/to/studio-master-dev/
-# Of course, your branch name will be different...
+# This branch name will become the topic name for your CLs so choose a unique name.
+# Of course, your branch name will be different...
$ repo start devsdk+build-tools+19_0_3 \
prebuilts/studio/sdk/darwin \
prebuilts/studio/sdk/linux \
@@ -201,9 +202,9 @@
### Make sure tests still pass
```
-$ cd /path/to/studio-master-dev/
+$ cd /path/to/studio-master-dev/tools/base/bazel
-$ bazel test ...
+$ ./bazel test $(<test_targets)
```
### Upload code review
@@ -216,7 +217,7 @@
prebuilts/studio/sdk/linux \
prebuilts/studio/sdk/windows \
tools/base \
- -c git commit -a -m "Updated SDK with build-tools;19.0.3"
+ -c git add -A; git commit -a -m "Updated SDK with build-tools;19.0.3"
# When uploading, include -t to ensure all code reviews have the
# same topic (the topic will be set to your current branch name).
diff --git a/bazel/sdk/dev-sdk-packages b/bazel/sdk/dev-sdk-packages
index 4e294b1..38794a1 100644
--- a/bazel/sdk/dev-sdk-packages
+++ b/bazel/sdk/dev-sdk-packages
@@ -4,12 +4,15 @@
# other files used by lint tests
platform-tools:{adb*,api/*,package.xml}
+build-tools;25.0.0
+build-tools;24.0.3
build-tools;24.0.1
build-tools;23.0.0
build-tools;22.0.1
build-tools;21.0.0
build-tools;20.0.0
-platforms;android-24
+platforms;android-25
+add-ons;addon-google_apis-google-24:**:docs/**
# Needed for typo checking
tools:support/*.txt
diff --git a/bazel/sdk/prebuilts.studio.sdk.BUILD b/bazel/sdk/prebuilts.studio.sdk.BUILD
index 4c8387c..b5a7ced 100644
--- a/bazel/sdk/prebuilts.studio.sdk.BUILD
+++ b/bazel/sdk/prebuilts.studio.sdk.BUILD
@@ -8,14 +8,29 @@
visibility = ["//visibility:public"],
)
+# TODO: Bump up to 25.0.0 once we fix AS tests.
filegroup(
name = "build-tools/latest",
- srcs = [":build-tools/24.0.1"],
+ srcs = [":build-tools/24.0.3"],
visibility = ["//visibility:public"],
)
# TODO: Migrate the packages below that depend on specific versions.
filegroup(
+ name = "build-tools/25.0.0",
+ srcs = glob(
+ include = ["*/build-tools/25.0.0/**"],
+ ),
+)
+
+filegroup(
+ name = "build-tools/24.0.3",
+ srcs = glob(
+ include = ["*/build-tools/24.0.3/**"],
+ ),
+)
+
+filegroup(
name = "build-tools/24.0.1",
srcs = glob(
include = ["*/build-tools/24.0.1/**"],
@@ -72,16 +87,20 @@
filegroup(
name = "platforms/latest",
- srcs = [":platforms/android-24"],
+ srcs = [":platforms/android-25"],
visibility = ["//visibility:public"],
)
# Version-specific rule left private in hopes we can depend on platforms/latest instead.
# TODO: Migrate the packages below that depend on specific versions.
platform_filegroup(
- name = "platforms/android-24",
+ name = "platforms/android-25",
visibility = [
"//tools/base/build-system/builder:__pkg__",
],
)
+filegroup(
+ name = "add-ons/addon-google_apis-google-24",
+ srcs = glob(["*/add-ons/addon-google_apis-google-24/**"]),
+)
diff --git a/bazel/test_targets b/bazel/test_targets
index ab98af7..68029cb 100644
--- a/bazel/test_targets
+++ b/bazel/test_targets
@@ -4,26 +4,9 @@
//tools/adt/idea:android_tests
//tools/adt/idea:uitest-framework_tests
//tools/analytics-library/...
-//tools/base/apkparser/...
-//tools/base/asset-studio/...
-//tools/base/build-system/...
-//tools/base/common/...
-//tools/base/ddmlib/...
-//tools/base/draw9patch/...
-//tools/base/instant-run/...
-//tools/base/jack/...
-//tools/base/layoutlib-api/...
-//tools/base/ninepatch/...
-//tools/base/perflib/...
-//tools/base/pixelprobe/...
-//tools/base/profiler/...
-//tools/base/repository/...
-//tools/base/sdk-common/...
-//tools/base/sdklib/...
-//tools/base/testutils/...
+//tools/base/...
//tools/data-binding:studio.compilerCommon_tests
//tools/data-binding:tools.compilerCommon_tests
//tools/vendor/google/...
//tools:idea.extensions_tests
-//tools:idea.forms-compiler_tests
//tools:idea.lang-api_tests
diff --git a/bazel/tools.idea.BUILD b/bazel/tools.idea.BUILD
index 7526e8d..39f3467 100755
--- a/bazel/tools.idea.BUILD
+++ b/bazel/tools.idea.BUILD
@@ -42,6 +42,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.annotations[module]",
"//tools:idea.util-rt[module]",
@@ -105,6 +106,7 @@
test_srcs = ["idea/java/compiler/forms-compiler/testSrc"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.instrumentation-util"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JDOM",
"//tools:idea.forms_rt[module]",
@@ -121,6 +123,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JUnit3",
"//tools/idea/.idea/libraries:JUnit4",
@@ -134,6 +137,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JUnit4",
"//tools:idea.java-runtime[module]",
@@ -146,6 +150,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:TestNG",
"//tools:idea.java-runtime[module]",
@@ -176,6 +181,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.maven-artifact-resolver-common"],
+ # do not sort: must match IML order
deps = [
"//tools:idea/plugins/maven/maven2-server-impl/lib/maven2/lib/maven-2.2.1-uber",
"//tools:idea.maven-artifact-resolver-common[module]",
@@ -189,6 +195,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.maven-artifact-resolver-common"],
+ # do not sort: must match IML order
deps = [
"//tools:idea/plugins/maven/maven30-server-impl/lib/maven3/lib/aether-api-1.13.1",
"//tools:idea/plugins/maven/maven30-server-impl/lib/maven3/lib/maven-core-3.0.5",
@@ -205,6 +212,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.maven-artifact-resolver-common"],
+ # do not sort: must match IML order
deps = [
"//tools:idea/plugins/maven/maven30-server-impl/lib/maven3/lib/maven-core-3.0.5",
"//tools:idea/plugins/maven/maven30-server-impl/lib/maven3/lib/plexus-component-annotations-1.5.5",
@@ -228,12 +236,14 @@
resources = ["idea/platform/util/resources"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:Trove4j",
"//tools:idea.annotations",
"//tools:idea.util-rt",
"//tools/idea/.idea/libraries:Snappy-Java",
],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:Mac",
"//tools/idea/.idea/libraries:JDOM",
@@ -258,6 +268,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.jps-model-api[module]",
@@ -271,6 +282,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/idea/.idea/libraries:JDOM"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.jps-model-api[module]",
@@ -284,6 +296,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools/idea/.idea/libraries:JDOM",
@@ -297,6 +310,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.jps-model-api[module]",
@@ -321,10 +335,12 @@
tags = ["managed"],
test_srcs = ["idea/platform/extensions/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:XStream",
"//tools/idea/.idea/libraries:JDOM",
],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:XStream",
"//tools/idea/.idea/libraries:JDOM",
@@ -342,12 +358,14 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.util",
"//tools:idea.extensions",
"//tools/idea/.idea/libraries:picocontainer",
"//tools:idea.platform-resources-en",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.extensions[module]",
@@ -365,10 +383,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.core-api",
"//tools:idea.jps-model-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.jps-model-api[module]",
@@ -382,6 +402,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.core-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.projectModel-api[module]",
@@ -395,6 +416,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.util[module]",
@@ -411,6 +433,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.editor-ui-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools/idea/.idea/libraries:JDOM",
@@ -427,6 +450,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.util",
"//tools:idea.extensions",
@@ -439,6 +463,7 @@
"//tools:idea.analysis-api",
"//tools:idea.editor-ui-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.extensions[module]",
@@ -470,6 +495,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools/idea/.idea/libraries:Netty",
@@ -505,6 +531,7 @@
tags = ["managed"],
test_srcs = ["idea/platform/lang-api/testSources"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.platform-api",
"//tools:idea.lvcs-api",
@@ -513,6 +540,7 @@
"//tools:idea.projectModel-api",
"//tools:idea.analysis-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.platform-api[module]",
"//tools:idea.lvcs-api[module]",
@@ -542,6 +570,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.projectModel-api[module]",
@@ -555,6 +584,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.xml-psi-api",
"//tools:idea.analysis-api",
@@ -563,6 +593,7 @@
"//tools:idea.extensions",
"//tools:idea.util",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.xml-psi-api[module]",
"//tools:idea.analysis-api[module]",
@@ -580,6 +611,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.xml-psi-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.xml-psi-api[module]",
@@ -593,11 +625,13 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.xml-psi-api",
"//tools:idea.xml-analysis-api",
"//tools:idea.xml-structure-view-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.lang-api[module]",
"//tools:idea.xml-psi-api[module]",
@@ -613,6 +647,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.xml-openapi"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.platform-api[module]",
"//tools:idea.xml-openapi[module]",
@@ -626,6 +661,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.editor-ui-api",
"//tools:idea.util",
@@ -635,6 +671,7 @@
"//tools:idea.platform-resources-en",
"//tools:idea.projectModel-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.editor-ui-api[module]",
"//tools:idea.util[module]",
@@ -655,6 +692,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.annotations[module]",
"//tools:idea.core-api[module]",
@@ -668,11 +706,13 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.platform-api",
"//tools:idea.vcs-api-core",
"//tools:idea.diff-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.platform-api[module]",
"//tools/idea/.idea/libraries:microba",
@@ -697,6 +737,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.analysis-api[module]",
"//tools:idea.java-psi-api[module]",
@@ -710,6 +751,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.java-psi-api[module]",
@@ -724,6 +766,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.core-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools/idea/.idea/libraries:picocontainer",
@@ -738,10 +781,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.projectModel-api",
"//tools:idea.jps-model-serialization",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.projectModel-api[module]",
"//tools:idea.core-impl[module]",
@@ -758,10 +803,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.indexing-api",
"//tools/idea/.idea/libraries:NanoXML",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-impl[module]",
"//tools:idea.indexing-api[module]",
@@ -776,12 +823,14 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.editor-ui-api",
"//tools:idea.util",
"//tools:idea.annotations",
"//tools:idea.core-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.editor-ui-api[module]",
"//tools:idea.util[module]",
@@ -799,11 +848,13 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.util",
"//tools/idea/.idea/libraries:JDOM",
"//tools:idea/plugins/maven/maven-server-api/lib/lucene-core-2.4.1",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools/idea/.idea/libraries:JDOM",
@@ -817,6 +868,7 @@
tags = ["managed"],
test_srcs = ["idea/platform/util/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:Groovy[test]",
"//tools:idea.util[module, test]",
@@ -826,7 +878,7 @@
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/idea/.idea/libraries:picocontainer[test]",
"//tools/idea/.idea/libraries:jna[test]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
],
)
@@ -844,10 +896,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.analysis-api",
"//tools:idea.core-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.analysis-api[module]",
"//tools:idea.core-api[module]",
@@ -867,6 +921,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.analysis-impl",
"//tools:idea.annotations",
@@ -876,6 +931,7 @@
"//tools:idea.projectModel-api",
"//tools:idea.projectModel-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.analysis-impl[module]",
"//tools:idea.annotations[module]",
@@ -889,6 +945,7 @@
iml_module(
name = "idea.java-psi-impl",
+ # do not sort: must match IML order
srcs = [
"idea/java/java-psi-impl/src",
"idea/java/java-psi-impl/gen",
@@ -896,10 +953,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.java-psi-api",
"//tools:idea.core-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.java-psi-api[module]",
"//tools:idea.core-impl[module]",
@@ -916,6 +975,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.structure-view-impl"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.structure-view-impl[module]",
"//tools:idea.java-psi-impl[module]",
@@ -928,6 +988,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.java-psi-api",
"//tools:idea.java-psi-impl",
@@ -936,6 +997,7 @@
"//tools:idea.projectModel-api",
"//tools:idea.java-indexing-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.java-psi-api[module]",
"//tools:idea.java-psi-impl[module]",
@@ -958,7 +1020,8 @@
)
iml_module(
- name = "idea.MM_RegExpSupport",
+ name = "idea.platform-impl_and_others",
+ # do not sort: must match IML order
srcs = [
"idea/RegExpSupport/src",
"idea/RegExpSupport/gen",
@@ -988,6 +1051,7 @@
"idea/xml/xml-structure-view-impl/src",
],
javacopts = ["-extra_checks:off"],
+ # do not sort: must match IML order
resources = [
"idea/xml/xml-analysis-impl/resources",
"idea/xml/xml-psi-impl/resources",
@@ -1007,6 +1071,7 @@
"idea/platform/testFramework/testSrc",
],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.xml-analysis-api",
"//tools:idea.xml-psi-api",
@@ -1035,6 +1100,7 @@
"//tools:idea.java-runtime",
"//tools/idea/.idea/libraries:Groovy",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.lang-api[module]",
"//tools/idea/.idea/libraries:JUnit4",
@@ -1122,8 +1188,9 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.platform-api[module]",
"//tools/idea/.idea/libraries:Jaxen",
],
@@ -1135,12 +1202,14 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
- "//tools:idea.MM_RegExpSupport",
+ "//tools:idea.platform-impl_and_others",
"//tools:idea.community-resources",
],
+ # do not sort: must match IML order
deps = [
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.community-resources[module]",
"//tools:idea.util[module]",
],
@@ -1152,6 +1221,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.util",
"//tools:idea.extensions",
@@ -1166,6 +1236,7 @@
"//tools:idea.java-indexing-api",
"//tools:idea.java-analysis-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools/idea/.idea/libraries:JUnit4[test]",
@@ -1182,7 +1253,7 @@
"//tools:idea.lang-api[module]",
"//tools:idea.vcs-api[module]",
"//tools/idea/.idea/libraries:XmlRPC",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.resources-en[module]",
"//tools:idea.java-psi-api[module]",
"//tools:idea.java-indexing-api[module]",
@@ -1197,6 +1268,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.xdebugger-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
"//tools:idea.resources[module]",
@@ -1220,10 +1292,12 @@
resources = ["idea/platform/external-system-api/resources"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.annotations",
"//tools:idea.external-system-rt",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.annotations[module]",
"//tools:idea.util[module]",
@@ -1242,6 +1316,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.jsp-base-openapi"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
"//tools:idea.util[module]",
@@ -1255,6 +1330,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.execution-openapi[module]",
"//tools:idea.jsp-openapi[module]",
@@ -1269,11 +1345,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jsp-openapi[module]",
"//tools:idea.xml-openapi[module]",
"//tools:idea.lang-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.openapi[module]",
"//tools/idea/.idea/libraries:Velocity",
],
@@ -1285,10 +1362,12 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.jsp-openapi",
"//tools:idea.openapi",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jsp-openapi[module]",
"//tools:idea.openapi[module]",
@@ -1302,12 +1381,13 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools:idea.util[module]",
"//tools/idea/.idea/libraries:JDOM",
"//tools/idea/.idea/libraries:Trove4j",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools/idea/.idea/libraries:Groovy",
"//tools:idea.platform-api[module]",
"//tools:idea.lang-api[module]",
@@ -1318,6 +1398,7 @@
iml_module(
name = "idea.properties-psi-api",
+ # do not sort: must match IML order
srcs = [
"idea/plugins/properties/properties-psi-api/src",
"idea/plugins/properties/properties-psi-api/gen",
@@ -1326,6 +1407,7 @@
resources = ["idea/plugins/properties/properties-psi-api/resources"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.core-api[module]",
"//tools:idea.editor-ui-api[module]",
@@ -1333,7 +1415,7 @@
"//tools:idea.indexing-api[module]",
"//tools:idea.xml-psi-api[module]",
"//tools:idea.projectModel-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.lang-api[module]",
"//tools:idea.boot[module]",
],
@@ -1346,13 +1428,14 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.properties-psi-api"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.properties-psi-api[module]",
"//tools:idea.core-impl[module]",
"//tools:idea.editor-ui-api[module]",
"//tools:idea.analysis-api[module]",
"//tools:idea.xml-psi-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.indexing-impl[module]",
"//tools:idea.structure-view-impl[module]",
"//tools:idea.analysis-impl[module]",
@@ -1365,9 +1448,10 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.platform-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.xdebugger-api[module]",
],
)
@@ -1379,12 +1463,14 @@
tags = ["managed"],
test_srcs = ["idea/platform/smRunner/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.testRunner",
"//tools/idea/.idea/libraries:tcServiceMessages",
],
+ # do not sort: must match IML order
deps = [
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.testRunner[module]",
"//tools:idea.xdebugger-api[module]",
"//tools/idea/.idea/libraries:tcServiceMessages",
@@ -1400,8 +1486,9 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.bootstrap[module]",
],
)
@@ -1412,10 +1499,11 @@
tags = ["managed"],
test_srcs = ["idea/jps/model-impl/testSrc"],
visibility = ["//visibility:public"],
- exports = ["//tools:idea.MM_RegExpSupport"],
+ exports = ["//tools:idea.platform-impl_and_others"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jps-model-impl[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
],
)
@@ -1426,6 +1514,7 @@
test_srcs = ["idea/jps/model-serialization/testSrc"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.jps-model-tests"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jps-model-serialization[module]",
"//tools:idea.jps-model-tests[module, test]",
@@ -1443,11 +1532,13 @@
tags = ["managed"],
test_srcs = ["idea/jps/jps-builders/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.util",
"//tools/idea/.idea/libraries:asm5",
"//tools/idea/.idea/libraries:protobuf",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.forms_rt[module]",
@@ -1463,7 +1554,7 @@
"//tools:idea.java-runtime[module]",
"//tools/idea/.idea/libraries:Log4J",
"//tools/idea/.idea/libraries:JUnit4[test]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools/idea/.idea/libraries:Eclipse[test]",
"//tools:idea.jps-model-api[module]",
"//tools:idea.jps-model-serialization[module]",
@@ -1481,6 +1572,7 @@
tags = ["managed"],
test_srcs = ["idea/plugins/ant/jps-plugin/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jps-model-api[module]",
"//tools:idea.jps-model-serialization[module]",
@@ -1498,6 +1590,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/idea/.idea/libraries:Ant"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.jps-builders[module]",
@@ -1516,6 +1609,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jps-model-api[module]",
"//tools:idea.jps-builders[module]",
@@ -1534,6 +1628,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/idea/.idea/libraries:Groovy"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:Groovy",
"//tools:idea.jps-builders[module]",
@@ -1551,6 +1646,7 @@
tags = ["managed"],
test_srcs = ["idea/plugins/maven/jps-plugin/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.jps-model-api[module]",
"//tools:idea.jps-model-impl[module]",
@@ -1564,6 +1660,7 @@
iml_module(
name = "idea.java-analysis-impl",
+ # do not sort: must match IML order
srcs = [
"idea/java/java-analysis-impl/src",
"idea/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src",
@@ -1571,6 +1668,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.analysis-impl",
"//tools:idea.java-indexing-impl",
@@ -1579,6 +1677,7 @@
"//tools:idea.java-analysis-api",
"//tools/idea/.idea/libraries:asm5",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.analysis-impl[module]",
"//tools:idea.java-indexing-impl[module]",
@@ -1586,13 +1685,14 @@
"//tools:idea.projectModel-impl[module]",
"//tools:idea.java-analysis-api[module]",
"//tools:idea.resources-en[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools/idea/.idea/libraries:asm5",
],
)
iml_module(
name = "idea.java-impl",
+ # do not sort: must match IML order
srcs = [
"idea/java/java-impl/src",
"idea/java/java-impl/gen",
@@ -1604,19 +1704,21 @@
resources = ["idea/plugins/generate-tostring/resources"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
- "//tools:idea.MM_RegExpSupport",
+ "//tools:idea.platform-impl_and_others",
"//tools:idea.java-psi-impl",
"//tools:idea.java-indexing-impl",
"//tools:idea.java-analysis-impl",
"//tools:idea.java-structure-view",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.openapi[module]",
"//tools/idea/.idea/libraries:Trove4j",
"//tools/idea/.idea/libraries:OroMatcher",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.java-runtime[module]",
"//tools:idea.compiler-openapi[module]",
"//tools:idea.jsp-openapi[module]",
@@ -1642,7 +1744,8 @@
)
iml_module(
- name = "idea.MM_idea-ui",
+ name = "idea.compiler-impl_and_others",
+ # do not sort: must match IML order
srcs = [
"idea/java/idea-ui/src",
"idea/platform/external-system-impl/src",
@@ -1659,23 +1762,25 @@
"idea/java/compiler/impl/testSrc",
],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.openapi",
"//tools:idea.util",
"//tools:idea.lang-api",
"//tools:idea.java-impl",
- "//tools:idea.MM_RegExpSupport",
+ "//tools:idea.platform-impl_and_others",
"//tools:idea.execution-openapi",
"//tools:idea.testRunner",
"//tools:idea.debugger-openapi",
"//tools:idea.compiler-openapi",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
"//tools:idea.compiler-openapi[module]",
"//tools:idea.java-impl[module]",
"//tools/idea/.idea/libraries:OroMatcher",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools/idea/.idea/libraries:Guava",
"//tools:idea.external-system-api[module]",
"//tools:idea.projectModel-impl[module]",
@@ -1716,17 +1821,18 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:asm5",
"//tools:idea.util[module]",
"//tools:idea.core-api[module]",
"//tools:idea.platform-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.lang-api[module]",
"//tools:idea.java-psi-api[module]",
"//tools:idea.execution-openapi[module]",
"//tools:idea.openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
],
)
@@ -1736,10 +1842,11 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
- "//tools:idea.MM_RegExpSupport[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.platform-impl_and_others[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools/idea/.idea/libraries:asm5",
"//tools:idea.platform-api[module]",
"//tools:idea.java-impl[module]",
@@ -1755,10 +1862,11 @@
test_srcs = ["idea/plugins/junit/test"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.smRunner"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.execution-openapi[module]",
"//tools:idea.openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.java-runtime[module]",
"//tools:idea.testRunner[module]",
"//tools/idea/.idea/libraries:JUnit3",
@@ -1775,6 +1883,7 @@
iml_module(
name = "idea.groovy-psi",
+ # do not sort: must match IML order
srcs = [
"idea/plugins/groovy/groovy-psi/src",
"idea/plugins/groovy/groovy-psi/gen",
@@ -1784,10 +1893,11 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/idea/.idea/libraries:Groovy"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:Groovy",
"//tools/idea/.idea/libraries:Guava",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.junit[module, test]",
"//tools:idea.java-indexing-api[module]",
"//tools:idea.java-psi-impl[module]",
@@ -1795,7 +1905,7 @@
"//tools:idea.core-impl[module]",
"//tools:idea.extensions[module]",
"//tools:idea.annotations[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.editor-ui-ex[module]",
"//tools:idea.java-analysis-impl[module]",
"//tools:idea.java-structure-view[module]",
@@ -1806,6 +1916,7 @@
iml_module(
name = "idea.eclipse",
+ # do not sort: must match IML order
srcs = [
"idea/plugins/eclipse/src",
"idea/plugins/eclipse/gen",
@@ -1815,12 +1926,13 @@
tags = ["managed"],
test_srcs = ["idea/plugins/eclipse/testSources"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JDOM",
"//tools:idea.openapi[module]",
"//tools:idea.bootstrap[module]",
"//tools/idea/.idea/libraries:JUnit4[test]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.compiler-openapi[module]",
"//tools:idea.annotations[module]",
"//tools:idea.java-impl[module]",
@@ -1835,15 +1947,17 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:Slf4j",
"//tools/idea/.idea/libraries:Gradle",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.external-system-rt[module]",
"//tools:idea.annotations[module]",
- "//tools:idea.MM_RegExpSupport[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.platform-impl_and_others[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools/idea/.idea/libraries:Slf4j",
"//tools/idea/.idea/libraries:Gradle",
"//tools/idea/.idea/libraries:GradleGuava",
@@ -1858,6 +1972,7 @@
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/idea/.idea/libraries:Gradle"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.annotations[module]",
"//tools:idea.external-system-rt[module]",
@@ -1877,19 +1992,21 @@
tags = ["managed"],
test_srcs = ["idea/plugins/properties/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.properties-psi-api",
"//tools:idea.properties-psi-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.lang-api[module]",
"//tools:idea.platform-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.annotations[module]",
"//tools:idea.resources[module, test]",
"//tools:idea.properties-psi-api[module]",
"//tools:idea.properties-psi-impl[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
],
)
@@ -1901,17 +2018,19 @@
tags = ["managed"],
test_srcs = ["idea/plugins/ant/tests/src"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:Ant",
- "//tools:idea.MM_RegExpSupport",
+ "//tools:idea.platform-impl_and_others",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/idea/.idea/libraries:Ant",
"//tools:idea.java-runtime[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.properties[module]",
"//tools:idea.execution-openapi[module]",
"//tools:idea.xml-openapi[module]",
@@ -1929,19 +2048,21 @@
tags = ["managed"],
test_srcs = ["idea/plugins/java-i18n/testSrc"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.properties",
"//tools:idea.java-impl",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.lang-api[module]",
"//tools:idea.openapi[module]",
"//tools:idea.properties[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.java-impl[module]",
"//tools:idea.jsp-base-openapi[module]",
"//tools:idea.jsp-openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.properties-psi-api[module]",
"//tools:idea.properties-psi-impl[module]",
],
@@ -1953,9 +2074,10 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.structuralsearch[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.openapi[module]",
"//tools:idea.java-impl[module]",
"//tools:idea.duplicates-analysis[module]",
@@ -1969,14 +2091,15 @@
tags = ["managed"],
test_srcs = ["idea/java/typeMigration/test"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.util[module]",
"//tools:idea.lang-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.openapi[module]",
"//tools:idea.structuralsearch[module]",
"//tools:idea.java-impl[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.structuralsearch-java[module]",
],
)
@@ -1989,9 +2112,10 @@
test_srcs = ["idea/plugins/testng/testSources"],
visibility = ["//visibility:public"],
exports = ["//tools:idea.smRunner"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.debugger-openapi[module]",
"//tools/idea/.idea/libraries:JUnit3[test]",
"//tools:idea.testRunner[module]",
@@ -2003,7 +2127,7 @@
"//tools:idea.jsp-openapi[module]",
"//tools/idea/.idea/libraries:TestNG",
"//tools:idea.java-indexing-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.smRunner[module]",
"//tools:idea.typeMigration[module]",
],
@@ -2019,6 +2143,7 @@
iml_module(
name = "idea.xpath",
+ # do not sort: must match IML order
srcs = [
"idea/plugins/xpath/xpath-lang/src",
"idea/plugins/xpath/xpath-view/src",
@@ -2028,10 +2153,11 @@
tags = ["managed"],
test_srcs = ["idea/plugins/xpath/xpath-lang/test"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.xml-openapi[module]",
"//tools:idea.lang-api[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.xslt-rt[module]",
"//tools:idea.annotations[module]",
"//tools/idea/.idea/libraries:Jaxen",
@@ -2047,8 +2173,9 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools/idea/.idea/libraries:asm5",
"//tools:idea.xpath[module]",
"//tools:idea.platform-api[module]",
@@ -2064,15 +2191,17 @@
tags = ["managed"],
test_srcs = ["idea/plugins/groovy/test"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:Groovy",
"//tools:idea.groovy-psi",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.openapi[module]",
"//tools:idea.debugger-openapi[module]",
"//tools:idea.groovy_rt[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.lang-api[module]",
"//tools:idea.properties[module]",
"//tools:idea.compiler-openapi[module]",
@@ -2086,7 +2215,7 @@
"//tools:idea.IntelliLang-java[module]",
"//tools:idea.IntelliLang-xml[module, test]",
"//tools:idea.jps-builders[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.junit[module, test]",
"//tools:idea.java-indexing-api[module]",
"//tools:idea.groovy-jps-plugin[module]",
@@ -2098,7 +2227,8 @@
)
iml_module(
- name = "idea.MM_maven2-server-impl",
+ name = "idea.maven_and_others",
+ # do not sort: must match IML order
srcs = [
"idea/plugins/maven/maven2-server-impl/src",
"idea/plugins/maven/src/main/java",
@@ -2111,17 +2241,19 @@
"idea/plugins/maven/src/test/java",
],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.maven-server-api",
"//tools:idea.openapi",
- "//tools:idea.MM_RegExpSupport",
+ "//tools:idea.platform-impl_and_others",
"//tools:idea.compiler-openapi",
- "//tools:idea.MM_idea-ui",
+ "//tools:idea.compiler-impl_and_others",
"//tools:idea.execution-openapi",
"//tools:idea.forms_rt",
"//tools/idea/.idea/libraries:JUnit4",
"//tools:idea.external-system-api",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.maven-server-api[module]",
"//tools:idea.util[module]",
@@ -2132,12 +2264,12 @@
"//tools/idea/.idea/libraries:commons-logging",
"//tools:idea/plugins/maven/maven2-server-impl/lib/commons-beanutils",
"//tools:idea.openapi[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.java-impl[module]",
"//tools:idea.IntelliLang-xml[module]",
"//tools:idea.properties[module]",
"//tools:idea.compiler-openapi[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.execution-openapi[module]",
"//tools:idea.forms_rt[module]",
"//tools/idea/.idea/libraries:jgoodies-forms",
@@ -2170,29 +2302,31 @@
resources = ["idea/plugins/gradle/resources"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:idea.external-system-api",
- "//tools:idea.MM_idea-ui",
+ "//tools:idea.compiler-impl_and_others",
"//tools:idea.gradle-tooling-extension-api",
"//tools/idea/.idea/libraries:Slf4j",
"//tools/idea/.idea/libraries:Gradle",
"//tools/idea/.idea/libraries:GradleGuava",
"//tools/idea/.idea/libraries:commons-io",
],
+ # do not sort: must match IML order
deps = [
"//tools:idea.external-system-api[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.gradle-tooling-extension-api[module]",
"//tools:idea.gradle-tooling-extension-impl[module]",
"//tools:idea.gradle-jps-plugin[module]",
"//tools:idea.lang-api[module]",
"//tools:idea.compiler-openapi[module]",
"//tools:idea.jetgroovy[module]",
- "//tools:idea.MM_RegExpSupport[module]",
+ "//tools:idea.platform-impl_and_others[module]",
"//tools:idea.execution-openapi[module]",
"//tools:idea.openapi[module]",
"//tools:idea.java-impl[module]",
- "//tools:idea.MM_maven2-server-impl[module]",
+ "//tools:idea.maven_and_others[module]",
"//tools:idea.junit[module]",
"//tools/idea/.idea/libraries:swingx",
"//tools/idea/.idea/libraries:Slf4j",
@@ -2215,10 +2349,11 @@
test_resources = ["idea/plugins/gradle/tooling-extension-impl/testData"],
test_srcs = ["idea/plugins/gradle/tooling-extension-impl/testSources"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.gradle-tooling-extension-impl[module]",
"//tools:idea.gradle[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
],
)
@@ -2231,11 +2366,12 @@
"idea/plugins/gradle/testSources",
],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:Mocks[test]",
"//tools/idea/.idea/libraries:JUnit4[test]",
- "//tools:idea.MM_RegExpSupport[module]",
- "//tools:idea.MM_idea-ui[module]",
+ "//tools:idea.platform-impl_and_others[module]",
+ "//tools:idea.compiler-impl_and_others[module]",
"//tools:idea.gradle[module, test]",
"//tools:idea.gradle-tooling-extension-tests[module, test]",
"//tools:idea.maven-server-api[module, test]",
@@ -3311,6 +3447,7 @@
javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.junit_rt[module]",
"//tools:idea.java-runtime[module]",
@@ -3453,10 +3590,12 @@
test_resources = ["swing-testing/fest-swing/src/test/resources"],
test_srcs = ["swing-testing/fest-swing/src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools:swing-testing/fest-swing/lib/fest-reflect-2.0-SNAPSHOT",
"//tools:swing-testing/fest-swing/lib/fest-util-1.3.0-SNAPSHOT",
],
+ # do not sort: must match IML order
deps = [
"//tools:swing-testing/fest-swing/lib/fest-reflect-2.0-SNAPSHOT",
"//tools:swing-testing/fest-swing/lib/fest-util-1.3.0-SNAPSHOT",
diff --git a/build-system/BUILD b/build-system/BUILD
index f0246cf..ff85c21 100644
--- a/build-system/BUILD
+++ b/build-system/BUILD
@@ -3,14 +3,15 @@
iml_module(
name = "studio.builder-test-api",
srcs = ["builder-test-api/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["builder-test-api/src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/base/ddmlib:studio.ddmlib",
"//tools/idea/.idea/libraries:guava-tools",
],
+ # do not sort: must match IML order
deps = [
"//tools/base/ddmlib:studio.ddmlib[module]",
"//tools/idea/.idea/libraries:guava-tools",
@@ -21,11 +22,11 @@
iml_module(
name = "studio.manifest-merger",
srcs = ["manifest-merger/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["manifest-merger/src/test/java"],
visibility = ["//visibility:public"],
exports = ["//tools/base/sdklib:studio.sdklib"],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/idea/.idea/libraries:gson",
@@ -43,8 +44,8 @@
visibility = ["//visibility:public"],
deps = [
"//tools/base/annotations",
- "//tools/base/ddmlib:tools.ddmlib",
"//tools/base/common:tools.common",
+ "//tools/base/ddmlib:tools.ddmlib",
"//tools/base/third_party:com.google.guava_guava",
],
)
diff --git a/build-system/builder-model/BUILD b/build-system/builder-model/BUILD
index b8d0130..4841c4f 100644
--- a/build-system/builder-model/BUILD
+++ b/build-system/builder-model/BUILD
@@ -1,3 +1,14 @@
+load("//tools/base/bazel:bazel.bzl", "iml_module")
+
+iml_module(
+ name = "studio.builder-model",
+ # do not sort: must match IML order
+ srcs = ["src/main/java"],
+ tags = ["managed"],
+ visibility = ["//visibility:public"],
+ deps = ["//tools/base/annotations:studio.android-annotations[module]"],
+)
+
java_library(
name = "builder-model",
srcs = glob([
diff --git a/build-system/builder-model/builder-model.iml b/build-system/builder-model/builder-model.iml
index 90fe45c..9d36831 100644
--- a/build-system/builder-model/builder-model.iml
+++ b/build-system/builder-model/builder-model.iml
@@ -10,6 +10,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="android-annotations" exported="" />
+ <orderEntry type="module" module-name="android-annotations" />
</component>
</module>
\ No newline at end of file
diff --git a/build-system/builder/BUILD b/build-system/builder/BUILD
index 91a9892..46b9b3e 100644
--- a/build-system/builder/BUILD
+++ b/build-system/builder/BUILD
@@ -33,10 +33,15 @@
java_test(
name = "tests",
srcs = glob(["src/test/java/**"]),
- javacopts = ["-extra_checks:off"],
+ data = [
+ "//prebuilts/studio/sdk:build-tools/20.0.0",
+ "//prebuilts/studio/sdk:build-tools/23.0.0",
+ "//prebuilts/studio/sdk:build-tools/latest",
+ "//prebuilts/studio/sdk:platforms/latest",
+ ],
jvm_flags = ["-Dtest.suite.jar=tests.jar"],
- test_class = "com.android.testutils.JarTestSuite",
resources = glob(["src/test/resources/**"]),
+ test_class = "com.android.testutils.JarTestSuite",
deps = [
":builder",
"//tools/base/annotations",
@@ -54,10 +59,4 @@
"//tools/base/third_party:org.bouncycastle_bcpkix-jdk15on",
"//tools/base/third_party:org.mockito_mockito-all",
],
- data = [
- "//prebuilts/studio/sdk:build-tools/20.0.0",
- "//prebuilts/studio/sdk:build-tools/23.0.0",
- "//prebuilts/studio/sdk:build-tools/latest",
- "//prebuilts/studio/sdk:platforms/latest",
- ]
)
diff --git a/build-system/builder/src/main/java/com/android/builder/core/AndroidBuilder.java b/build-system/builder/src/main/java/com/android/builder/core/AndroidBuilder.java
index 547f54d..f07d083 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/AndroidBuilder.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/AndroidBuilder.java
@@ -30,7 +30,6 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.builder.compiling.DependencyFileProcessor;
-import com.android.builder.files.FileModificationType;
import com.android.builder.files.NativeLibraryAbiPredicate;
import com.android.builder.files.RelativeFile;
import com.android.builder.files.RelativeFiles;
@@ -69,6 +68,7 @@
import com.android.ide.common.process.ProcessInfoBuilder;
import com.android.ide.common.process.ProcessOutputHandler;
import com.android.ide.common.process.ProcessResult;
+import com.android.ide.common.res2.FileStatus;
import com.android.ide.common.signing.CertificateInfo;
import com.android.ide.common.signing.KeystoreHelper;
import com.android.ide.common.signing.KeytoolException;
@@ -140,7 +140,7 @@
/**
* Minimal supported version of build tools.
*/
- public static final Revision MIN_BUILD_TOOLS_REV = new Revision(24, 0, 2);
+ public static final Revision MIN_BUILD_TOOLS_REV = new Revision(25, 0, 0);
/**
* API level for split APKs.
@@ -1687,33 +1687,33 @@
*/
FileUtils.deleteIfExists(outApkLocation);
- Map<RelativeFile, FileModificationType> javaResourceMods = Maps.newHashMap();
- Map<File, FileModificationType> javaResourceArchiveMods = Maps.newHashMap();
+ Map<RelativeFile, FileStatus> javaResourceMods = Maps.newHashMap();
+ Map<File, FileStatus> javaResourceArchiveMods = Maps.newHashMap();
for (File resourceLocation : javaResourcesLocations) {
if (resourceLocation.isFile()) {
- javaResourceArchiveMods.put(resourceLocation, FileModificationType.NEW);
+ javaResourceArchiveMods.put(resourceLocation, FileStatus.NEW);
} else {
Set<RelativeFile> files =
RelativeFiles.fromDirectory(resourceLocation, rf -> rf.getFile().isFile());
javaResourceMods.putAll(
- Maps.asMap(files, Functions.constant(FileModificationType.NEW)));
+ Maps.asMap(files, Functions.constant(FileStatus.NEW)));
}
}
NativeLibraryAbiPredicate nativeLibraryPredicate =
new NativeLibraryAbiPredicate(abiFilters, jniDebugBuild);
- Map<RelativeFile, FileModificationType> jniMods = Maps.newHashMap();
- Map<File, FileModificationType> jniArchiveMods = Maps.newHashMap();
+ Map<RelativeFile, FileStatus> jniMods = Maps.newHashMap();
+ Map<File, FileStatus> jniArchiveMods = Maps.newHashMap();
for (File jniLoc : jniLibsLocations) {
if (jniLoc.isFile()) {
- jniArchiveMods.put(jniLoc, FileModificationType.NEW);
+ jniArchiveMods.put(jniLoc, FileStatus.NEW);
} else {
Set<RelativeFile> files =
RelativeFiles.fromDirectory(
jniLoc,
RelativeFiles.fromPathPredicate(nativeLibraryPredicate));
jniMods.putAll(
- Maps.asMap(files, Functions.constant(FileModificationType.NEW)));
+ Maps.asMap(files, Functions.constant(FileStatus.NEW)));
}
}
@@ -1763,22 +1763,22 @@
}
// add the output of the java resource merger
- for (Map.Entry<RelativeFile, FileModificationType> resourceUpdate :
+ for (Map.Entry<RelativeFile, FileStatus> resourceUpdate :
javaResourceMods.entrySet()) {
packager.updateResource(resourceUpdate.getKey(), resourceUpdate.getValue());
}
- for (Map.Entry<File, FileModificationType> resourceArchiveUpdate :
+ for (Map.Entry<File, FileStatus> resourceArchiveUpdate :
javaResourceArchiveMods.entrySet()) {
packager.updateResourceArchive(resourceArchiveUpdate.getKey(),
resourceArchiveUpdate.getValue(), i -> false);
}
- for (Map.Entry<RelativeFile, FileModificationType> jniLibUpdates : jniMods.entrySet()) {
+ for (Map.Entry<RelativeFile, FileStatus> jniLibUpdates : jniMods.entrySet()) {
packager.updateResource(jniLibUpdates.getKey(), jniLibUpdates.getValue());
}
- for (Map.Entry<File, FileModificationType> resourceArchiveUpdate :
+ for (Map.Entry<File, FileStatus> resourceArchiveUpdate :
jniArchiveMods.entrySet()) {
packager.updateResourceArchive(resourceArchiveUpdate.getKey(),
resourceArchiveUpdate.getValue(), nativeLibraryPredicate.negate());
diff --git a/build-system/builder/src/main/java/com/android/builder/core/ApkInfoParser.java b/build-system/builder/src/main/java/com/android/builder/core/ApkInfoParser.java
index 394c490..0f9e915 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/ApkInfoParser.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/ApkInfoParser.java
@@ -25,7 +25,7 @@
import com.android.ide.common.process.ProcessExecutor;
import com.android.ide.common.process.ProcessInfoBuilder;
import com.android.utils.LineCollector;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.io.File;
import java.util.List;
@@ -79,7 +79,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("packageName", mPackageName)
.add("versionCode", mVersionCode)
.add("versionName", mVersionName)
diff --git a/build-system/builder/src/main/java/com/android/builder/core/BuildToolsServiceLoader.java b/build-system/builder/src/main/java/com/android/builder/core/BuildToolsServiceLoader.java
index d9abef5..b2bb06d 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/BuildToolsServiceLoader.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/BuildToolsServiceLoader.java
@@ -23,6 +23,7 @@
import com.android.sdklib.BuildToolInfo;
import com.android.utils.ILogger;
import com.google.common.base.Joiner;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -123,7 +124,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("serviceClass", serviceClass)
.add("classpath", Joiner.on(",").join(classpath))
.toString();
diff --git a/build-system/builder/src/main/java/com/android/builder/core/DefaultApiVersion.java b/build-system/builder/src/main/java/com/android/builder/core/DefaultApiVersion.java
index 85a4af4..7b8bf76 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/DefaultApiVersion.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/DefaultApiVersion.java
@@ -19,6 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.builder.model.ApiVersion;
+import com.android.sdklib.SdkVersionInfo;
/**
* Basic implementation of ApiVersion
@@ -54,6 +55,21 @@
return new DefaultApiVersion(1, null);
}
+ /** Checks if the specified api version is a preview version. */
+ public static boolean isPreview(@NonNull ApiVersion apiVersion) {
+ return apiVersion.getCodename() != null;
+ }
+
+ /** Checks if the specified api version is having legacy multidex support. */
+ public static boolean isLegacyMultidex(@NonNull ApiVersion apiVersion) {
+ if (isPreview(apiVersion)) {
+ //noinspection ConstantConditions - it is preview, so codename is not null
+ return SdkVersionInfo.getApiByPreviewName(apiVersion.getCodename(), true) < 21;
+ } else {
+ return apiVersion.getApiLevel() < 21;
+ }
+ }
+
@Override
public int getApiLevel() {
return mApiLevel;
diff --git a/build-system/builder/src/main/java/com/android/builder/core/DefaultBuildType.java b/build-system/builder/src/main/java/com/android/builder/core/DefaultBuildType.java
index 88c32ec..d79545c 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/DefaultBuildType.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/DefaultBuildType.java
@@ -21,6 +21,7 @@
import com.android.builder.internal.BaseConfigImpl;
import com.android.builder.model.BuildType;
import com.android.builder.model.SigningConfig;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
public class DefaultBuildType extends BaseConfigImpl implements BuildType {
@@ -287,7 +288,7 @@
@Override
@NonNull
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", mName)
.add("debuggable", mDebuggable)
.add("testCoverageEnabled", mTestCoverageEnabled)
diff --git a/build-system/builder/src/main/java/com/android/builder/core/DefaultProductFlavor.java b/build-system/builder/src/main/java/com/android/builder/core/DefaultProductFlavor.java
index 2508b98..8a6b7a6 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/DefaultProductFlavor.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/DefaultProductFlavor.java
@@ -24,6 +24,7 @@
import com.android.builder.model.ApiVersion;
import com.android.builder.model.ProductFlavor;
import com.android.builder.model.SigningConfig;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
@@ -760,7 +761,7 @@
@Override
@NonNull
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", mName)
.add("dimension", mDimension)
.add("minSdkVersion", mMinSdkVersion)
diff --git a/build-system/builder/src/main/java/com/android/builder/core/DefaultVectorDrawablesOptions.java b/build-system/builder/src/main/java/com/android/builder/core/DefaultVectorDrawablesOptions.java
index e35f35b..fc55695 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/DefaultVectorDrawablesOptions.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/DefaultVectorDrawablesOptions.java
@@ -19,7 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.builder.model.VectorDrawablesOptions;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import java.io.Serializable;
@@ -88,7 +88,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("mGeneratedDensities", mGeneratedDensities)
.add("mUseSupportLibrary", mUseSupportLibrary)
.toString();
diff --git a/build-system/builder/src/main/java/com/android/builder/core/JackProcessBuilder.java b/build-system/builder/src/main/java/com/android/builder/core/JackProcessBuilder.java
index 42a6d41..ec721ba 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/JackProcessBuilder.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/JackProcessBuilder.java
@@ -83,6 +83,8 @@
builder.addArgs("--verbose", "info");
}
+ builder.addArgs("-D", "jack.reporter=sdk");
+
builder.addArgs("-D", "jack.dex.debug.vars=" + options.isDebuggable());
if (!options.getClasspaths().isEmpty()) {
@@ -115,7 +117,7 @@
if (options.isMultiDex()) {
builder.addArgs("--multi-dex");
- if (options.getMinSdkVersion() < 21) {
+ if (DefaultApiVersion.isLegacyMultidex(options.getMinSdkVersion())) {
builder.addArgs("legacy");
} else {
builder.addArgs("native");
@@ -134,8 +136,9 @@
builder.addArgs("--incremental-folder", options.getIncrementalDir().getAbsolutePath());
}
- if (options.getMinSdkVersion() > 0) {
- builder.addArgs("-D", "jack.android.min-api-level=" + options.getMinSdkVersion());
+ if (!DefaultApiVersion.isPreview(options.getMinSdkVersion())) {
+ builder.addArgs(
+ "-D", "jack.android.min-api-level=" + options.getMinSdkVersion().getApiLevel());
}
if (!options.getAnnotationProcessorNames().isEmpty()) {
diff --git a/build-system/builder/src/main/java/com/android/builder/core/JackProcessOptions.java b/build-system/builder/src/main/java/com/android/builder/core/JackProcessOptions.java
index 6d05757..d918b1e 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/JackProcessOptions.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/JackProcessOptions.java
@@ -18,12 +18,12 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.repository.Revision;
+import com.android.builder.model.ApiVersion;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
-import com.google.common.collect.Range;
import java.io.File;
import java.util.Collection;
@@ -36,10 +36,6 @@
*/
public class JackProcessOptions {
- // Revisions with broken coverage plugin for in-process.
- public static final Range<Revision> COVERAGE_BROKEN =
- Range.singleton(new Revision(24, 0, 3));
-
// Class name of the code coverage plugin.
public static final String COVERAGE_PLUGIN_NAME = "com.android.jack.coverage.CodeCoverage";
@@ -63,7 +59,8 @@
@Nullable
private File mMappingFile = null;
private boolean mMultiDex;
- private int mMinSdkVersion;
+ @Nullable
+ private ApiVersion minSdkVersion;
@NonNull
private List<File> mResourceDirectories = ImmutableList.of();
@NonNull
@@ -207,12 +204,14 @@
mMultiDex = multiDex;
}
- public int getMinSdkVersion() {
- return mMinSdkVersion;
+ @NonNull
+ public ApiVersion getMinSdkVersion() {
+ Preconditions.checkNotNull(minSdkVersion, "Min sdk version not set.");
+ return minSdkVersion;
}
- public void setMinSdkVersion(int minSdkVersion) {
- mMinSdkVersion = minSdkVersion;
+ public void setMinSdkVersion(@NonNull ApiVersion minSdkVersion) {
+ this.minSdkVersion = minSdkVersion;
}
@NonNull
diff --git a/build-system/builder/src/main/java/com/android/builder/core/JackToolchain.java b/build-system/builder/src/main/java/com/android/builder/core/JackToolchain.java
index 4a18adc..22df111 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/JackToolchain.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/JackToolchain.java
@@ -20,11 +20,15 @@
import static com.google.common.base.Preconditions.checkState;
import com.android.annotations.NonNull;
+import com.android.ide.common.blame.Message;
+import com.android.ide.common.blame.ParsingProcessOutputHandler;
+import com.android.ide.common.blame.parser.JsonEncodedGradleMessageParser;
+import com.android.ide.common.blame.parser.ToolOutputParser;
import com.android.ide.common.process.JavaProcessExecutor;
import com.android.ide.common.process.JavaProcessInfo;
-import com.android.ide.common.process.LoggedProcessOutputHandler;
import com.android.ide.common.process.ProcessException;
import com.android.ide.common.process.ProcessInfoBuilder;
+import com.android.ide.common.process.ProcessOutput;
import com.android.ide.common.process.ProcessOutputHandler;
import com.android.ide.common.process.ProcessResult;
import com.android.jack.api.ConfigNotSupportedException;
@@ -43,19 +47,15 @@
import com.android.sdklib.BuildToolInfo;
import com.android.utils.FileUtils;
import com.android.utils.ILogger;
-import com.android.utils.SdkUtils;
-import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-
+import com.google.common.io.Closer;
import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.OutputStream;
+import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* Features exposed by the Jack toolchain. This is used for invoking Jack to convert inputs (source
@@ -82,10 +82,15 @@
@NonNull private BuildToolInfo buildToolInfo;
@NonNull private ILogger logger;
+ @NonNull private ErrorReporter errorReporter;
- public JackToolchain(@NonNull BuildToolInfo buildToolInfo, @NonNull ILogger logger) {
+ public JackToolchain(
+ @NonNull BuildToolInfo buildToolInfo,
+ @NonNull ILogger logger,
+ @NonNull ErrorReporter errorReporter) {
this.buildToolInfo = buildToolInfo;
this.logger = logger;
+ this.errorReporter = errorReporter;
}
/**
@@ -93,19 +98,19 @@
* using the Jack toolchain. It accepts source files, .jar or .jack as inputs, and produces
* .jack or .dex files as outputs.
*
- * @param options options for configuring Jack.
+ * @param options options for configuring Jack.
* @param javaProcessExecutor java executor to be used for out of process execution
- * @param isInProcess whether to run Jack in memory or spawn another Java process.
- * @throws ToolchainException if there is an exception related to running Jack toolchain
- * @throws ProcessException if a process in which the conversion is run fails
+ * @param isInProcess whether to run Jack in memory or spawn another Java process.
+ * @throws ToolchainException if there is an exception related to running Jack toolchain
+ * @throws ProcessException if a process in which the conversion is run fails
* @throws ClassNotFoundException if running in process, and unable to load the classes required
- * for the conversion
+ * for the conversion
*/
public void convert(
@NonNull JackProcessOptions options,
@NonNull JavaProcessExecutor javaProcessExecutor,
boolean isInProcess)
- throws ToolchainException, ProcessException, ClassNotFoundException {
+ throws ToolchainException, ProcessException, ClassNotFoundException, IOException {
// Create all the necessary directories if needed.
if (options.getDexOutputDirectory() != null) {
@@ -143,35 +148,50 @@
logger.warning(DefaultDexOptions.OPTIMIZE_WARNING);
}
- if (isInProcess) {
- convertUsingApis(options);
+ ParsingProcessOutputHandler parser =
+ new ParsingProcessOutputHandler(
+ new ToolOutputParser(
+ new JsonEncodedGradleMessageParser(), Message.Kind.ERROR, logger),
+ errorReporter);
+
+ if (!isInProcess) {
+ convertUsingCli(options, parser, javaProcessExecutor);
} else {
- convertUsingCli(options, new LoggedProcessOutputHandler(logger), javaProcessExecutor);
+ ProcessOutput output = parser.createOutput();
+ try (Closer c = Closer.create()) {
+ c.register(output);
+ convertUsingApis(options, output);
+ } finally {
+ parser.handleOutput(output);
+ }
}
}
/**
- * Converts inputs in process. This is using the Jack toolchain APIs. See the
- * {@link #convertUsingJackApis(JackProcessOptions)} and
- * {@link #convertUsingJillApis(JackProcessOptions)} for more details.
+ * Converts inputs in process. This is using the Jack toolchain APIs. See the {@link
+ * #convertUsingJackApis(JackProcessOptions, ProcessOutput)} and {@link
+ * #convertUsingJillApis(JackProcessOptions)} for more details.
*/
- private void convertUsingApis(@NonNull JackProcessOptions options)
- throws ToolchainException, ClassNotFoundException {
+ private void convertUsingApis(
+ @NonNull JackProcessOptions options, @NonNull ProcessOutput output)
+ throws ToolchainException, ClassNotFoundException, ProcessException {
+
if (options.getUseJill()) {
convertUsingJillApis(options);
} else {
- convertUsingJackApis(options);
+ convertUsingJackApis(options, output);
}
}
/**
* Convert the inputs using Jack in-process and its APIs. Inputs are sources, .jar files and
- * Jack library format (.jack) files. Depending on the options specified, this can produce
- * Jack library format or .dex output.
+ * Jack library format (.jack) files. Depending on the options specified, this can produce Jack
+ * library format or .dex output.
*
* @param options options how to run Jack
*/
- private void convertUsingJackApis(@NonNull JackProcessOptions options)
+ private void convertUsingJackApis(
+ @NonNull JackProcessOptions options, @NonNull ProcessOutput output)
throws ClassNotFoundException, ToolchainException {
BuildToolsServiceLoader.BuildToolServiceLoader buildToolServiceLoader =
@@ -201,16 +221,15 @@
config.setOutputJackFile(options.getOutputFile());
}
config.setImportedJackLibraryFiles(options.getImportFiles());
- if (options.getMinSdkVersion() > 0) {
- config.setAndroidMinApiLevel(options.getMinSdkVersion());
+ if (!DefaultApiVersion.isPreview(options.getMinSdkVersion())) {
+ config.setAndroidMinApiLevel(options.getMinSdkVersion().getApiLevel());
}
config.setProguardConfigFiles(options.getProguardFiles());
config.setJarJarConfigFiles(options.getJarJarRuleFiles());
if (options.isMultiDex()) {
- if (options.getMinSdkVersion()
- < BuildToolInfo.SDK_LEVEL_FOR_MULTIDEX_NATIVE_SUPPORT) {
+ if (DefaultApiVersion.isLegacyMultidex(options.getMinSdkVersion())) {
config.setMultiDexKind(MultiDexKind.LEGACY);
} else {
config.setMultiDexKind(MultiDexKind.NATIVE);
@@ -226,7 +245,7 @@
config.setProperty("jack.import.type.policy", "keep-first");
config.setProperty("jack.import.resource.policy", "keep-first");
- config.setReporter(ReporterKind.DEFAULT, outputStream);
+ config.setReporter(ReporterKind.SDK, output.getStandardOutput());
if (options.getSourceCompatibility() != null) {
config.setProperty(
@@ -299,23 +318,19 @@
"Something out of Jack control has happened: " + e.getMessage(), e);
} catch (CompilationException e) {
throw new ToolchainException("Jack compilation exception", e);
- } finally {
- // always show Jack output, it might contain useful warnings/errors
- processJackOutput(logger, outputStream);
}
}
/**
- * It performs the same operation like {@link #convertUsingApis(JackProcessOptions)},
- * but it performs the conversion in a separate process. See
- * {@link #convertUsingJackCli(JackProcessOptions, ProcessOutputHandler, JavaProcessExecutor)}
- * and
+ * It performs the same operation like {@link #convertUsingApis(JackProcessOptions,
+ * ProcessOutput)} , but it performs the conversion in a separate process. See {@link
+ * #convertUsingJackCli(JackProcessOptions, ProcessOutputHandler, JavaProcessExecutor)} and
* {@link #convertUsingJillCli(JackProcessOptions, ProcessOutputHandler, JavaProcessExecutor)}
* for details.
*
- * @param options options how to run Jack
+ * @param options options how to run Jack
* @param processOutputHandler handler for the output
- * @param javaProcessExecutor executor for running the process
+ * @param javaProcessExecutor executor for running the process
* @throws ProcessException in case that running the process fails
*/
private void convertUsingCli(
@@ -331,8 +346,8 @@
}
/**
- * It performs the same operation like {@link #convertUsingJackApis(JackProcessOptions)}
- * but it does that in a separate process.
+ * It performs the same operation like {@link #convertUsingJackApis(JackProcessOptions,
+ * ProcessOutput)} but it does that in a separate process.
*/
private void convertUsingJackCli(
@NonNull JackProcessOptions options,
@@ -346,46 +361,6 @@
.assertNormalExitValue();
}
- /** Parses the Jack compilation output. */
- private static void processJackOutput(
- @NonNull ILogger logger, @NonNull OutputStream outputStream) {
- Iterable<String> msgIterator =
- Splitter.on(SdkUtils.getLineSeparator()).split(outputStream.toString());
-
- for (String msg : msgIterator) {
- if (msg.startsWith("ERROR") || msg.startsWith("WARNING")) {
- // (ERROR|WARNING):file:position in file:message
- // TODO add JackParser to process the output; it will be used on studio side as well
- Pattern pattern = Pattern.compile("^(ERROR|WARNING):\\s*(.*):(\\d+):\\s*(.*)");
- Matcher matcher = pattern.matcher(msg);
- if (matcher.matches()) {
- String msgType = matcher.group(1);
- String content = matcher.group(4);
-
- if (msgType.equals("ERROR")) {
- logger.error(
- null,
- matcher.group(2) + ":" + matcher.group(3) + ": error: " + content);
- } else if (msgType.equals("WARNING")) {
- logger.warning(
- matcher.group(2)
- + ":"
- + matcher.group(3)
- + ": warning: "
- + content);
- }
- } else if (msg.startsWith("ERROR")) {
- logger.error(null, msg);
- } else {
- // starts with WARNING
- logger.warning(msg);
- }
- } else {
- logger.info(msg);
- }
- }
- }
-
private Api04Config createJackConfig(
@NonNull JackProvider jackProvider, @NonNull BuildToolInfo.JackVersion apiVersion)
throws ConfigNotSupportedException {
diff --git a/build-system/builder/src/main/java/com/android/builder/core/VariantConfiguration.java b/build-system/builder/src/main/java/com/android/builder/core/VariantConfiguration.java
index 12cc290..3718c7f 100644
--- a/build-system/builder/src/main/java/com/android/builder/core/VariantConfiguration.java
+++ b/build-system/builder/src/main/java/com/android/builder/core/VariantConfiguration.java
@@ -932,7 +932,7 @@
return runner;
}
- if (isMultiDexEnabled() && isLegacyMultiDexMode()) {
+ if (isLegacyMultiDexMode()) {
return MULTIDEX_TEST_RUNNER;
}
@@ -2316,7 +2316,16 @@
}
public boolean isLegacyMultiDexMode() {
- return isMultiDexEnabled() && getMinSdkVersion().getApiLevel() < 21;
+ if (!isMultiDexEnabled()) {
+ return false;
+ }
+
+ ApiVersion minSdk = getMinSdkVersion();
+ if (minSdk.getCodename() == null) {
+ return minSdk.getApiLevel() < 21;
+ } else {
+ return SdkVersionInfo.getApiByPreviewName(minSdk.getCodename(), true) < 21;
+ }
}
/**
diff --git a/build-system/builder/src/main/java/com/android/builder/dependency/AbstractBundleDependency.java b/build-system/builder/src/main/java/com/android/builder/dependency/AbstractBundleDependency.java
index 895133b..e0a0aa2 100644
--- a/build-system/builder/src/main/java/com/android/builder/dependency/AbstractBundleDependency.java
+++ b/build-system/builder/src/main/java/com/android/builder/dependency/AbstractBundleDependency.java
@@ -26,6 +26,7 @@
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.JavaLibrary;
import com.android.builder.model.MavenCoordinates;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -209,7 +210,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("mBundle", mBundle)
.add("mBundleFolder", mBundleFolder)
.add("mLibraryDependencies", mLibraryDependencies)
diff --git a/build-system/builder/src/main/java/com/android/builder/dependency/AtomDependency.java b/build-system/builder/src/main/java/com/android/builder/dependency/AtomDependency.java
index cc3fe74..44113f8 100644
--- a/build-system/builder/src/main/java/com/android/builder/dependency/AtomDependency.java
+++ b/build-system/builder/src/main/java/com/android/builder/dependency/AtomDependency.java
@@ -30,6 +30,7 @@
import com.android.builder.model.AndroidAtom;
import com.android.builder.model.MavenCoordinates;
import com.android.utils.FileUtils;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -160,7 +161,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("mAtomDependencies", mAtomDependencies)
.add("mAtomName", mAtomName)
.add("super", super.toString())
diff --git a/build-system/builder/src/main/java/com/android/builder/dependency/DependencyContainerImpl.java b/build-system/builder/src/main/java/com/android/builder/dependency/DependencyContainerImpl.java
index 86c3f9b..ac6dd0d 100644
--- a/build-system/builder/src/main/java/com/android/builder/dependency/DependencyContainerImpl.java
+++ b/build-system/builder/src/main/java/com/android/builder/dependency/DependencyContainerImpl.java
@@ -22,7 +22,7 @@
import com.android.builder.model.AndroidAtom;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.JavaLibrary;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -299,7 +299,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("mLibraryDependencies", mLibraryDependencies)
.add("mAtomDependencies", mAtomDependencies)
.add("mJavaDependencies", mJavaDependencies)
diff --git a/build-system/builder/src/main/java/com/android/builder/dependency/JarDependency.java b/build-system/builder/src/main/java/com/android/builder/dependency/JarDependency.java
index 4c754f2..aabd280 100644
--- a/build-system/builder/src/main/java/com/android/builder/dependency/JarDependency.java
+++ b/build-system/builder/src/main/java/com/android/builder/dependency/JarDependency.java
@@ -20,13 +20,13 @@
import com.android.annotations.Nullable;
import com.android.builder.model.JavaLibrary;
import com.android.builder.model.MavenCoordinates;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* Represents a Jar dependency. This could be the output of a Java project.
@@ -164,7 +164,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("mJarFile", mJarFile)
.add("mIsProvided", mIsProvided)
.add("mProjectPath", mProjectPath)
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/aapt/v1/AaptV1.java b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v1/AaptV1.java
index cea6f5e..e8ca1f1 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/aapt/v1/AaptV1.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v1/AaptV1.java
@@ -45,7 +45,6 @@
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
-
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -58,7 +57,6 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-
import javax.imageio.ImageIO;
/**
@@ -212,7 +210,7 @@
File manifestFile = config.getManifestFile();
Preconditions.checkNotNull(manifestFile);
- builder.addArgs("-M", manifestFile.getAbsolutePath());
+ builder.addArgs("-M", FileUtils.toExportableSystemDependentPath(manifestFile));
if (config.getResourceDir() != null) {
builder.addArgs("-S", config.getResourceDir().getAbsolutePath());
@@ -221,7 +219,8 @@
// outputs
if (config.getSourceOutputDir() != null) {
builder.addArgs("-m");
- builder.addArgs("-J", config.getSourceOutputDir().getAbsolutePath());
+ builder.addArgs(
+ "-J", FileUtils.toExportableSystemDependentPath(config.getSourceOutputDir()));
}
if (config.getResourceOutputApk() != null) {
@@ -229,11 +228,16 @@
}
if (config.getProguardOutputFile() != null) {
- builder.addArgs("-G", config.getProguardOutputFile().getAbsolutePath());
+ builder.addArgs(
+ "-G",
+ FileUtils.toExportableSystemDependentPath(config.getProguardOutputFile()));
}
if (config.getMainDexListProguardOutputFile() != null) {
- builder.addArgs("-D", config.getMainDexListProguardOutputFile().getAbsolutePath());
+ builder.addArgs(
+ "-D",
+ FileUtils.toExportableSystemDependentPath(
+ config.getMainDexListProguardOutputFile()));
}
if (config.getSplits() != null) {
@@ -346,8 +350,9 @@
if (config.getSymbolOutputDir() != null && (config.getVariantType() == VariantType.LIBRARY
|| !config.getLibraries().isEmpty())) {
- builder.addArgs("--output-text-symbols",
- config.getSymbolOutputDir().getAbsolutePath());
+ builder.addArgs(
+ "--output-text-symbols",
+ FileUtils.toExportableSystemDependentPath(config.getSymbolOutputDir()));
}
// All the vector XML files that are outside of an "-anydpi-v21" directory were left there
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/AaptV2CommandBuilder.java b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/AaptV2CommandBuilder.java
new file mode 100644
index 0000000..f15c9d6
--- /dev/null
+++ b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/AaptV2CommandBuilder.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.builder.internal.aapt.v2;
+
+import com.android.annotations.NonNull;
+import com.android.builder.core.VariantType;
+import com.android.builder.internal.aapt.AaptException;
+import com.android.builder.internal.aapt.AaptPackageConfig;
+import com.android.builder.internal.aapt.AaptUtils;
+import com.android.builder.model.AaptOptions;
+import com.android.sdklib.BuildToolInfo;
+import com.android.sdklib.IAndroidTarget;
+import com.android.utils.ILogger;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Builds the command lines for use with {@code aapt2}.
+ */
+public final class AaptV2CommandBuilder {
+
+ /**
+ * Utility class, no constructor.
+ */
+ private AaptV2CommandBuilder() {}
+
+ /**
+ * Creates the command line used to compile a resource.
+ * See {@link com.android.builder.internal.aapt.Aapt#compile(File, File)}.
+ *
+ * @param file see above
+ * @param output see above
+ * @return the command line arguments
+ */
+ public static ImmutableList<String> makeCompile(@NonNull File file, @NonNull File output) {
+ return ImmutableList.of(
+ "compile",
+ "-o",
+ output.getAbsolutePath(),
+ file.getAbsolutePath());
+ }
+
+ /**
+ * Creates the command line used to link the package.
+ * See {@link com.android.builder.internal.aapt.Aapt#link(AaptPackageConfig)}.
+ *
+ * @param config see above
+ * @param intermediateDir a directory for intermediate files
+ * @param buildToolInfo build tools
+ * @return the command line arguments
+ * @throws AaptException failed to build the command line
+ */
+ public static ImmutableList<String> makeLink(
+ @NonNull AaptPackageConfig config,
+ @NonNull File intermediateDir,
+ @NonNull BuildToolInfo buildToolInfo) throws AaptException {
+ ImmutableList.Builder<String> builder = ImmutableList.builder();
+
+ builder.add("link");
+
+ if (config.isVerbose()) {
+ builder.add("-v");
+ }
+
+ File stableResourceIdsFile = new File(intermediateDir, "stable-resource-ids.txt");
+ // TODO: For now, we ignore this file, but as soon as aapt2 supports it, we'll use it.
+
+ // inputs
+ IAndroidTarget target = config.getAndroidTarget();
+ Preconditions.checkNotNull(target);
+ builder.add("-I", target.getPath(IAndroidTarget.ANDROID_JAR));
+
+ File manifestFile = config.getManifestFile();
+ Preconditions.checkNotNull(manifestFile);
+ builder.add("--manifest", manifestFile.getAbsolutePath());
+
+ if (config.getResourceDir() != null) {
+ // TODO: Fix when aapt 2 supports -R directories (http://b.android.com/209331)
+ // builder.addArgs("-R", config.getResourceDir().getAbsolutePath());
+ try {
+ Files.walk(config.getResourceDir().toPath())
+ .filter(Files::isRegularFile)
+ .forEach((p) -> builder.add("-R", p.toString()));
+ } catch (IOException e) {
+ throw new AaptException("Failed to walk path " + config.getResourceDir());
+ }
+ }
+
+ builder.add("--auto-add-overlay");
+
+ // outputs
+ if (config.getSourceOutputDir() != null) {
+ builder.add("--java", config.getSourceOutputDir().getAbsolutePath());
+ }
+
+ if (config.getResourceOutputApk() != null) {
+ builder.add("-o", config.getResourceOutputApk().getAbsolutePath());
+ } else {
+ // FIXME: Fix when aapt 2 support not providing -o (http://b.android.com/210026)
+ try {
+ File tmpOutput = File.createTempFile("aapt-", "-out");
+ tmpOutput.deleteOnExit();
+ builder.add("-o", tmpOutput.getAbsolutePath());
+ } catch (IOException e) {
+ throw new AaptException("No output apk defined and failed to create tmp file", e);
+ }
+ }
+
+ if (config.getProguardOutputFile()!= null) {
+ builder.add("--proguard", config.getProguardOutputFile().getAbsolutePath());
+ }
+
+ if (config.getSplits() != null) {
+ for (String split : config.getSplits()) {
+ // FIXME: Fix when --split is supported (http://b.android.com/212372)
+// builder.addArgs("--split", split);
+ }
+ }
+
+ // options controlled by build variants
+
+ if (config.isDebuggable()) {
+// builder.addArgs("--debug-mode");
+ }
+
+ ILogger logger = config.getLogger();
+ Preconditions.checkNotNull(logger);
+ if (config.getVariantType() != VariantType.ANDROID_TEST
+ && config.getCustomPackageForR() != null) {
+ builder.add("--custom-package", config.getCustomPackageForR());
+ }
+
+ if (config.isPseudoLocalize()) {
+ Preconditions.checkState(buildToolInfo.getRevision().getMajor() >= 21);
+// builder.addArgs("--pseudo-localize");
+ }
+
+ // bundle specific options
+ boolean generateFinalIds = true;
+ if (config.getVariantType() == VariantType.LIBRARY) {
+ generateFinalIds = false;
+ } else if (config.getVariantType() == VariantType.ATOM && config.getBaseFeature() != null) {
+ generateFinalIds = false;
+ }
+ if (!generateFinalIds) {
+ builder.add("--static-lib"); // --non-constant-id
+ }
+
+ // AAPT options
+ AaptOptions options = config.getOptions();
+ Preconditions.checkNotNull(options);
+ String ignoreAssets = options.getIgnoreAssets();
+ if (ignoreAssets != null) {
+// builder.addArgs("--ignore-assets", ignoreAssets);
+ }
+
+ if (config.getOptions().getFailOnMissingConfigEntry()) {
+ Preconditions.checkState(buildToolInfo.getRevision().getMajor() > 20);
+// builder.addArgs("--error-on-missing-config-entry");
+ }
+
+ /*
+ * Never compress apks.
+ */
+// builder.addArgs("-0", "apk");
+
+ /*
+ * Add custom no-compress extensions.
+ */
+ Collection<String> noCompressList = config.getOptions().getNoCompress();
+ if (noCompressList != null) {
+ for (String noCompress : noCompressList) {
+ builder.add("-0", noCompress);
+ }
+ }
+ List<String> additionalParameters = config.getOptions().getAdditionalParameters();
+ if (additionalParameters != null) {
+ builder.addAll(additionalParameters);
+ }
+
+ List<String> resourceConfigs = new ArrayList<String>();
+ resourceConfigs.addAll(config.getResourceConfigs());
+
+ /*
+ * Split the density and language resource configs, since starting in 21, the
+ * density resource configs should be passed with --preferred-density to ensure packaging
+ * of scalable resources when no resource for the preferred density is present.
+ */
+ Collection<String> otherResourceConfigs;
+ String preferredDensity = null;
+ Collection<String> densityResourceConfigs = Lists.newArrayList(
+ AaptUtils.getDensityResConfigs(resourceConfigs));
+ otherResourceConfigs = Lists.newArrayList(AaptUtils.getNonDensityResConfigs(
+ resourceConfigs));
+ preferredDensity = config.getPreferredDensity();
+
+ if (preferredDensity != null && !densityResourceConfigs.isEmpty()) {
+ throw new AaptException(
+ String.format("When using splits in tools 21 and above, "
+ + "resConfigs should not contain any densities. Right now, it "
+ + "contains \"%1$s\"\nSuggestion: remove these from resConfigs "
+ + "from build.gradle",
+ Joiner.on("\",\"").join(densityResourceConfigs)));
+ }
+
+ if (densityResourceConfigs.size() > 1) {
+ throw new AaptException("Cannot filter assets for multiple densities using "
+ + "SDK build tools 21 or later. Consider using apk splits instead.");
+ }
+
+ if (preferredDensity == null && densityResourceConfigs.size() == 1) {
+ preferredDensity = Iterables.getOnlyElement(densityResourceConfigs);
+ }
+
+ if (!otherResourceConfigs.isEmpty()) {
+ Joiner joiner = Joiner.on(',');
+ builder.add("-c", joiner.join(otherResourceConfigs));
+ }
+
+ if (preferredDensity != null) {
+ builder.add("--preferred-density", preferredDensity);
+ }
+
+ if (config.getSymbolOutputDir() != null && (config.getVariantType() == VariantType.LIBRARY
+ || !config.getLibraries().isEmpty())) {
+// builder.addArgs("--output-text-symbols",
+// config.getSymbolOutputDir().getAbsolutePath());
+ }
+
+ builder.add("--no-version-vectors");
+
+ return builder.build();
+ }
+}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/OutOfProcessAaptV2.java b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/OutOfProcessAaptV2.java
index d7cbcaf..2adc715 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/OutOfProcessAaptV2.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/aapt/v2/OutOfProcessAaptV2.java
@@ -18,31 +18,19 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.builder.core.VariantType;
import com.android.builder.internal.aapt.AaptException;
import com.android.builder.internal.aapt.AaptPackageConfig;
-import com.android.builder.internal.aapt.AaptUtils;
import com.android.builder.internal.aapt.AbstractProcessExecutionAapt;
-import com.android.builder.model.AaptOptions;
import com.android.builder.png.QueuedCruncher;
import com.android.ide.common.process.ProcessExecutor;
import com.android.ide.common.process.ProcessInfoBuilder;
import com.android.ide.common.process.ProcessOutputHandler;
import com.android.repository.Revision;
import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
import com.android.utils.ILogger;
-import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
/**
* Implementation of {@link com.android.builder.internal.aapt.Aapt} that uses out-of-process
@@ -103,10 +91,7 @@
return new CompileInvocation(
new ProcessInfoBuilder()
.setExecutable(getAapt2ExecutablePath())
- .addArgs("compile")
- .addArgs("-o")
- .addArgs(output.getAbsolutePath())
- .addArgs(file.getAbsolutePath()),
+ .addArgs(AaptV2CommandBuilder.makeCompile(file, output)),
new File(output, Aapt2RenamingConventions.compilationRename(file)));
}
@@ -117,178 +102,7 @@
ProcessInfoBuilder builder = new ProcessInfoBuilder();
builder.setExecutable(getAapt2ExecutablePath());
- builder.addArgs("link");
-
- if (config.isVerbose()) {
- builder.addArgs("-v");
- }
-
- File stableResourceIdsFile = new File(mIntermediateDir, "stable-resource-ids.txt");
- // TODO: For now, we ignore this file, but as soon as aapt2 supports it, we'll use it.
-
- // inputs
- IAndroidTarget target = config.getAndroidTarget();
- Preconditions.checkNotNull(target);
- builder.addArgs("-I", target.getPath(IAndroidTarget.ANDROID_JAR));
-
- File manifestFile = config.getManifestFile();
- Preconditions.checkNotNull(manifestFile);
- builder.addArgs("--manifest", manifestFile.getAbsolutePath());
-
- if (config.getResourceDir() != null) {
- // TODO: Fix when aapt 2 supports -R directories (http://b.android.com/209331)
- // builder.addArgs("-R", config.getResourceDir().getAbsolutePath());
- try {
- Files.walk(config.getResourceDir().toPath())
- .filter(Files::isRegularFile)
- .forEach((p) -> builder.addArgs("-R", p.toString()));
- } catch (IOException e) {
- throw new AaptException("Failed to walk path " + config.getResourceDir());
- }
- }
-
- builder.addArgs("--auto-add-overlay");
-
- // outputs
- if (config.getSourceOutputDir() != null) {
- builder.addArgs("--java", config.getSourceOutputDir().getAbsolutePath());
- }
-
- if (config.getResourceOutputApk() != null) {
- builder.addArgs("-o", config.getResourceOutputApk().getAbsolutePath());
- } else {
- // FIXME: Fix when aapt 2 support not providing -o (http://b.android.com/210026)
- try {
- File tmpOutput = File.createTempFile("aapt-", "-out");
- tmpOutput.deleteOnExit();
- builder.addArgs("-o", tmpOutput.getAbsolutePath());
- } catch (IOException e) {
- throw new AaptException("No output apk defined and failed to create tmp file", e);
- }
- }
-
- if (config.getProguardOutputFile()!= null) {
- builder.addArgs("--proguard", config.getProguardOutputFile().getAbsolutePath());
- }
-
- if (config.getSplits() != null) {
- for (String split : config.getSplits()) {
- // FIXME: Fix when --split is supported (http://b.android.com/212372)
-// builder.addArgs("--split", split);
- }
- }
-
- // options controlled by build variants
-
- if (config.isDebuggable()) {
-// builder.addArgs("--debug-mode");
- }
-
- ILogger logger = config.getLogger();
- Preconditions.checkNotNull(logger);
- if (config.getVariantType() != VariantType.ANDROID_TEST
- && config.getCustomPackageForR() != null) {
- builder.addArgs("--custom-package", config.getCustomPackageForR());
- }
-
- if (config.isPseudoLocalize()) {
- Preconditions.checkState(mBuildToolInfo.getRevision().getMajor() >= 21);
-// builder.addArgs("--pseudo-localize");
- }
-
- // bundle specific options
- boolean generateFinalIds = true;
- if (config.getVariantType() == VariantType.LIBRARY) {
- generateFinalIds = false;
- } else if (config.getVariantType() == VariantType.ATOM && config.getBaseFeature() != null) {
- generateFinalIds = false;
- }
- if (!generateFinalIds) {
- builder.addArgs("--static-lib"); // --non-constant-id
- }
-
- // AAPT options
- AaptOptions options = config.getOptions();
- Preconditions.checkNotNull(options);
- String ignoreAssets = options.getIgnoreAssets();
- if (ignoreAssets != null) {
-// builder.addArgs("--ignore-assets", ignoreAssets);
- }
-
- if (config.getOptions().getFailOnMissingConfigEntry()) {
- Preconditions.checkState(mBuildToolInfo.getRevision().getMajor() > 20);
-// builder.addArgs("--error-on-missing-config-entry");
- }
-
- /*
- * Never compress apks.
- */
-// builder.addArgs("-0", "apk");
-
- /*
- * Add custom no-compress extensions.
- */
- Collection<String> noCompressList = config.getOptions().getNoCompress();
- if (noCompressList != null) {
- for (String noCompress : noCompressList) {
- builder.addArgs("-0", noCompress);
- }
- }
- List<String> additionalParameters = config.getOptions().getAdditionalParameters();
- if (additionalParameters != null) {
- builder.addArgs(additionalParameters);
- }
-
- List<String> resourceConfigs = new ArrayList<String>();
- resourceConfigs.addAll(config.getResourceConfigs());
-
- /*
- * Split the density and language resource configs, since starting in 21, the
- * density resource configs should be passed with --preferred-density to ensure packaging
- * of scalable resources when no resource for the preferred density is present.
- */
- Collection<String> otherResourceConfigs;
- String preferredDensity = null;
- Collection<String> densityResourceConfigs = Lists.newArrayList(
- AaptUtils.getDensityResConfigs(resourceConfigs));
- otherResourceConfigs = Lists.newArrayList(AaptUtils.getNonDensityResConfigs(
- resourceConfigs));
- preferredDensity = config.getPreferredDensity();
-
- if (preferredDensity != null && !densityResourceConfigs.isEmpty()) {
- throw new AaptException(
- String.format("When using splits in tools 21 and above, "
- + "resConfigs should not contain any densities. Right now, it "
- + "contains \"%1$s\"\nSuggestion: remove these from resConfigs "
- + "from build.gradle",
- Joiner.on("\",\"").join(densityResourceConfigs)));
- }
-
- if (densityResourceConfigs.size() > 1) {
- throw new AaptException("Cannot filter assets for multiple densities using "
- + "SDK build tools 21 or later. Consider using apk splits instead.");
- }
-
- if (preferredDensity == null && densityResourceConfigs.size() == 1) {
- preferredDensity = Iterables.getOnlyElement(densityResourceConfigs);
- }
-
- if (!otherResourceConfigs.isEmpty()) {
- Joiner joiner = Joiner.on(',');
- builder.addArgs("-c", joiner.join(otherResourceConfigs));
- }
-
- if (preferredDensity != null) {
- builder.addArgs("--preferred-density", preferredDensity);
- }
-
- if (config.getSymbolOutputDir() != null && (config.getVariantType() == VariantType.LIBRARY
- || !config.getLibraries().isEmpty())) {
-// builder.addArgs("--output-text-symbols",
-// config.getSymbolOutputDir().getAbsolutePath());
- }
-
- builder.addArgs("--no-version-vectors");
+ builder.addArgs(AaptV2CommandBuilder.makeLink(config, mIntermediateDir, mBuildToolInfo));
return builder;
}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/compiler/AidlProcessor.java b/build-system/builder/src/main/java/com/android/builder/internal/compiler/AidlProcessor.java
index d66048c..b2c8f56 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/compiler/AidlProcessor.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/compiler/AidlProcessor.java
@@ -28,7 +28,6 @@
import com.android.repository.io.FileOpUtils;
import com.android.utils.FileUtils;
import com.google.common.io.Files;
-
import java.io.File;
import java.io.IOException;
import java.util.Collection;
@@ -111,8 +110,10 @@
boolean isParcelable = data.getOutputFiles().isEmpty();
- String relative = FileOpUtils
- .makeRelative(sourceFolder, sourceFile, FileOpUtils.create());
+ String relative =
+ FileUtils.toSystemIndependentPath(
+ FileOpUtils.makeRelative(
+ sourceFolder, sourceFile, FileOpUtils.create()));
boolean isWhiteListed =
mPackageWhiteList != null && mPackageWhiteList.contains(relative);
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/compiler/DexKey.java b/build-system/builder/src/main/java/com/android/builder/internal/compiler/DexKey.java
index 0f51bb2..461cf20 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/compiler/DexKey.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/compiler/DexKey.java
@@ -18,6 +18,7 @@
import com.android.annotations.NonNull;
import com.android.repository.Revision;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.w3c.dom.Attr;
@@ -89,7 +90,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("buildTools", getBuildToolsRevision())
.add("sourceFile", getSourceFile())
.add("mJumboMode", mJumboMode)
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/compiler/DxDexKey.java b/build-system/builder/src/main/java/com/android/builder/internal/compiler/DxDexKey.java
index 91cdd18..6b1f046 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/compiler/DxDexKey.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/compiler/DxDexKey.java
@@ -20,6 +20,7 @@
import com.android.annotations.Nullable;
import com.android.repository.Revision;
import com.google.common.base.Joiner;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
@@ -162,7 +163,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("dexKey", super.toString())
.add("mAdditionalParameters", mAdditionalParameters)
.add("mIsMultiDex", mIsMultiDex)
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackConversionCache.java b/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackConversionCache.java
index d02e219..01959f6 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackConversionCache.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackConversionCache.java
@@ -21,11 +21,6 @@
import com.android.builder.core.JackProcessOptions;
import com.android.builder.core.JackToolchain;
import com.android.ide.common.process.ProcessException;
-import com.android.jack.api.ConfigNotSupportedException;
-import com.android.jack.api.v01.CompilationException;
-import com.android.jack.api.v01.ConfigurationException;
-import com.android.jack.api.v01.UnrecoverableException;
-import com.android.jill.api.v01.TranslationException;
import com.android.utils.FileUtils;
import com.android.utils.Pair;
import com.google.common.base.Preconditions;
@@ -94,6 +89,7 @@
androidBuilder.getTargetInfo().getBuildTools().getRevision(),
options.getJumboMode(),
options.getDexOptimize(),
+ options.getMinSdkVersion().getApiString(),
options.getUseJill() ? JILL_USED : JACK_USED,
options.getAdditionalParameters());
@@ -107,7 +103,8 @@
JackToolchain toolchain =
new JackToolchain(
androidBuilder.getTargetInfo().getBuildTools(),
- androidBuilder.getLogger());
+ androidBuilder.getLogger(),
+ androidBuilder.getErrorReporter());
toolchain.convert(
options, androidBuilder.getJavaProcessExecutor(), isJackInProcess);
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackDexKey.java b/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackDexKey.java
index 8b5d18f..093eec6 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackDexKey.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/compiler/JackDexKey.java
@@ -44,10 +44,13 @@
private static final String ATTR_PARAMETER_VALUE = "param-value";
// Attribute containing tool used to convert the input e.g. Jack, Jill.
private static final String ATTR_TOOL_USED = "toolUsed";
+ private static final String ATTR_MIN_API_NAME = "minApiName";
@Nullable
private final String toolUsed;
@NonNull
+ private final String minApiName;
+ @NonNull
private final ImmutableSortedMap<String, String> additionalParameters;
private JackDexKey(
@@ -56,9 +59,11 @@
boolean jumboMode,
boolean optimize,
@Nullable String toolUsed,
+ @NonNull String minApiName,
@NonNull Map<String, String> additionalParameters) {
super(sourceFile, buildToolsRevision, jumboMode, optimize);
this.toolUsed = toolUsed;
+ this.minApiName = minApiName;
this.additionalParameters = ImmutableSortedMap.copyOf(additionalParameters);
}
@@ -68,6 +73,7 @@
boolean jumboMode,
boolean optimize,
@Nullable String toolUsed,
+ @NonNull String minApiName,
@NonNull Map<String, String> additionalParameters) {
return new JackDexKey(
sourceFile,
@@ -75,6 +81,7 @@
jumboMode,
optimize,
toolUsed,
+ minApiName,
additionalParameters);
}
@@ -99,6 +106,15 @@
toolUsed = toolUsedAttribute.getNodeValue();
}
+ String minApiName;
+ Node minApiAttribute = attrMap.getNamedItem(ATTR_MIN_API_NAME);
+ if (minApiAttribute != null) {
+ minApiName = minApiAttribute.getNodeValue();
+ } else {
+ // specify unknown value
+ minApiName = "-1";
+ }
+
Map<String, String> additionalParameters = Maps.newHashMap();
if (attrMap.getLength() > 0) {
Document document = attrMap.item(0).getOwnerDocument();
@@ -112,8 +128,14 @@
Node paramEntry = elemAdditionalParams.getChildNodes().item(i);
additionalParameters.put(
- paramEntry.getAttributes().getNamedItem(ATTR_PARAMETER_VALUE).getNodeValue(),
- paramEntry.getAttributes().getNamedItem(ATTR_PARAMETER_KEY).getNodeValue()
+ paramEntry
+ .getAttributes()
+ .getNamedItem(ATTR_PARAMETER_VALUE)
+ .getNodeValue(),
+ paramEntry
+ .getAttributes()
+ .getNamedItem(ATTR_PARAMETER_KEY)
+ .getNodeValue()
);
}
}
@@ -126,6 +148,7 @@
jumboMode,
optimize,
toolUsed,
+ minApiName,
additionalParameters);
};
@@ -139,6 +162,10 @@
toolUsedAttr.setValue(toolUsed);
itemNode.getAttributes().setNamedItem(toolUsedAttr);
+ Attr minApiAttr = document.createAttribute(ATTR_MIN_API_NAME);
+ minApiAttr.setValue(minApiName);
+ itemNode.getAttributes().setNamedItem(minApiAttr);
+
Element params = document.createElement(ELEM_ADDITIONAL_PARAMETERS);
for (String paramKey: additionalParameters.keySet()) {
String paramValue = additionalParameters.get(paramKey);
@@ -167,11 +194,12 @@
JackDexKey dxDexKey = (JackDexKey) o;
return Objects.equal(toolUsed, dxDexKey.toolUsed)
+ && minApiName.equals(dxDexKey.minApiName)
&& additionalParameters.equals(dxDexKey.additionalParameters);
}
@Override
public int hashCode() {
- return Objects.hashCode(super.hashCode(), toolUsed, additionalParameters);
+ return Objects.hashCode(super.hashCode(), toolUsed, minApiName, additionalParameters);
}
}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/IncrementalPackager.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/IncrementalPackager.java
old mode 100755
new mode 100644
index ba254c4..0a29603
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/IncrementalPackager.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/IncrementalPackager.java
@@ -25,8 +25,6 @@
import com.android.builder.packaging.ApkCreatorFactory;
import com.android.builder.packaging.PackagerException;
import com.android.ide.common.res2.FileStatus;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -156,7 +154,7 @@
Iterables.filter(
updates,
p -> p.getStatus() == FileStatus.REMOVED),
- PackagedFileUpdate.EXTRACT_NAME);
+ PackagedFileUpdate::getName);
for (String deletedPath : deletedPaths) {
mApkCreator.deleteFile(deletedPath);
@@ -165,11 +163,6 @@
Predicate<PackagedFileUpdate> isNewOrChanged =
pfu -> pfu.getStatus() == FileStatus.NEW || pfu.getStatus() == FileStatus.CHANGED;
- Function<PackagedFileUpdate, File> extractBaseFile =
- Functions.compose(
- RelativeFile::getBase,
- PackagedFileUpdate.EXTRACT_SOURCE);
-
Iterable<PackagedFileUpdate> newOrChangedNonArchiveFiles =
Iterables.filter(
updates,
@@ -184,11 +177,12 @@
updates,
pfu -> pfu.getSource().getBase().isFile() && isNewOrChanged.test(pfu));
- Iterable<File> archives = Iterables.transform(newOrChangedArchiveFiles, extractBaseFile);
+ Iterable<File> archives =
+ Iterables.transform(newOrChangedArchiveFiles, pfu -> pfu.getSource().getBase());
Set<String> names = Sets.newHashSet(
Iterables.transform(
newOrChangedArchiveFiles,
- PackagedFileUpdate.EXTRACT_NAME));
+ PackagedFileUpdate::getName));
/*
* Build the name map. The name of the file in the filesystem (or zip file) may not
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/OldPackager.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/OldPackager.java
index 6128d07..8db49b3 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/OldPackager.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/OldPackager.java
@@ -23,7 +23,6 @@
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.builder.files.FileModificationType;
import com.android.builder.files.RelativeFile;
import com.android.builder.packaging.ApkCreator;
import com.android.builder.packaging.ApkCreatorFactory;
@@ -32,6 +31,7 @@
import com.android.builder.packaging.ZipAbortException;
import com.android.builder.packaging.ZipEntryFilter;
import com.android.builder.signing.SignedJarApkCreatorFactory;
+import com.android.ide.common.res2.FileStatus;
import com.android.utils.ILogger;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
@@ -297,9 +297,9 @@
* @throws PackagerException failed to update the package
*/
public void updateResource(@NonNull RelativeFile file,
- @NonNull FileModificationType modificationType) throws PackagerException {
- if (modificationType == FileModificationType.NEW
- || modificationType == FileModificationType.CHANGED) {
+ @NonNull FileStatus modificationType) throws PackagerException {
+ if (modificationType == FileStatus.NEW
+ || modificationType == FileStatus.CHANGED) {
doAddFile(file.getFile(), file.getOsIndependentRelativePath());
} else {
throw new UnsupportedOperationException("Cannot remove a file from archive.");
@@ -319,12 +319,12 @@
* @throws PackagerException failed to update the package
*/
public void updateResourceArchive(@NonNull File file,
- @NonNull FileModificationType modificationType,
+ @NonNull FileStatus modificationType,
@NonNull final Predicate<String> isIgnored) throws PackagerException {
Preconditions.checkNotNull(mApkCreator, "mApkCreator == null");
- if (modificationType == FileModificationType.NEW
- || modificationType == FileModificationType.CHANGED) {
+ if (modificationType == FileStatus.NEW
+ || modificationType == FileStatus.CHANGED) {
try {
Closer closer = Closer.create();
try {
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/PackagedFileUpdate.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/PackagedFileUpdate.java
index f6bac8f..1304a98 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/PackagedFileUpdate.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/PackagedFileUpdate.java
@@ -19,9 +19,10 @@
import com.android.annotations.NonNull;
import com.android.builder.files.RelativeFile;
import com.android.ide.common.res2.FileStatus;
-import com.google.common.base.Function;
import com.google.common.base.Objects;
+import java.util.function.Function;
+
/**
* Elementary update of a file in a package.
*
@@ -36,39 +37,6 @@
class PackagedFileUpdate {
/**
- * Function that extracts the name of the file to update.
- */
- static final Function<PackagedFileUpdate, String> EXTRACT_NAME =
- new Function<PackagedFileUpdate, String>() {
- @Override
- public String apply(PackagedFileUpdate input) {
- return input.getName();
- }
- };
-
- /**
- * Function that extracts the status of the file.
- */
- static final Function<PackagedFileUpdate, FileStatus> EXTRACT_STATUS =
- new Function<PackagedFileUpdate, FileStatus>() {
- @Override
- public FileStatus apply(PackagedFileUpdate input) {
- return input.getStatus();
- }
- };
-
- /**
- * Function that extracts the source of the file to update.
- */
- static final Function<PackagedFileUpdate, RelativeFile> EXTRACT_SOURCE =
- new Function<PackagedFileUpdate, RelativeFile>() {
- @Override
- public RelativeFile apply(PackagedFileUpdate input) {
- return input.getSource();
- }
- };
-
- /**
* The source. May not exist if {@link #mStatus} is {@link FileStatus#REMOVED}.
*/
@NonNull
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/sign/ManifestGenerationExtension.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/sign/ManifestGenerationExtension.java
index 1e703c9..8db3d6c 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/sign/ManifestGenerationExtension.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/sign/ManifestGenerationExtension.java
@@ -21,7 +21,7 @@
import com.android.builder.internal.packaging.zip.StoredEntry;
import com.android.builder.internal.packaging.zip.ZFile;
import com.android.builder.internal.packaging.zip.ZFileExtension;
-import com.android.builder.internal.packaging.zip.utils.CachedSupplier;
+import com.android.builder.internal.utils.CachedSupplier;
import com.android.builder.internal.utils.IOExceptionRunnable;
import com.android.builder.packaging.ManifestAttributes;
import com.google.common.base.Preconditions;
@@ -31,6 +31,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
@@ -130,14 +131,16 @@
mCreatedBy = createdBy;
mManifest = new Manifest();
mDirty = false;
- mManifestBytes = new CachedSupplier<byte[]>() {
- @Override
- protected byte[] compute() throws IOException {
- ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+ mManifestBytes = new CachedSupplier<>(() -> {
+ ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+ try {
mManifest.write(outBytes);
- return outBytes.toByteArray();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- };
+
+ return outBytes.toByteArray();
+ });
}
/**
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/CentralDirectory.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/CentralDirectory.java
index 98884d1..92392cf 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/CentralDirectory.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/CentralDirectory.java
@@ -17,7 +17,7 @@
package com.android.builder.internal.packaging.zip;
import com.android.annotations.NonNull;
-import com.android.builder.internal.packaging.zip.utils.CachedSupplier;
+import com.android.builder.internal.utils.CachedSupplier;
import com.android.builder.internal.packaging.zip.utils.MsDosDateTimeUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
@@ -28,6 +28,7 @@
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
@@ -196,12 +197,7 @@
CentralDirectory(@NonNull ZFile file) {
mEntries = Maps.newHashMap();
mFile = file;
- mBytesSupplier = new CachedSupplier<byte[]>() {
- @Override
- protected byte[] compute() throws IOException {
- return computeByteRepresentation();
- }
- };
+ mBytesSupplier = new CachedSupplier<>(this::computeByteRepresentation);
}
/**
@@ -403,9 +399,9 @@
* Computes the byte representation of the central directory.
*
* @return a byte array containing the whole central directory
- * @throws IOException failed to write the byte array
+ * @throws UncheckedIOException failed to write the byte array
*/
- private byte[] computeByteRepresentation() throws IOException {
+ private byte[] computeByteRepresentation() {
List<StoredEntry> sorted = Lists.newArrayList(mEntries.values());
Collections.sort(sorted, StoredEntry.COMPARE_BY_NAME);
@@ -417,59 +413,62 @@
byte[][] extraFields = new byte[mEntries.size()][];
byte[][] comments = new byte[mEntries.size()][];
- /*
- * First collect all the data and compute the total size of the central directory.
- */
- int idx = 0;
- int total = 0;
- for (StoredEntry entry : sorted) {
- cdhs[idx] = entry.getCentralDirectoryHeader();
- compressInfos[idx] = cdhs[idx].getCompressionInfoWithWait();
- encodedFileNames[idx] = cdhs[idx].getEncodedFileName();
- extraFields[idx] = new byte[cdhs[idx].getExtraField().size()];
- cdhs[idx].getExtraField().write(ByteBuffer.wrap(extraFields[idx]));
- comments[idx] = cdhs[idx].getComment();
+ try {
+ /*
+ * First collect all the data and compute the total size of the central directory.
+ */
+ int idx = 0;
+ int total = 0;
+ for (StoredEntry entry : sorted) {
+ cdhs[idx] = entry.getCentralDirectoryHeader();
+ compressInfos[idx] = cdhs[idx].getCompressionInfoWithWait();
+ encodedFileNames[idx] = cdhs[idx].getEncodedFileName();
+ extraFields[idx] = new byte[cdhs[idx].getExtraField().size()];
+ cdhs[idx].getExtraField().write(ByteBuffer.wrap(extraFields[idx]));
+ comments[idx] = cdhs[idx].getComment();
- total += F_OFFSET.endOffset() + encodedFileNames[idx].length
- + extraFields[idx].length + comments[idx].length;
- idx++;
- }
-
- ByteBuffer out = ByteBuffer.allocate(total);
-
-
- for (idx = 0; idx < mEntries.size(); idx++) {
- F_SIGNATURE.write(out);
- F_MADE_BY.write(out, cdhs[idx].getMadeBy());
- F_VERSION_EXTRACT.write(out, compressInfos[idx].getVersionExtract());
- F_GP_BIT.write(out, cdhs[idx].getGpBit().getValue());
- F_METHOD.write(out, compressInfos[idx].getMethod().methodCode);
-
- if (mFile.areTimestampsIgnored()) {
- F_LAST_MOD_TIME.write(out, 0);
- F_LAST_MOD_DATE.write(out, 0);
- } else {
- F_LAST_MOD_TIME.write(out, cdhs[idx].getLastModTime());
- F_LAST_MOD_DATE.write(out, cdhs[idx].getLastModDate());
+ total += F_OFFSET.endOffset() + encodedFileNames[idx].length
+ + extraFields[idx].length + comments[idx].length;
+ idx++;
}
- F_CRC32.write(out, cdhs[idx].getCrc32());
- F_COMPRESSED_SIZE.write(out, compressInfos[idx].getCompressedSize());
- F_UNCOMPRESSED_SIZE.write(out, cdhs[idx].getUncompressedSize());
+ ByteBuffer out = ByteBuffer.allocate(total);
- F_FILE_NAME_LENGTH.write(out, cdhs[idx].getEncodedFileName().length);
- F_EXTRA_FIELD_LENGTH.write(out, cdhs[idx].getExtraField().size());
- F_COMMENT_LENGTH.write(out, cdhs[idx].getComment().length);
- F_DISK_NUMBER_START.write(out);
- F_INTERNAL_ATTRIBUTES.write(out, cdhs[idx].getInternalAttributes());
- F_EXTERNAL_ATTRIBUTES.write(out, cdhs[idx].getExternalAttributes());
- F_OFFSET.write(out, cdhs[idx].getOffset());
+ for (idx = 0; idx < mEntries.size(); idx++) {
+ F_SIGNATURE.write(out);
+ F_MADE_BY.write(out, cdhs[idx].getMadeBy());
+ F_VERSION_EXTRACT.write(out, compressInfos[idx].getVersionExtract());
+ F_GP_BIT.write(out, cdhs[idx].getGpBit().getValue());
+ F_METHOD.write(out, compressInfos[idx].getMethod().methodCode);
- out.put(encodedFileNames[idx]);
- out.put(extraFields[idx]);
- out.put(comments[idx]);
+ if (mFile.areTimestampsIgnored()) {
+ F_LAST_MOD_TIME.write(out, 0);
+ F_LAST_MOD_DATE.write(out, 0);
+ } else {
+ F_LAST_MOD_TIME.write(out, cdhs[idx].getLastModTime());
+ F_LAST_MOD_DATE.write(out, cdhs[idx].getLastModDate());
+ }
+
+ F_CRC32.write(out, cdhs[idx].getCrc32());
+ F_COMPRESSED_SIZE.write(out, compressInfos[idx].getCompressedSize());
+ F_UNCOMPRESSED_SIZE.write(out, cdhs[idx].getUncompressedSize());
+
+ F_FILE_NAME_LENGTH.write(out, cdhs[idx].getEncodedFileName().length);
+ F_EXTRA_FIELD_LENGTH.write(out, cdhs[idx].getExtraField().size());
+ F_COMMENT_LENGTH.write(out, cdhs[idx].getComment().length);
+ F_DISK_NUMBER_START.write(out);
+ F_INTERNAL_ATTRIBUTES.write(out, cdhs[idx].getInternalAttributes());
+ F_EXTERNAL_ATTRIBUTES.write(out, cdhs[idx].getExternalAttributes());
+ F_OFFSET.write(out, cdhs[idx].getOffset());
+
+ out.put(encodedFileNames[idx]);
+ out.put(extraFields[idx]);
+ out.put(comments[idx]);
+ }
+
+ return out.array();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
-
- return out.array();
}
}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/Eocd.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/Eocd.java
index 5d1a38b..5d3bf33 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/Eocd.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/Eocd.java
@@ -17,15 +17,14 @@
package com.android.builder.internal.packaging.zip;
import com.android.annotations.NonNull;
-import com.android.builder.internal.packaging.zip.utils.CachedSupplier;
-import com.android.builder.internal.utils.IOExceptionWrapper;
+import com.android.builder.internal.utils.CachedSupplier;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.primitives.Ints;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
/**
@@ -158,12 +157,7 @@
mComment = new byte[commentSize];
bytes.get(mComment);
- mByteSupplier = new CachedSupplier<byte[]>() {
- @Override
- protected byte[] compute() throws IOException {
- return computeByteRepresentation();
- }
- };
+ mByteSupplier = new CachedSupplier<>(this::computeByteRepresentation);
}
/**
@@ -184,16 +178,7 @@
mDirectoryOffset = directoryOffset;
mDirectorySize = directorySize;
mComment = new byte[0];
- mByteSupplier = new CachedSupplier<byte[]>() {
- @Override
- protected byte[] compute() {
- try {
- return computeByteRepresentation();
- } catch (IOException e) {
- throw new IOExceptionWrapper(e);
- }
- }
- };
+ mByteSupplier = new CachedSupplier<byte[]>(this::computeByteRepresentation);
}
/**
@@ -248,22 +233,26 @@
* Computes the byte representation of the EOCD.
*
* @return a byte representation of the EOCD that has exactly {@link #getEocdSize()} bytes
- * @throws IOException failed to generate the EOCD data
+ * @throws UncheckedIOException failed to generate the EOCD data
*/
@NonNull
- private byte[] computeByteRepresentation() throws IOException {
+ private byte[] computeByteRepresentation() {
ByteBuffer out = ByteBuffer.allocate(F_COMMENT_SIZE.endOffset() + mComment.length);
- F_SIGNATURE.write(out);
- F_NUMBER_OF_DISK.write(out);
- F_DISK_CD_START.write(out);
- F_RECORDS_DISK.write(out, mTotalRecords);
- F_RECORDS_TOTAL.write(out, mTotalRecords);
- F_CD_SIZE.write(out, mDirectorySize);
- F_CD_OFFSET.write(out, mDirectoryOffset);
- F_COMMENT_SIZE.write(out, mComment.length);
- out.put(mComment);
+ try {
+ F_SIGNATURE.write(out);
+ F_NUMBER_OF_DISK.write(out);
+ F_DISK_CD_START.write(out);
+ F_RECORDS_DISK.write(out, mTotalRecords);
+ F_RECORDS_TOTAL.write(out, mTotalRecords);
+ F_CD_SIZE.write(out, mDirectorySize);
+ F_CD_OFFSET.write(out, mDirectoryOffset);
+ F_COMMENT_SIZE.write(out, mComment.length);
+ out.put(mComment);
- return out.array();
+ return out.array();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/FileUseMapEntry.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/FileUseMapEntry.java
index 94e8191..c0529c8 100644
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/FileUseMapEntry.java
+++ b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/FileUseMapEntry.java
@@ -18,7 +18,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Ints;
@@ -154,7 +154,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("start", mStart)
.add("end", mEnd)
.add("store", mStore)
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/utils/CachedSupplier.java b/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/utils/CachedSupplier.java
deleted file mode 100644
index d6f7704..0000000
--- a/build-system/builder/src/main/java/com/android/builder/internal/packaging/zip/utils/CachedSupplier.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.android.builder.internal.packaging.zip.utils;
-
-import java.io.IOException;
-
-/**
- * Supplier that will cache a computed value and always supply the same value. It can be used to
- * lazily compute data. For example:
- * <pre>
- * CachedSupplier<Integer> value = new CachedSupplier<Integer>() {
- * protected Integer compute() {
- * Integer result;
- * // Do some expensive computation.
- * return result;
- * }
- * }
- *
- * if (a) {
- * // We need the result of the expensive computation.
- * Integer r = value.get();
- * }
- *
- * if (b) {
- * // We also need the result of the expensive computation.
- * Integer r = value.get();
- * }
- *
- * // If neither a nor b are true, we avoid doing the computation at all.
- * </pre>
- */
-public abstract class CachedSupplier<T> {
-
- /**
- * The cached data, {@code null} if computation resulted in {@code null}.
- */
- private T mCached;
-
- /**
- * Is the current data in {@link #mCached} valid?
- */
- private boolean mValid;
-
- /**
- * Creates a new supplier.
- */
- public CachedSupplier() {
- mValid = false;
- }
-
-
- /**
- * Obtains the value.
- * @return the value, either cached (if one exists) or computed
- * @throws IOException failed to compute the value
- */
- public synchronized T get() throws IOException {
- if (!mValid) {
- mCached = compute();
- mValid = true;
- }
-
- return mCached;
- }
-
- /**
- * Computes the supplier value. This method is only invoked once.
- * @return the result of the computation, {@code null} is allowed and, if returned, then
- * {@link #get()} will also return {@code null}
- * @throws IOException failed to compute the value
- */
- protected abstract T compute() throws IOException;
-
- /**
- * Resets the cache forcing a {@link #compute()} next time {@link #get()} is invoked.
- */
- public synchronized void reset() {
- mValid = false;
- }
-
- /**
- * In some cases, we may be able to precompute the cache value (or load it from somewhere we
- * had previously stored it). This method allows the cache value to be loaded.
- * <p>
- * If this method is invoked, then an invocation of {@link #get()} will not trigger an
- * invocation of {@link #compute()}.
- * @param t the new cache contents; will replace any currently cache content, if one exists
- */
- public synchronized void precomputed(T t) {
- mCached = t;
- mValid = true;
- }
-
- /**
- * Checks if the contents of the cache are valid.
- * @return are there valid contents in the cache?
- */
- public synchronized boolean isValid() {
- return mValid;
- }
-}
diff --git a/build-system/builder/src/main/java/com/android/builder/internal/utils/CachedSupplier.java b/build-system/builder/src/main/java/com/android/builder/internal/utils/CachedSupplier.java
new file mode 100644
index 0000000..ead563a
--- /dev/null
+++ b/build-system/builder/src/main/java/com/android/builder/internal/utils/CachedSupplier.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.builder.internal.utils;
+
+import com.android.annotations.NonNull;
+
+import java.util.function.Supplier;
+
+/**
+ * Supplier that will cache a computed value and always supply the same value. It can be used to
+ * lazily compute data. For example:
+ * <pre>
+ * CachedSupplier<Integer> value = new CachedSupplier<>(() -> {
+ * Integer result;
+ * // Do some expensive computation.
+ * return result;
+ * });
+ *
+ * if (a) {
+ * // We need the result of the expensive computation.
+ * Integer r = value.get();
+ * }
+ *
+ * if (b) {
+ * // We also need the result of the expensive computation.
+ * Integer r = value.get();
+ * }
+ *
+ * // If neither a nor b are true, we avoid doing the computation at all.
+ * </pre>
+ */
+public class CachedSupplier<T> {
+
+ /**
+ * The cached data, {@code null} if computation resulted in {@code null}.
+ */
+ private T cached;
+
+ /**
+ * Is the current data in {@link #cached} valid?
+ */
+ private boolean valid;
+
+ /**
+ * Actual supplier of data, if computation is needed.
+ */
+ @NonNull
+ private final Supplier<T> supplier;
+
+ /**
+ * Creates a new supplier.
+ */
+ public CachedSupplier(@NonNull Supplier<T> supplier) {
+ valid = false;
+ this.supplier = supplier;
+ }
+
+
+ /**
+ * Obtains the value.
+ *
+ * @return the value, either cached (if one exists) or computed
+ */
+ public synchronized T get() {
+ if (!valid) {
+ cached = supplier.get();
+ valid = true;
+ }
+
+ return cached;
+ }
+
+ /**
+ * Resets the cache forcing a {@code get()} on the supplier next time {@link #get()} is invoked.
+ */
+ public synchronized void reset() {
+ cached = null;
+ valid = false;
+ }
+
+ /**
+ * In some cases, we may be able to precompute the cache value (or load it from somewhere we
+ * had previously stored it). This method allows the cache value to be loaded.
+ *
+ * <p>If this method is invoked, then an invocation of {@link #get()} will not trigger an
+ * invocation of the supplier provided in the constructor.
+ *
+ * @param t the new cache contents; will replace any currently cache content, if one exists
+ */
+ public synchronized void precomputed(T t) {
+ cached = t;
+ valid = true;
+ }
+
+ /**
+ * Checks if the contents of the cache are valid.
+ *
+ * @return are there valid contents in the cache?
+ */
+ public synchronized boolean isValid() {
+ return valid;
+ }
+}
diff --git a/build-system/builder/src/main/java/com/android/builder/png/AaptProcess.java b/build-system/builder/src/main/java/com/android/builder/png/AaptProcess.java
index 2b30897..bf41fb3 100644
--- a/build-system/builder/src/main/java/com/android/builder/png/AaptProcess.java
+++ b/build-system/builder/src/main/java/com/android/builder/png/AaptProcess.java
@@ -21,11 +21,11 @@
import com.android.builder.tasks.BooleanLatch;
import com.android.builder.tasks.Job;
import com.android.ide.common.process.ProcessException;
+import com.android.utils.FileUtils;
import com.android.utils.GrabProcessOutput;
import com.android.utils.ILogger;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
-
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
@@ -92,9 +92,9 @@
hashCode(), in.getAbsolutePath().length(), out.getAbsolutePath().length());
mProcessOutputFacade.setNotifier(notifier);
mWriter.write("s\n");
- mWriter.write(in.getAbsolutePath());
+ mWriter.write(FileUtils.toExportableSystemDependentPath(in));
mWriter.write("\n");
- mWriter.write(out.getAbsolutePath());
+ mWriter.write(FileUtils.toExportableSystemDependentPath(out));
mWriter.write("\n");
mWriter.flush();
mLogger.verbose("Processed(%1$d) %2$s job:%3$s", hashCode(), in.getName(), job.toString());
@@ -122,7 +122,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("hashcode", hashCode())
.add("\nlocation", mAaptLocation)
.add("\nready", mReady.get())
diff --git a/build-system/builder/src/main/java/com/android/builder/png/QueuedCruncher.java b/build-system/builder/src/main/java/com/android/builder/png/QueuedCruncher.java
index 64bd473..da92a2c 100644
--- a/build-system/builder/src/main/java/com/android/builder/png/QueuedCruncher.java
+++ b/build-system/builder/src/main/java/com/android/builder/png/QueuedCruncher.java
@@ -16,7 +16,6 @@
package com.android.builder.png;
-import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.concurrency.GuardedBy;
@@ -28,9 +27,8 @@
import com.android.ide.common.internal.PngCruncher;
import com.android.ide.common.internal.PngException;
import com.android.utils.ILogger;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
-
import java.io.File;
import java.io.IOException;
import java.time.Duration;
@@ -215,18 +213,6 @@
@Override
public void crunchPng(int key, @NonNull final File from, @NonNull final File to)
throws PngException {
-
- if (from.getAbsolutePath().length() > 240
- && SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- throw new PngException("File path too long on Windows, keep below 240 characters : "
- + from.getAbsolutePath());
- }
- if (to.getAbsolutePath().length() > 240
- && SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- throw new PngException("File path too long on Windows, keep below 240 characters : "
- + to.getAbsolutePath());
- }
-
try {
final Job<AaptProcess> aaptProcessJob = new QueuedJob(
key,
@@ -253,7 +239,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("from", from.getAbsolutePath())
.add("to", to.getAbsolutePath())
.toString();
diff --git a/build-system/builder/src/main/java/com/android/builder/signing/DefaultSigningConfig.java b/build-system/builder/src/main/java/com/android/builder/signing/DefaultSigningConfig.java
index 5d9a231..b10d822 100644
--- a/build-system/builder/src/main/java/com/android/builder/signing/DefaultSigningConfig.java
+++ b/build-system/builder/src/main/java/com/android/builder/signing/DefaultSigningConfig.java
@@ -21,7 +21,7 @@
import com.android.builder.model.SigningConfig;
import com.android.ide.common.signing.KeystoreHelper;
import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.io.File;
import java.security.KeyStore;
@@ -205,7 +205,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("storeFile", mStoreFile.getAbsolutePath())
.add("storePassword", mStorePassword)
.add("keyAlias", mKeyAlias)
diff --git a/build-system/builder/src/main/java/com/android/builder/testing/ConnectedDevice.java b/build-system/builder/src/main/java/com/android/builder/testing/ConnectedDevice.java
index 3a2882e..578cdbe 100644
--- a/build-system/builder/src/main/java/com/android/builder/testing/ConnectedDevice.java
+++ b/build-system/builder/src/main/java/com/android/builder/testing/ConnectedDevice.java
@@ -29,7 +29,6 @@
import com.android.ddmlib.SyncException;
import com.android.ddmlib.TimeoutException;
import com.android.utils.ILogger;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
@@ -137,12 +136,10 @@
iDevice.installPackages(splitApkFiles, true /*reinstall*/,
ImmutableList.copyOf(options), timeoutInMs, TimeUnit.MILLISECONDS);
} catch (Exception e) {
- List<String> apkFileNames = Lists.transform(splitApkFiles, new Function<File, String>() {
- @Override
- public String apply(@Nullable File input) {
- return input != null ? input.getAbsolutePath() : null;
- }
- });
+ List<String> apkFileNames =
+ Lists.transform(
+ splitApkFiles,
+ input -> input != null ? input.getAbsolutePath() : null);
logger.error(e, "Unable to install " + Joiner.on(',').join(apkFileNames));
throw new DeviceException(e);
}
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/aapt/AaptTestUtils.java b/build-system/builder/src/test/java/com/android/builder/internal/aapt/AaptTestUtils.java
index 057b6c1..6f32b2c 100644
--- a/build-system/builder/src/test/java/com/android/builder/internal/aapt/AaptTestUtils.java
+++ b/build-system/builder/src/test/java/com/android/builder/internal/aapt/AaptTestUtils.java
@@ -22,17 +22,17 @@
import com.android.testutils.TestResources;
import com.android.utils.FileUtils;
import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.common.io.Resources;
-
-import org.junit.rules.TemporaryFolder;
-
import java.io.File;
+import org.junit.rules.TemporaryFolder;
/**
* Utility files for Aapt tests.
*/
public class AaptTestUtils {
+
/**
* Obtains a PNG for testing.
*
@@ -51,6 +51,24 @@
}
/**
+ * Obtains a PNG with a long filename for testing
+ *
+ * @param temporaryFolder the temporary folder where temporery files should be places
+ * @return a file with a PNG with a long filename in a {@code drawables} folder
+ * @throws Exception failed to create the PNG
+ */
+ @NonNull
+ public static File getTestPngWithLongFileName(@NonNull TemporaryFolder temporaryFolder)
+ throws Exception {
+ File drawables = new File(temporaryFolder.getRoot(), "drawable");
+ FileUtils.mkdirs(drawables);
+ File dstPng = new File(drawables, Strings.repeat("a", 230) + ".png");
+ Resources.asByteSource(Resources.getResource("testData/aapt/lena.png"))
+ .copyTo(Files.asByteSink(dstPng));
+ return dstPng;
+ }
+
+ /**
* Obtains a text file for testing.
*
* @param temporaryFolder the temporary folder where temporary files should be placed
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/aapt/v1/AaptV1Test.java b/build-system/builder/src/test/java/com/android/builder/internal/aapt/v1/AaptV1Test.java
index f678043..c50d5b4 100644
--- a/build-system/builder/src/test/java/com/android/builder/internal/aapt/v1/AaptV1Test.java
+++ b/build-system/builder/src/test/java/com/android/builder/internal/aapt/v1/AaptV1Test.java
@@ -49,11 +49,6 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import com.google.common.io.Files;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
import java.io.File;
import java.time.Duration;
import java.util.Collection;
@@ -63,6 +58,9 @@
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
/**
* Tests for {@link AaptV1}.
@@ -193,6 +191,18 @@
}
@Test
+ public void compilePngWithLongPath() throws Exception {
+ Aapt aapt = makeAapt();
+ Future<File> compiledFuture =
+ aapt.compile(
+ AaptTestUtils.getTestPngWithLongFileName(mTemporaryFolder),
+ AaptTestUtils.getOutputDir(mTemporaryFolder));
+ File compiled = compiledFuture.get();
+ assertNotNull(compiled);
+ assertTrue(compiled.isFile());
+ }
+
+ @Test
public void compileTxt() throws Exception {
Aapt aapt = makeAapt();
Future<File> compiledFuture =
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/aapt/v2/AaptV2Test.java b/build-system/builder/src/test/java/com/android/builder/internal/aapt/v2/AaptV2Test.java
index 8e16505..16241fb 100644
--- a/build-system/builder/src/test/java/com/android/builder/internal/aapt/v2/AaptV2Test.java
+++ b/build-system/builder/src/test/java/com/android/builder/internal/aapt/v2/AaptV2Test.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.builder.internal.aapt.Aapt;
import com.android.builder.internal.aapt.AaptTestUtils;
@@ -31,14 +32,13 @@
import com.android.testutils.TestUtils;
import com.android.utils.ILogger;
import com.android.utils.StdLogger;
-
+import java.io.File;
+import java.util.concurrent.Future;
+import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.File;
-import java.util.concurrent.Future;
-
/**
* Tests for {@code aapt2}.
*/
@@ -88,6 +88,21 @@
}
@Test
+ public void pngWithLongPathCrunchingTest() throws Exception {
+ // This fails on Windows due to issues in aapt handling of long paths.
+ Assume.assumeFalse(SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS);
+
+ Aapt aapt = makeAapt();
+ Future<File> compiledFuture =
+ aapt.compile(
+ AaptTestUtils.getTestPngWithLongFileName(mTemporaryFolder),
+ AaptTestUtils.getOutputDir(mTemporaryFolder));
+ File compiled = compiledFuture.get();
+ assertNotNull(compiled);
+ assertTrue(compiled.isFile());
+ }
+
+ @Test
public void resourceProcessingTest() throws Exception {
Aapt aapt = makeAapt();
Future<File> compiledFuture =
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/compiler/PreDexCacheTest.java b/build-system/builder/src/test/java/com/android/builder/internal/compiler/PreDexCacheTest.java
index 6a31783..c3e0a15 100644
--- a/build-system/builder/src/test/java/com/android/builder/internal/compiler/PreDexCacheTest.java
+++ b/build-system/builder/src/test/java/com/android/builder/internal/compiler/PreDexCacheTest.java
@@ -548,7 +548,7 @@
Files.write("dx!", dx, Charsets.UTF_8);
return BuildToolInfo.modifiedLayout(
- new Revision(24, 0, 2),
+ new Revision(25, 0, 0),
toolDir,
new File(toolDir, FN_AAPT),
new File(toolDir, FN_AIDL),
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/utils/CachedSupplierTest.java b/build-system/builder/src/test/java/com/android/builder/internal/utils/CachedSupplierTest.java
new file mode 100644
index 0000000..e8ce7b3
--- /dev/null
+++ b/build-system/builder/src/test/java/com/android/builder/internal/utils/CachedSupplierTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.builder.internal.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+import java.util.function.Supplier;
+
+public class CachedSupplierTest {
+
+ @Test
+ public void testGetsOnlyOnce() {
+ TestSupplier ts = new TestSupplier();
+ CachedSupplier<String> cs = new CachedSupplier<>(ts);
+ assertFalse(cs.isValid());
+
+ ts.value = "foo";
+ assertEquals(0, ts.invocationCount);
+ assertEquals("foo", cs.get());
+ assertEquals(1, ts.invocationCount);
+ assertTrue(cs.isValid());
+
+ ts.value = "bar";
+ assertEquals("foo", cs.get());
+ assertEquals(1, ts.invocationCount);
+ assertTrue(cs.isValid());
+ }
+
+ @Test
+ public void cacheCanBePreset() {
+ TestSupplier ts = new TestSupplier();
+ ts.value = "foo";
+ CachedSupplier<String> cs = new CachedSupplier<>(ts);
+ cs.precomputed("bar");
+ assertTrue(cs.isValid());
+
+ assertEquals("bar", cs.get());
+ assertEquals(0, ts.invocationCount);
+ }
+
+ @Test
+ public void exceptionThrownBySupplier() {
+ CachedSupplier<String> cs = new CachedSupplier<>(() -> {
+ throw new RuntimeException("foo");
+ });
+ assertFalse(cs.isValid());
+
+ try {
+ cs.get();
+ fail();
+ } catch (RuntimeException e) {
+ assertEquals("foo", e.getMessage());
+ }
+
+ assertFalse(cs.isValid());
+
+ try {
+ cs.get();
+ fail();
+ } catch (RuntimeException e) {
+ assertEquals("foo", e.getMessage());
+ }
+ }
+
+ @Test
+ public void reset() {
+ TestSupplier ts = new TestSupplier();
+ ts.value = "foo";
+ CachedSupplier<String> cs = new CachedSupplier<>(ts);
+ assertFalse(cs.isValid());
+
+ assertEquals("foo", cs.get());
+ assertEquals(1, ts.invocationCount);
+ assertTrue(cs.isValid());
+ ts.value = "bar";
+
+ cs.reset();
+ assertFalse(cs.isValid());
+ assertEquals("bar", cs.get());
+ assertEquals(2, ts.invocationCount);
+ }
+
+ static class TestSupplier implements Supplier<String> {
+ int invocationCount = 0;
+ String value;
+
+ @Override
+ public String get() {
+ invocationCount++;
+ return value;
+ }
+ }
+}
diff --git a/build-system/builder/src/test/java/com/android/builder/internal/utils/FileCacheTest.java b/build-system/builder/src/test/java/com/android/builder/internal/utils/FileCacheTest.java
index f2bdcf7..772c02d 100644
--- a/build-system/builder/src/test/java/com/android/builder/internal/utils/FileCacheTest.java
+++ b/build-system/builder/src/test/java/com/android/builder/internal/utils/FileCacheTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.repository.Revision;
import com.android.utils.FileUtils;
@@ -343,7 +344,7 @@
fail("expected IllegalStateException");
} catch (IllegalStateException exception) {
assertThat(exception).hasMessage("Some exception");
- assertThat(cacheFolder.getRoot().list().length == 0);
+ assertThat(cacheFolder.getRoot().list()).isEmpty();
}
assertEquals(0, fileCache.getHits());
@@ -615,7 +616,11 @@
inputFile = new File("com.android.support/design/23.3.0/jars/classes.jar");
inputs = new FileCache.Inputs.Builder().putFilePath("file", inputFile).build();
assertThat(inputs.toString()).isEqualTo("file=" + inputFile.getPath());
- assertThat(inputs.getKey()).isEqualTo("25dcc2247956f01b9dbdca420eff87c96aaf2874");
+ if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
+ assertThat(inputs.getKey()).isEqualTo("4b30578b0f46117c61911c027a589b48b80bd3d1");
+ } else {
+ assertThat(inputs.getKey()).isEqualTo("25dcc2247956f01b9dbdca420eff87c96aaf2874");
+ }
// Test Windows-based input file path
inputFile =
@@ -639,7 +644,11 @@
inputFile = new File("foo`-=[]\\\\;',./~!@#$%^&*()_+{}|:\\\"<>?");
inputs = new FileCache.Inputs.Builder().putFilePath("file", inputFile).build();
assertThat(inputs.toString()).isEqualTo("file=" + inputFile.getPath());
- assertThat(inputs.getKey()).isEqualTo("7f205499565a454d0186f34313e63281c7192a43");
+ if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
+ assertThat(inputs.getKey()).isEqualTo("c9a5f22f392f6186b18b66f70e59fa20583533dd");
+ } else {
+ assertThat(inputs.getKey()).isEqualTo("7f205499565a454d0186f34313e63281c7192a43");
+ }
// Test empty file path
inputFile = new File("");
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/api/ApkOutputFile.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/api/ApkOutputFile.java
index 1271c63..ea3ddbc 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/api/ApkOutputFile.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/api/ApkOutputFile.java
@@ -20,9 +20,8 @@
import com.android.annotations.Nullable;
import com.android.build.FilterData;
import com.android.build.OutputFile;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -30,6 +29,7 @@
import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.Callable;
+import java.util.function.Function;
/**
* Represents a resource output from a variant configuration.
@@ -84,12 +84,8 @@
@NonNull
public String getSplitIdentifiers(char separatorChar) {
- return Joiner.on(separatorChar).join(Iterables.transform(filters, new Function<FilterData, Object>() {
- @Override
- public Object apply(FilterData filterData) {
- return filterData.getIdentifier();
- }
- }));
+ return Joiner.on(separatorChar)
+ .join(Iterables.transform(filters, FilterData::getIdentifier));
}
@Override
@@ -100,7 +96,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("OutputType", outputType)
.add("Filters", Joiner.on(',').join(filters, new Function<FilterData, String>() {
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomCache.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomCache.java
deleted file mode 100644
index c330e03..0000000
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomCache.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.android.build.gradle.internal;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.concurrency.GuardedBy;
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-
-import org.gradle.api.Project;
-import org.gradle.api.file.CopySpec;
-
-import java.io.File;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-
-import groovy.lang.Closure;
-
-/**
- * Cache to Atom prepareTask.
- *
- * Each project creates its own version of AtomDependency, but they all represent the
- * same atom. This creates a single task that will unarchive the atom so that this is done only
- * once even for multi-module projects where 2+ modules depend on the same atom.
- *
- * The prepareTask is created in the root project always.
- */
-public class AtomCache {
-
- @NonNull
- private static final AtomCache sCache = new AtomCache();
-
- @NonNull
- public static AtomCache getCache() {
- return sCache;
- }
-
- public synchronized void unload() {
- bundleLatches.clear();
- }
-
- @GuardedBy("this")
- private final Map<String, CountDownLatch> bundleLatches = Maps.newHashMap();
-
- public static void unzipAtom(final File bundle, final File folderOut, final Project project) {
- for (File f : Files.fileTreeTraverser().postOrderTraversal(folderOut)) {
- f.delete();
- }
-
- folderOut.mkdirs();
-
- project.copy(new Closure(AtomCache.class) {
- public Object doCall(CopySpec cs) {
- cs.from(project.zipTree(bundle));
- cs.into(folderOut);
-
- return cs;
- }
- });
- }
-}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomTaskManager.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomTaskManager.java
index 2ce9db3..08959b8 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomTaskManager.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/AtomTaskManager.java
@@ -191,6 +191,10 @@
variantScope,
ExecutionType.ATOM_TASK_MANAGER_CREATE_COMPILE_TASK,
() -> {
+ // create data binding merge task before the javac task so that it can
+ // parse jars before any consumer
+ createDataBindingMergeArtifactsTaskIfNecessary(tasks, variantScope);
+
// First, build the .class files with javac and compile the jar.
AndroidTask<? extends JavaCompile> javacTask =
createJavacTask(tasks, variantScope);
@@ -199,8 +203,8 @@
setJavaCompilerTask(javacTask, tasks, variantScope);
- getAndroidTasks().create(tasks,
- new AndroidJarTask.JarClassesConfigAction(variantScope));
+ getAndroidTasks()
+ .create(tasks, new AndroidJarTask.JarClassesConfigAction(variantScope));
// Then, build the dex with jack if enabled.
// TODO: This means recompiling everything twice if jack is enabled.
@@ -213,20 +217,31 @@
} else {
// Prevent the use of java 1.8 without jack, which would otherwise cause an
// internal javac error.
- if (variantScope.getGlobalScope().getExtension().getCompileOptions()
- .getTargetCompatibility().isJava8Compatible()) {
+ if (variantScope
+ .getGlobalScope()
+ .getExtension()
+ .getCompileOptions()
+ .getTargetCompatibility()
+ .isJava8Compatible()) {
// Only warn for users of retrolambda and dexguard
if (project.getPlugins().hasPlugin("me.tatarka.retrolambda")
|| project.getPlugins().hasPlugin("dexguard")) {
- getLogger().warn("Jack is disabled, but one of the plugins you "
- + "are using supports Java 8 language features.");
+ getLogger()
+ .warn(
+ "Jack is disabled, but one of the plugins you "
+ + "are using supports Java 8 language features.");
} else {
- androidBuilder.getErrorReporter().handleSyncError(
- variantScope.getVariantConfiguration().getFullName(),
- SyncIssue.TYPE_JACK_REQUIRED_FOR_JAVA_8_LANGUAGE_FEATURES,
- "Jack is required to support java 8 language features. "
- + "Either enable Jack or remove "
- + "sourceCompatibility JavaVersion.VERSION_1_8.");
+ androidBuilder
+ .getErrorReporter()
+ .handleSyncError(
+ variantScope
+ .getVariantConfiguration()
+ .getFullName(),
+ SyncIssue
+ .TYPE_JACK_REQUIRED_FOR_JAVA_8_LANGUAGE_FEATURES,
+ "Jack is required to support java 8 language features. "
+ + "Either enable Jack or remove "
+ + "sourceCompatibility JavaVersion.VERSION_1_8.");
}
}
createPostCompilationTasks(tasks, variantScope);
@@ -310,6 +325,17 @@
getAssembleDefault().dependsOn(variantScope.getAssembleTask().getName());
}
+
+ // also publish the artifact with its full config name
+ if (getExtension().getPublishNonDefault()) {
+ String classifier =
+ variantData.getVariantDependency().getPublishConfiguration().getName();
+ bundleAtom.configure(tasks, packageTask -> project.getArtifacts().add(classifier,
+ new AtomPublishArtifact(
+ getGlobalScope().getProjectBaseName(),
+ classifier,
+ packageTask)));
+ }
}
@NonNull
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/DependencyManager.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/DependencyManager.java
index 4d29d16..876252e 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/DependencyManager.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/DependencyManager.java
@@ -19,6 +19,7 @@
import static com.android.SdkConstants.DOT_JAR;
import static com.android.SdkConstants.EXT_ANDROID_PACKAGE;
import static com.android.SdkConstants.EXT_JAR;
+import static com.android.build.gradle.internal.TaskManager.DIR_ATOMBUNDLES;
import static com.android.build.gradle.internal.TaskManager.DIR_BUNDLES;
import static com.android.build.gradle.internal.dependency.DependencyChecker.computeVersionLessCoordinateKey;
import static com.android.builder.core.BuilderConstants.EXT_ATOMBUNDLE_ARCHIVE;
@@ -29,11 +30,9 @@
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.build.gradle.AndroidConfig;
import com.android.build.gradle.AndroidGradleOptions;
import com.android.build.gradle.internal.dependency.VariantDependencies;
import com.android.build.gradle.internal.scope.AndroidTask;
-import com.android.build.gradle.internal.tasks.PrepareAtomTask;
import com.android.build.gradle.internal.tasks.PrepareDependenciesTask;
import com.android.build.gradle.internal.tasks.PrepareLibraryTask;
import com.android.build.gradle.internal.variant.BaseVariantData;
@@ -83,7 +82,6 @@
import org.gradle.api.artifacts.result.ResolvedDependencyResult;
import org.gradle.api.artifacts.result.UnresolvedDependencyResult;
import org.gradle.api.logging.Logging;
-import org.gradle.api.plugins.ApplicationPlugin;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.specs.Specs;
import org.gradle.util.GUtil;
@@ -113,7 +111,6 @@
private boolean repositoriesUpdated = false;
private final Map<String, PrepareLibraryTask> prepareLibTaskMap = Maps.newHashMap();
- private final Map<String, PrepareAtomTask> prepareAtomTaskMap = Maps.newHashMap();
public DependencyManager(
@NonNull Project project,
@@ -135,11 +132,6 @@
variantData.getScope().getPreBuildTask());
}
- for (AndroidAtom androidAtom : variantDeps.getCompileDependencies().getAtomDependencies()) {
- addDependencyToPrepareTask(tasks, androidAtom, prepareDependenciesTask,
- variantData.getScope().getPreBuildTask());
- }
-
for (AndroidLibrary androidLibrary : variantDeps.getPackageDependencies().getAndroidDependencies()) {
addDependencyToPrepareTask(tasks, androidLibrary, prepareDependenciesTask,
variantData.getScope().getPreBuildTask());
@@ -162,26 +154,6 @@
}
}
- private void addDependencyToPrepareTask(
- @NonNull TaskFactory tasks,
- @NonNull AndroidAtom atom,
- @NonNull AndroidTask<PrepareDependenciesTask> prepareDependenciesTask,
- @NonNull AndroidTask<DefaultTask> preBuildTask) {
- PrepareAtomTask prepareAtomTask = prepareAtomTaskMap.get(atom.getResolvedCoordinates().toString());
- if (prepareAtomTask != null) {
- prepareDependenciesTask.dependsOn(tasks, prepareAtomTask);
- prepareAtomTask.dependsOn(preBuildTask.getName());
- }
-
- for (AndroidAtom childAtom : atom.getAtomDependencies()) {
- addDependencyToPrepareTask(tasks, childAtom, prepareDependenciesTask, preBuildTask);
- }
-
- for (AndroidLibrary childLib : atom.getLibraryDependencies()) {
- addDependencyToPrepareTask(tasks, childLib, prepareDependenciesTask, preBuildTask);
- }
- }
-
public void resolveDependencies(
@NonNull VariantDependencies variantDeps,
@Nullable VariantDependencies testedVariantDeps,
@@ -194,17 +166,13 @@
// an identity set.
Set<LibraryDependency> libsToExplode = Sets.newIdentityHashSet();
- Multimap<AndroidAtom, Configuration> reverseAtomMap = ArrayListMultimap.create();
-
resolveDependencyForConfig(
variantDeps,
testedVariantDeps,
testedProjectPath,
- libsToExplode,
- reverseAtomMap);
+ libsToExplode);
processLibraries(libsToExplode);
- processAtoms(reverseAtomMap);
}
private void processLibraries(@NonNull Set<LibraryDependency> libsToExplode) {
@@ -213,43 +181,6 @@
}
}
- private void processAtoms(@NonNull Multimap<AndroidAtom, Configuration> reverseMap) {
- for (AndroidAtom atom : reverseMap.keySet()) {
- setupPrepareAtomTask(atom, reverseMap.get(atom));
- }
- }
-
- private void setupPrepareAtomTask(
- @NonNull AndroidAtom androidAtom,
- @Nullable Collection<Configuration> configurationList) {
- Task task = maybeCreatePrepareAtomTask(androidAtom, project);
-
- // Use the reverse map to find all the configurations that included this android
- // library so that we can make sure they are built.
- // TODO fix, this is not optimum as we bring in more dependencies than we should.
- if (configurationList != null && !configurationList.isEmpty()) {
- for (Configuration configuration: configurationList) {
- task.dependsOn(configuration.getBuildDependencies());
- }
- }
-
- // check if this library is created by a parent (this is based on the
- // output file.
- // TODO Fix this as it's fragile
- /*
- This is a somewhat better way but it doesn't work in some project with
- weird setups...
- Project parentProject = DependenciesImpl.getProject(atom.getBundle(), projects)
- if (parentProject != null) {
- String configName = atom.getProjectVariant()
- if (configName == null) {
- configName = "default"
- }
-
- prepareAtomTask.dependsOn parentProject.getPath() + ":assemble${configName.capitalize()}"
- }*/
- }
-
/**
* Handles the library and returns a task to "prepare" the library (ie unarchive it). The task
* will be reused for all projects using the same library.
@@ -294,55 +225,11 @@
return prepareLibraryTask;
}
- /**
- * Handles the atom and returns a task to "prepare" the atom (ie unarchive it). The task
- * will be reused for all projects using the same atp,.
- *
- * @param atom the atom.
- * @param project the project
- * @return the prepare task.
- */
- private PrepareAtomTask maybeCreatePrepareAtomTask(
- @NonNull AndroidAtom atom,
- @NonNull Project project) {
- AtomDependency atomDependency = (AtomDependency) atom;
-
- // create proper key for the map. atom here contains all the dependencies which
- // are not relevant for the task (since the task only extract the aar which does not
- // include the dependencies.
- // However there is a possible case of a rewritten dependencies (with resolution strategy)
- // where the aar here could have different dependencies, in which case we would still
- // need the same task.
- // So we extract a AbstractAtomDependency (no dependencies) from the AtomDependency to
- // make the map key that doesn't take into account the dependencies.
- String key = atom.getResolvedCoordinates().toString();
-
- PrepareAtomTask prepareAtomTask = prepareAtomTaskMap.get(key);
-
- if (prepareAtomTask == null) {
- String bundleName = GUtil.toCamelCase(atomDependency.getName().replaceAll("\\:", " "));
-
- prepareAtomTask = project.getTasks().create(
- "prepare" + bundleName + "Atom", PrepareAtomTask.class);
-
- prepareAtomTask.setDescription("Prepare " + atomDependency.getName());
- prepareAtomTask.setBundle(atomDependency.getBundle());
- prepareAtomTask.setExplodedDir(atomDependency.getFolder());
- prepareAtomTask.setVariantName("");
-
- prepareAtomTaskMap.put(key, prepareAtomTask);
- }
-
- return prepareAtomTask;
- }
-
private void resolveDependencyForConfig(
@NonNull final VariantDependencies variantDeps,
@Nullable VariantDependencies testedVariantDeps,
@Nullable String testedProjectPath,
- @NonNull Set<LibraryDependency> libsToExplodeOut,
- @NonNull Multimap<AndroidAtom, Configuration> reverseAtomMap) {
-
+ @NonNull Set<LibraryDependency> libsToExplodeOut) {
boolean needPackageScope = true;
if (AndroidGradleOptions.buildModelOnly(project)) {
// if we're only syncing (building the model), then we only need the package
@@ -378,7 +265,6 @@
packageClasspath,
variantDeps,
libsToExplodeOut,
- reverseAtomMap,
currentUnresolvedDependencies,
testedProjectPath,
artifactSet,
@@ -397,7 +283,6 @@
compileClasspath,
variantDeps,
libsToExplodeOut,
- reverseAtomMap,
currentUnresolvedDependencies,
testedProjectPath,
artifactSet,
@@ -454,7 +339,7 @@
if (DEBUG_DEPENDENCY) {
System.out.println(project.getName() + ":" + compileClasspath.getName() + "/" +packageClasspath.getName());
- System.out.println("<<<<<<`<");
+ System.out.println("<<<<<<<<<<");
}
}
@@ -469,7 +354,6 @@
@NonNull Configuration configuration,
@NonNull final VariantDependencies variantDeps,
@NonNull Set<LibraryDependency> libsToExplodeOut,
- @NonNull Multimap<AndroidAtom, Configuration> reverseAtomMap,
@NonNull Set<String> currentUnresolvedDependencies,
@Nullable String testedProjectPath,
@NonNull Set<String> artifactSet,
@@ -499,7 +383,6 @@
addDependency(
((ResolvedDependencyResult) dependencyResult).getSelected(),
variantDeps,
- configuration,
libraryDependencies,
atomDependencies,
jarDependencies,
@@ -508,7 +391,6 @@
foundJars,
artifacts,
libsToExplodeOut,
- reverseAtomMap,
currentUnresolvedDependencies,
testedProjectPath,
Collections.emptyList(),
@@ -699,7 +581,6 @@
private void addDependency(
@NonNull ResolvedComponentResult resolvedComponentResult,
@NonNull VariantDependencies configDependencies,
- @NonNull Configuration configuration,
@NonNull Collection<LibraryDependency> outLibraries,
@NonNull Collection<AtomDependency> outAtoms,
@NonNull List<JarDependency> outJars,
@@ -708,7 +589,6 @@
@NonNull Map<ModuleVersionIdentifier, List<JarDependency>> alreadyFoundJars,
@NonNull Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,
@NonNull Set<LibraryDependency> libsToExplodeOut,
- @NonNull Multimap<AndroidAtom, Configuration> reverseAtomMap,
@NonNull Set<String> currentUnresolvedDependencies,
@Nullable String testedProjectPath,
@NonNull List<String> projectChain,
@@ -747,10 +627,6 @@
printIndent(indent, "FOUND ATOM: " + moduleVersion.getName());
}
outAtoms.addAll(atomsForThisModule);
-
- for (AndroidAtom atom : atomsForThisModule) {
- reverseAtomMap.put(atom, configuration);
- }
} else if (jarsForThisModule != null) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "FOUND JAR: " + moduleVersion.getName());
@@ -812,7 +688,6 @@
addDependency(
selected,
configDependencies,
- configuration,
nestedLibraries,
nestedAtoms,
nestedJars,
@@ -821,7 +696,6 @@
alreadyFoundJars,
artifacts,
libsToExplodeOut,
- reverseAtomMap,
currentUnresolvedDependencies,
testedProjectPath,
newProjectChain,
@@ -993,12 +867,25 @@
printIndent(indent, "PATH: " + path);
}
- File explodedDir = project.file(project.getBuildDir() + "/" + FD_INTERMEDIATES + "/exploded-atombundle/" + path);
+ final String variantName = artifact.getClassifier();
+
+ // if there is a variant name then we use it for the leaf
+ // (this means the subproject is publishing all its variants and each
+ // artifact has a classifier that is the variant Name).
+ // Otherwise the subproject only outputs a single artifact
+ // and the location was set to default.
+ String pathLeaf = variantName != null ? variantName : "default";
+
+ Project subProject = project.findProject(gradlePath);
+ File stagingDir = FileUtils.join(
+ subProject.getBuildDir(),
+ FD_INTERMEDIATES, DIR_ATOMBUNDLES,
+ pathLeaf);
@SuppressWarnings("unchecked")
AtomDependency atomDependency = new AtomDependency(
artifact.getFile(),
- explodedDir,
+ stagingDir,
nestedLibraries,
nestedAtoms,
nestedJars,
@@ -1011,7 +898,6 @@
atomsForThisModule.add(atomDependency);
outAtoms.add(atomDependency);
- reverseAtomMap.put(atomDependency, configuration);
} else if (EXT_JAR.equals(artifact.getExtension())) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "TYPE: JAR");
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/SdkHandler.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/SdkHandler.java
index 2bdc287..6cef039 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/SdkHandler.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/SdkHandler.java
@@ -23,6 +23,7 @@
import com.android.annotations.Nullable;
import com.android.annotations.concurrency.GuardedBy;
import com.android.build.gradle.AndroidGradleOptions;
+import com.android.build.gradle.internal.ndk.NdkHandler;
import com.android.builder.core.AndroidBuilder;
import com.android.builder.core.LibraryRequest;
import com.android.builder.model.OptionalCompilationStep;
@@ -78,7 +79,6 @@
private SdkLibData sdkLibData = SdkLibData.dontDownload();
private boolean isRegularSdk = true;
- public static final String NDK_BUNDLE_SUBPATH = "ndk-bundle";
public static void setTestSdkFolder(File testSdkFolder) {
sTestSdkFolder = testSdkFolder;
}
@@ -241,26 +241,6 @@
}
}
- private void findNdkLocation(@NonNull Properties properties) {
- String ndkDirProp = properties.getProperty("ndk.dir");
- if (ndkDirProp != null) {
- ndkFolder = new File(ndkDirProp);
- return;
- }
-
- String ndkEnvVar = System.getenv("ANDROID_NDK_HOME");
- if (ndkEnvVar != null) {
- ndkFolder = new File(ndkEnvVar);
- return;
- }
-
- String stdEnvVar = System.getenv("ANDROID_HOME");
- if (stdEnvVar != null && !stdEnvVar.isEmpty()) {
- // Worth checking if the NDK came bundled with the SDK
- ndkFolder = new File(stdEnvVar, NDK_BUNDLE_SUBPATH);
- }
- }
-
private void findLocation(@NonNull Project project) {
if (sTestSdkFolder != null) {
sdkFolder = sTestSdkFolder;
@@ -295,7 +275,7 @@
}
findSdkLocation(properties, rootDir);
- findNdkLocation(properties);
+ ndkFolder = NdkHandler.findNdkDirectory(properties);
}
public void setSdkLibData(SdkLibData sdkLibData) {
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/TaskManager.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/TaskManager.java
index 1ed9f59..ed299ab 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/TaskManager.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/TaskManager.java
@@ -2019,17 +2019,6 @@
@NonNull final TaskFactory tasks,
@NonNull final VariantScope scope,
final boolean compileJavaSources) {
- if (androidBuilder.getTargetInfo() != null
- && !androidBuilder.getTargetInfo().getBuildTools().supportsJack()) {
- androidBuilder
- .getErrorReporter()
- .handleSyncError(
- BuildToolInfo.JackVersion.V4.getMinRevision().toString(),
- SyncIssue.TYPE_BUILD_TOOLS_TOO_LOW,
- String.format(
- "Jack requires Build Tools %s or later.",
- BuildToolInfo.JackVersion.V4.getMinRevision().toString()));
- }
if (scope.getTestedVariantData() != null) {
scope.getTransformManager().addStream(
@@ -2041,11 +2030,15 @@
.build());
}
// ----- Create PreDex tasks for libraries -----
- JackPreDexTransform preDexPackagedTransform = new JackPreDexTransform(
- androidBuilder,
- globalScope.getExtension().getDexOptions().getJavaMaxHeapSize(),
- scope.getVariantConfiguration().getJackOptions(),
- true);
+ JackPreDexTransform preDexPackagedTransform =
+ JackPreDexTransform.builder()
+ .androidBuilder(androidBuilder)
+ .javaMaxHeapSize(
+ globalScope.getExtension().getDexOptions().getJavaMaxHeapSize())
+ .coreJackOptions(scope.getVariantConfiguration().getJackOptions())
+ .minApiVersion(scope.getMinSdkVersion())
+ .forPackagedLibs()
+ .create();
Optional<AndroidTask<TransformTask>> packageTask =
scope.getTransformManager().addTransform(tasks, scope, preDexPackagedTransform);
@@ -2061,11 +2054,15 @@
jacocoTask));
}
- JackPreDexTransform preDexRuntimeTransform = new JackPreDexTransform(
- androidBuilder,
- globalScope.getExtension().getDexOptions().getJavaMaxHeapSize(),
- scope.getVariantConfiguration().getJackOptions(),
- false);
+ JackPreDexTransform preDexRuntimeTransform =
+ JackPreDexTransform.builder()
+ .androidBuilder(androidBuilder)
+ .javaMaxHeapSize(
+ globalScope.getExtension().getDexOptions().getJavaMaxHeapSize())
+ .coreJackOptions(scope.getVariantConfiguration().getJackOptions())
+ .minApiVersion(scope.getMinSdkVersion())
+ .forClasspathLibs()
+ .create();
scope.getTransformManager().addTransform(tasks, scope, preDexRuntimeTransform);
// ----- Create Jack Task -----
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/VariantManager.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/VariantManager.java
index 75fda58..a44cfcf 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/VariantManager.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/VariantManager.java
@@ -444,7 +444,6 @@
variantData.setVariantDependency(variantDep);
if (variantType == VariantType.ANDROID_TEST &&
- testVariantConfig.isMultiDexEnabled() &&
testVariantConfig.isLegacyMultiDexMode()) {
project.getDependencies().add(
variantDep.getCompileConfiguration().getName(), COM_ANDROID_SUPPORT_MULTIDEX_INSTRUMENTATION);
@@ -613,7 +612,7 @@
variantProviders.toArray(new ConfigurationProvider[variantProviders.size()]));
variantData.setVariantDependency(variantDep);
- if (variantConfig.isMultiDexEnabled() && variantConfig.isLegacyMultiDexMode()) {
+ if (variantConfig.isLegacyMultiDexMode()) {
project.getDependencies().add(
variantDep.getCompileConfiguration().getName(), COM_ANDROID_SUPPORT_MULTIDEX);
project.getDependencies().add(
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/VariantDependencies.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/VariantDependencies.java
index 31dd46c..a4a7580 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/VariantDependencies.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/VariantDependencies.java
@@ -23,7 +23,7 @@
import com.android.builder.core.VariantType;
import com.android.builder.dependency.DependencyContainer;
import com.android.builder.model.SyncIssue;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import org.gradle.api.Project;
@@ -370,7 +370,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", variantName)
.toString();
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/SigningConfig.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/SigningConfig.java
index 35b0832..a38b750 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/SigningConfig.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/SigningConfig.java
@@ -20,7 +20,7 @@
import com.android.builder.core.BuilderConstants;
import com.android.builder.signing.DefaultSigningConfig;
import com.android.prefs.AndroidLocation;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import org.gradle.api.Named;
import org.gradle.api.tasks.Input;
@@ -179,7 +179,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", mName)
.add("storeFile", getStoreFile() != null ? getStoreFile().getAbsolutePath() : "null")
.add("storePassword", getStorePassword())
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/externalBuild/ExternalBuildManifestLoader.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/externalBuild/ExternalBuildManifestLoader.java
index 8b35105..8e846ec 100755
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/externalBuild/ExternalBuildManifestLoader.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/externalBuild/ExternalBuildManifestLoader.java
@@ -84,7 +84,7 @@
ExternalBuildApkManifest.AndroidSdk sdk = manifest.getAndroidSdk();
BuildToolInfo buildToolInfo = BuildToolInfo.partial(
- new Revision(24, 0, 2),
+ new Revision(25, 0, 0),
project.getProjectDir(),
ImmutableMap.of(
// TODO: Put dx.jar in the proto
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidAtomImpl.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidAtomImpl.java
index 0c939ad..97aed21 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidAtomImpl.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidAtomImpl.java
@@ -22,6 +22,7 @@
import com.android.builder.model.AndroidAtom;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.JavaLibrary;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -231,7 +232,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", getName())
.add("project", getProject())
.add("variant", variant)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidLibraryImpl.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidLibraryImpl.java
index 4aaeb0d..a5aa7ad 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidLibraryImpl.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/AndroidLibraryImpl.java
@@ -21,6 +21,7 @@
import com.android.annotations.concurrency.Immutable;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.JavaLibrary;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -257,7 +258,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", getName())
.add("project", getProject())
.add("variant", variant)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/LibraryImpl.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/LibraryImpl.java
index 1e92e4f..45a6674 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/LibraryImpl.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/LibraryImpl.java
@@ -21,6 +21,7 @@
import com.android.annotations.concurrency.Immutable;
import com.android.builder.model.Library;
import com.android.builder.model.MavenCoordinates;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import java.io.Serializable;
@@ -126,7 +127,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", name)
.add("requestedCoordinates", requestedCoordinates)
.add("resolvedCoordinates", resolvedCoordinates)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunBuildContext.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunBuildContext.java
old mode 100755
new mode 100644
index 5ce338b..588a30f
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunBuildContext.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunBuildContext.java
@@ -24,7 +24,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CaseFormat;
import com.google.common.base.Charsets;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
@@ -268,7 +268,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("fileType", fileType)
.add("location", location)
.toString();
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunVerifier.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunVerifier.java
index 399c75e..fd160cc 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunVerifier.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/InstantRunVerifier.java
@@ -34,21 +34,12 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
+import com.android.build.gradle.internal.LoggerWrapper;
+import com.android.utils.ILogger;
import com.google.common.base.Objects;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.AnnotationNode;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
-import org.objectweb.asm.util.Textifier;
-import org.objectweb.asm.util.TraceMethodVisitor;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -61,6 +52,16 @@
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import org.gradle.api.logging.Logging;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AnnotationNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.util.Textifier;
+import org.objectweb.asm.util.TraceMethodVisitor;
/**
* Instant Run Verifier responsible for checking that a class change (between two developers
@@ -71,6 +72,8 @@
public class InstantRunVerifier {
private static final Comparator<MethodNode> METHOD_COMPARATOR = new MethodNodeComparator();
+ private static final ILogger LOGGER =
+ new LoggerWrapper(Logging.getLogger(InstantRunVerifier.class));
@VisibleForTesting
static final Comparator<AnnotationNode> ANNOTATION_COMPARATOR =
@@ -196,6 +199,10 @@
// potentially, we could try to see if anything has really changed between
// the two classes but the fact that we got an updated class means so far that
// we have a new version and should restart.
+ LOGGER.info(
+ "Class %s annotated with %s.",
+ updatedClass.name,
+ IncrementalVisitor.DISABLE_ANNOTATION_TYPE.getClassName());
return INSTANT_RUN_DISABLED;
}
}
@@ -345,9 +352,12 @@
if ((disabledMethod || usingBlackListedAPIs) &&
!METHOD_COMPARATOR.areEqual(methodNode, updatedMethod)) {
- return disabledMethod
- ? INSTANT_RUN_DISABLED
- : REFLECTION_USED;
+ if (disabledMethod) {
+ LOGGER.info("Instant Run disabled for method %s.", updatedMethod.name);
+ return INSTANT_RUN_DISABLED;
+ } else {
+ return REFLECTION_USED;
+ }
}
return COMPATIBLE;
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/StringSwitch.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/StringSwitch.java
index b161f17..10bc793 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/StringSwitch.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/incremental/StringSwitch.java
@@ -16,7 +16,6 @@
package com.android.build.gradle.internal.incremental;
-import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
@@ -32,6 +31,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
/**
@@ -143,14 +143,10 @@
visitHashMethod(mv);
// Group strings by hash code.
- Multimap<Integer, String> buckets = Multimaps.index(strings, HASH_METHOD);
+ Multimap<Integer, String> buckets = Multimaps.index(strings, HASH_METHOD::apply);
List<Map.Entry<Integer, Collection<String>>> sorted = Ordering.natural()
- .onResultOf(new Function<Map.Entry<Integer, Collection<String>>, Integer>() {
- @Override
- public Integer apply(Map.Entry<Integer, Collection<String>> entry) {
- return entry.getKey();
- }
- }).immutableSortedCopy(buckets.asMap().entrySet());
+ .onResultOf(Map.Entry<Integer, Collection<String>>::getKey)
+ .immutableSortedCopy(buckets.asMap().entrySet());
int sortedHashes[] = new int[sorted.size()];
List<String> sortedCases[] = new List[sorted.size()];
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/DefaultNdkInfo.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/DefaultNdkInfo.java
index d238c3a..2efd3b3 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/DefaultNdkInfo.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/DefaultNdkInfo.java
@@ -203,6 +203,7 @@
@NonNull Toolchain toolchain,
@NonNull String toolchainVersion,
@NonNull Abi abi) {
+ abi = getToolchainAbi(abi);
String version = toolchainVersion.isEmpty()
? getDefaultToolchainVersion(toolchain, abi)
: toolchainVersion;
@@ -250,6 +251,11 @@
}
}
+ @NonNull
+ protected Abi getToolchainAbi(@NonNull Abi abi) {
+ return abi;
+ }
+
/**
* Return the executable for compiling C code.
*/
@@ -259,6 +265,7 @@
@NonNull Toolchain toolchain,
@NonNull String toolchainVersion,
@NonNull Abi abi) {
+ abi = getToolchainAbi(abi);
String compiler = toolchain == Toolchain.CLANG ? "clang" : abi.getGccExecutablePrefix() + "-gcc";
return new File(getToolchainPath(toolchain, toolchainVersion, abi), "bin/" + compiler);
}
@@ -272,16 +279,42 @@
@NonNull Toolchain toolchain,
@NonNull String toolchainVersion,
@NonNull Abi abi) {
+ abi = getToolchainAbi(abi);
String compiler = toolchain == Toolchain.CLANG ? "clang++" : abi.getGccExecutablePrefix() + "-g++";
return new File(getToolchainPath(toolchain, toolchainVersion, abi), "bin/" + compiler);
}
+ /**
+ * Return the linker.
+ */
+ @Override
+ @NonNull
+ public File getLinker(
+ @NonNull Toolchain toolchain,
+ @NonNull String toolchainVersion,
+ @NonNull Abi abi) {
+ return getCppCompiler(toolchain, toolchainVersion, abi);
+ }
+
+ /**
+ * Return the assembler.
+ */
+ @Override
+ @NonNull
+ public File getAssembler(
+ @NonNull Toolchain toolchain,
+ @NonNull String toolchainVersion,
+ @NonNull Abi abi) {
+ return getCCompiler(toolchain, toolchainVersion, abi);
+ }
+
@Override
@NonNull
public File getAr(
@NonNull Toolchain toolchain,
@NonNull String toolchainVersion,
@NonNull Abi abi) {
+ abi = getToolchainAbi(abi);
// For clang, we use the ar from the GCC toolchain.
String ar = abi.getGccExecutablePrefix()
+ (toolchain == Toolchain.CLANG ? "-ar" : "-gcc-ar");
@@ -296,6 +329,7 @@
@Override
@NonNull
public File getStripExecutable(Toolchain toolchain, String toolchainVersion, Abi abi) {
+ abi = getToolchainAbi(abi);
return FileUtils.join(
getToolchainPath(
Toolchain.GCC,
@@ -316,7 +350,8 @@
*/
@Override
@NonNull
- public String getDefaultToolchainVersion(@NonNull Toolchain toolchain, @NonNull final Abi abi) {
+ public String getDefaultToolchainVersion(@NonNull Toolchain toolchain, @NonNull Abi abi) {
+ abi = getToolchainAbi(abi);
String defaultVersion = defaultToolchainVersions.get(Pair.of(toolchain, abi));
if (defaultVersion != null) {
return defaultVersion;
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkHandler.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkHandler.java
index 1b026ed..595a14d 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkHandler.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkHandler.java
@@ -71,9 +71,12 @@
if (revision == null) {
ndkInfo = new DefaultNdkInfo(ndkDirectory);
} else if (revision.getMajor() > LATEST_SUPPORTED_VERSION) {
- ndkInfo = new NdkR13Info(ndkDirectory);
+ ndkInfo = new NdkR14Info(ndkDirectory);
} else {
switch (revision.getMajor()) {
+ case 14:
+ ndkInfo = new NdkR14Info(ndkDirectory);
+ break;
case 13:
ndkInfo = new NdkR13Info(ndkDirectory);
break;
@@ -146,20 +149,28 @@
return toolchainVersion;
}
+ @Nullable
+ private static File findNdkDirectory(@NonNull File projectDir) {
+ File localProperties = new File(projectDir, FN_LOCAL_PROPERTIES);
+ Properties properties = null;
+ if (localProperties.isFile()) {
+ properties = readProperties(localProperties);
+ }
+
+ return findNdkDirectory(properties);
+ }
+
/**
* Determine the location of the NDK directory.
*
- * The NDK directory can be set in the local.properties file or using the ANDROID_NDK_HOME
- * environment variable.
+ * The NDK directory can be set in the local.properties file, using the ANDROID_NDK_HOME
+ * environment variable or come bundled with the SDK.
*
* Return null if NDK directory is not found.
*/
@Nullable
- private static File findNdkDirectory(@NonNull File projectDir) {
- File localProperties = new File(projectDir, FN_LOCAL_PROPERTIES);
-
- if (localProperties.isFile()) {
- Properties properties = readProperties(localProperties);
+ public static File findNdkDirectory(@Nullable Properties properties) {
+ if (properties != null) {
String ndkDirProp = properties.getProperty("ndk.dir");
if (ndkDirProp != null) {
return new File(ndkDirProp);
@@ -168,7 +179,7 @@
String ndkEnvVar = System.getenv("ANDROID_NDK_HOME");
if (ndkEnvVar != null) {
- return new File(ndkEnvVar);
+ return new File(ndkEnvVar);
}
String stdEnvVar = System.getenv("ANDROID_HOME");
@@ -322,6 +333,23 @@
}
/**
+ * Return the executable for linking binary files.
+ */
+ @NonNull
+ public File getLinker(@NonNull Abi abi) {
+ checkNotNull(ndkInfo);
+ return ndkInfo.getLinker(toolchain, toolchainVersion, abi);
+ }
+
+ /**
+ * Return the executable for assembling code.
+ */
+ @NonNull
+ public File getAssembler(@NonNull Abi abi) {
+ checkNotNull(ndkInfo);
+ return ndkInfo.getAssembler(toolchain, toolchainVersion, abi);
+ }
+ /**
* Return the static archiver.
*/
@NonNull
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkInfo.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkInfo.java
index a03d3d3..de61f46 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkInfo.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkInfo.java
@@ -69,6 +69,24 @@
@NonNull String toolchainVersion,
@NonNull Abi abi);
+ /**
+ * Return the executable for compiling C code.
+ */
+ @NonNull
+ File getLinker(
+ @NonNull Toolchain toolchain,
+ @NonNull String toolchainVersion,
+ @NonNull Abi abi);
+
+ /**
+ * Return the executable for compiling C++ code.
+ */
+ @NonNull
+ File getAssembler(
+ @NonNull Toolchain toolchain,
+ @NonNull String toolchainVersion,
+ @NonNull Abi abi);
+
@NonNull
File getAr(
@NonNull Toolchain toolchain,
@@ -108,5 +126,5 @@
* ABI. The result is cached for performance.
*/
@NonNull
- String getDefaultToolchainVersion(@NonNull Toolchain toolchain, @NonNull final Abi abi);
+ String getDefaultToolchainVersion(@NonNull Toolchain toolchain, @NonNull Abi abi);
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14Info.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14Info.java
new file mode 100644
index 0000000..39c32fb
--- /dev/null
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14Info.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.build.gradle.internal.ndk;
+
+import com.android.annotations.NonNull;
+import com.android.build.gradle.internal.core.Abi;
+import com.android.build.gradle.internal.core.Toolchain;
+import com.google.common.base.MoreObjects;
+
+import java.io.File;
+
+/**
+ * NdkInfo for r14.
+ */
+public class NdkR14Info extends DefaultNdkInfo {
+
+ public NdkR14Info(@NonNull File root) {
+ super(root);
+ }
+
+ @Override
+ @NonNull
+ protected Abi getToolchainAbi(@NonNull Abi abi) {
+ if (abi == Abi.MIPS) {
+ return Abi.MIPS64;
+ }
+ return abi;
+ }
+
+ @Override
+ @NonNull
+ public StlNativeToolSpecification getStlNativeToolSpecification(
+ @NonNull Stl stl,
+ @NonNull String stlVersion,
+ @NonNull Abi abi) {
+ StlSpecification spec = new NdkR14StlSpecificationFactory().create(
+ stl,
+ MoreObjects.firstNonNull(
+ stlVersion,
+ getDefaultToolchainVersion(Toolchain.GCC, abi)),
+ abi);
+ return new DefaultStlNativeToolSpecification(this, spec, stl);
+ }
+}
diff --git a/build-system/builder/src/main/java/com/android/builder/files/FileModificationType.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14StlSpecificationFactory.java
similarity index 63%
rename from build-system/builder/src/main/java/com/android/builder/files/FileModificationType.java
rename to build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14StlSpecificationFactory.java
index dd6dab9..d408fc4 100644
--- a/build-system/builder/src/main/java/com/android/builder/files/FileModificationType.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ndk/NdkR14StlSpecificationFactory.java
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package com.android.builder.files;
+package com.android.build.gradle.internal.ndk;
-// FIXME: Replace by FileStatus in a separate CL.
-public enum FileModificationType {
- NEW, REMOVED, CHANGED
+import com.android.annotations.NonNull;
+import com.android.build.gradle.internal.core.Abi;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * Factory for creating STL specification for NDK r14.
+ */
+public class NdkR14StlSpecificationFactory extends NdkR13StlSpecificationFactory{
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableDirectoryInput.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableDirectoryInput.java
index 22d062a..61d2a8a 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableDirectoryInput.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableDirectoryInput.java
@@ -21,7 +21,7 @@
import com.android.build.api.transform.DirectoryInput;
import com.android.build.api.transform.Status;
import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import java.io.File;
@@ -64,7 +64,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", getName())
.add("file", getFile())
.add("contentTypes", Joiner.on(',').join(getContentTypes()))
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableJarInput.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableJarInput.java
index 39130c2..d85b556 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableJarInput.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableJarInput.java
@@ -22,7 +22,7 @@
import com.android.build.api.transform.QualifiedContent;
import com.android.build.api.transform.Status;
import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.io.File;
import java.util.Set;
@@ -61,7 +61,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", getName())
.add("file", getFile())
.add("contentTypes", Joiner.on(',').join(getContentTypes()))
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableTransformInput.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableTransformInput.java
index fced479..ec33024 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableTransformInput.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/ImmutableTransformInput.java
@@ -21,7 +21,7 @@
import com.android.build.api.transform.DirectoryInput;
import com.android.build.api.transform.JarInput;
import com.android.build.api.transform.TransformInput;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import java.io.File;
@@ -61,7 +61,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("rootLocation", optionalRootLocation)
.add("jarInputs", jarInputs)
.add("folderInputs", directoryInputs)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/IntermediateStream.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/IntermediateStream.java
index bb20c17..04b9440 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/IntermediateStream.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/IntermediateStream.java
@@ -22,7 +22,7 @@
import com.android.build.api.transform.QualifiedContent.Scope;
import com.android.build.api.transform.TransformInput;
import com.android.build.api.transform.TransformOutputProvider;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -157,7 +157,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("rootLocation", rootLocation.get())
.add("scopes", getScopes())
.add("contentTypes", getContentTypes())
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/OriginalStream.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/OriginalStream.java
index b076fe6..7ed8d9d 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/OriginalStream.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/OriginalStream.java
@@ -29,7 +29,7 @@
import com.android.build.api.transform.Status;
import com.android.build.api.transform.TransformInput;
import com.google.common.base.Charsets;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
@@ -265,7 +265,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("jarFiles", jarFiles.get())
.add("folders", folders.get())
.add("scopes", getScopes())
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/QualifiedContentImpl.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/QualifiedContentImpl.java
index 2749244..3875809 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/QualifiedContentImpl.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/pipeline/QualifiedContentImpl.java
@@ -19,7 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.concurrency.Immutable;
import com.android.build.api.transform.QualifiedContent;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import java.io.File;
@@ -84,7 +84,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", name)
.add("file", file)
.add("contentTypes", contentTypes)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/profile/RecordingBuildListener.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/profile/RecordingBuildListener.java
index a6d7f07..14e0b3a 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/profile/RecordingBuildListener.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/profile/RecordingBuildListener.java
@@ -38,7 +38,7 @@
@NonNull
private final Recorder mRecorder;
- // map of outstanding tasks executing, keyed by their name.
+ // map of outstanding tasks executing, keyed by their path.
@NonNull
private final Map<String, GradleBuildProfileSpan.Builder> mTaskRecords =
new ConcurrentHashMap<>();
@@ -54,12 +54,12 @@
builder.setId(mRecorder.allocationRecordId());
builder.setStartTimeInMs(System.currentTimeMillis());
- mTaskRecords.put(task.getName(), builder);
+ mTaskRecords.put(task.getPath(), builder);
}
@Override
public void afterExecute(@NonNull Task task, @NonNull TaskState taskState) {
- GradleBuildProfileSpan.Builder record = mTaskRecords.get(task.getName());
+ GradleBuildProfileSpan.Builder record = mTaskRecords.remove(task.getPath());
record.setDurationInMs(System.currentTimeMillis() - record.getStartTimeInMs());
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/scope/AndroidTask.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/scope/AndroidTask.java
index ad93df5..0db37e6 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/scope/AndroidTask.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/scope/AndroidTask.java
@@ -18,7 +18,7 @@
import com.android.annotations.NonNull;
import com.android.build.gradle.internal.TaskFactory;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import org.gradle.api.Action;
@@ -178,7 +178,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("name", name)
.add("taskType", taskType)
.toString();
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/PrepareAtomTask.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/PrepareAtomTask.java
deleted file mode 100644
index ab4c35f..0000000
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/PrepareAtomTask.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.android.build.gradle.internal.tasks;
-
-import com.android.build.gradle.internal.AtomCache;
-
-import org.gradle.api.tasks.InputFile;
-import org.gradle.api.tasks.OutputDirectory;
-import org.gradle.api.tasks.ParallelizableTask;
-import org.gradle.api.tasks.TaskAction;
-
-import java.io.File;
-
-@ParallelizableTask
-public class PrepareAtomTask extends DefaultAndroidTask {
- private File bundle;
- private File explodedDir;
-
- @TaskAction
- public void prepare() {
- AtomCache.unzipAtom(getBundle(), getExplodedDir(), getProject());
-
- // TODO: verify a classes.dex is present after we properly support atom dependencies.
- }
-
- @InputFile
- public File getBundle() {
- return bundle;
- }
-
- @OutputDirectory
- public File getExplodedDir() {
- return explodedDir;
- }
-
- public void setBundle(File bundle) {
- this.bundle = bundle;
- }
-
- public void setExplodedDir(File explodedDir) {
- this.explodedDir = explodedDir;
- }
-
-}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/databinding/DataBindingExportBuildInfoTask.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/databinding/DataBindingExportBuildInfoTask.java
index 34e2b27..bb49900 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/databinding/DataBindingExportBuildInfoTask.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/databinding/DataBindingExportBuildInfoTask.java
@@ -24,7 +24,6 @@
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.google.common.base.CharMatcher;
-import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.gradle.api.Action;
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/test/TestApplicationTestData.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/test/TestApplicationTestData.java
index add6129..2f6c3fe 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/test/TestApplicationTestData.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/test/TestApplicationTestData.java
@@ -33,7 +33,6 @@
import com.android.ide.common.process.ProcessExecutor;
import com.android.sdklib.BuildToolInfo;
import com.android.utils.ILogger;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -108,12 +107,7 @@
List<File> testedSplitApkFiles = getSplitApks();
List<String> testedSplitApksPath = Lists.transform(testedSplitApkFiles,
- new Function<File, String>() {
- @Override
- public String apply(@Nullable File file) {
- return file != null ? file.getAbsolutePath() : null;
- }
- });
+ file -> file != null ? file.getAbsolutePath() : null);
testedApks.addAll(
SplitOutputMatcher.computeBestOutput(processExecutor,
splitSelectExe,
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/InstantRunTransform.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/InstantRunTransform.java
index 889ac30..bf5088e 100755
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/InstantRunTransform.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/InstantRunTransform.java
@@ -39,7 +39,6 @@
import com.android.build.gradle.internal.incremental.IncrementalVisitor;
import com.android.build.gradle.internal.incremental.InstantRunBuildContext;
import com.android.build.gradle.internal.incremental.InstantRunBuildMode;
-import com.android.build.gradle.internal.incremental.InstantRunVerifier;
import com.android.build.gradle.internal.incremental.InstantRunVerifierStatus;
import com.android.build.gradle.internal.pipeline.ExtendedContentType;
import com.android.build.gradle.internal.pipeline.TransformManager;
@@ -53,12 +52,6 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
-
-import org.gradle.api.logging.Logging;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -69,6 +62,10 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.gradle.api.logging.Logging;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
/**
* Implementation of the {@link Transform} to run the byte code enhancement logic on compiled
@@ -186,73 +183,77 @@
}
for (TransformInput input : invocation.getInputs()) {
- for (DirectoryInput directoryInput : input.getDirectoryInputs()) {
- File inputDir = directoryInput.getFile();
- if (invocation.isIncremental()) {
- for (Map.Entry<File, Status> fileEntry : directoryInput.getChangedFiles()
- .entrySet()) {
+ input.getDirectoryInputs().parallelStream().forEach(directoryInput -> {
+ try {
+ File inputDir = directoryInput.getFile();
+ if (invocation.isIncremental()) {
+ for (Map.Entry<File, Status> fileEntry : directoryInput.getChangedFiles()
+ .entrySet()) {
- File inputFile = fileEntry.getKey();
- if (!inputFile.getName().endsWith(SdkConstants.DOT_CLASS))
- continue;
- switch (fileEntry.getValue()) {
- case ADDED:
- // a new file was added, we only generate the classes.2 format
- transformToClasses2Format(
- inputDir,
- inputFile,
- classesTwoOutput,
- Status.ADDED);
- break;
- case REMOVED:
- // remove the classes.2 and classes.3 files.
- deleteOutputFile(IncrementalSupportVisitor.VISITOR_BUILDER,
- inputDir, inputFile, classesTwoOutput);
- deleteOutputFile(IncrementalChangeVisitor.VISITOR_BUILDER,
- inputDir, inputFile, classesThreeOutput);
- break;
- case CHANGED:
- transformToClasses2Format(
- inputDir,
- inputFile,
- classesTwoOutput,
- Status.CHANGED);
+ File inputFile = fileEntry.getKey();
+ if (!inputFile.getName().endsWith(SdkConstants.DOT_CLASS))
+ continue;
+ switch (fileEntry.getValue()) {
+ case ADDED:
+ // a new file was added, we only generate the classes.2 format
+ transformToClasses2Format(
+ inputDir,
+ inputFile,
+ classesTwoOutput,
+ Status.ADDED);
+ break;
+ case REMOVED:
+ // remove the classes.2 and classes.3 files.
+ deleteOutputFile(IncrementalSupportVisitor.VISITOR_BUILDER,
+ inputDir, inputFile, classesTwoOutput);
+ deleteOutputFile(IncrementalChangeVisitor.VISITOR_BUILDER,
+ inputDir, inputFile, classesThreeOutput);
+ break;
+ case CHANGED:
+ transformToClasses2Format(
+ inputDir,
+ inputFile,
+ classesTwoOutput,
+ Status.CHANGED);
- if (!cleanUpClassesThree) {
- transformToClasses3Format(
- inputDir,
- inputFile,
- classesThreeOutput);
- }
- break;
- case NOTCHANGED:
- break;
- default:
- throw new IllegalStateException("Unhandled file status "
- + fileEntry.getValue());
- }
- }
- } else {
- // non incremental mode, we need to traverse the TransformInput#getFiles()
- // folder
- for (File file : Files.fileTreeTraverser().breadthFirstTraversal(inputDir)) {
- if (file.isDirectory()) {
- continue;
- }
+ if (!cleanUpClassesThree) {
+ transformToClasses3Format(
+ inputDir,
+ inputFile,
+ classesThreeOutput);
+ }
+ break;
+ case NOTCHANGED:
+ break;
+ default:
+ throw new IllegalStateException("Unhandled file status "
+ + fileEntry.getValue());
+ }
+ }
+ } else {
+ // non incremental mode, we need to traverse the TransformInput#getFiles()
+ // folder
+ for (File file : Files.fileTreeTraverser().breadthFirstTraversal(inputDir)) {
+ if (file.isDirectory()) {
+ continue;
+ }
- try {
- transformToClasses2Format(
- inputDir,
- file,
- classesTwoOutput,
- Status.ADDED);
- } catch (IOException e) {
- throw new RuntimeException("Exception while preparing "
- + file.getAbsolutePath());
- }
- }
- }
- }
+ try {
+ transformToClasses2Format(
+ inputDir,
+ file,
+ classesTwoOutput,
+ Status.ADDED);
+ } catch (IOException e) {
+ throw new RuntimeException("Exception while preparing "
+ + file.getAbsolutePath());
+ }
+ }
+ }
+ } catch (IOException x) {
+ throw new RuntimeException(x); // Lambdas don't like checked exceptions.
+ }
+ });
}
wrapUpOutputs(classesTwoOutput, classesThreeOutput);
@@ -385,6 +386,7 @@
if (outputFile == null) {
transformScope.getInstantRunBuildContext().setVerifierStatus(
InstantRunVerifierStatus.INSTANT_RUN_DISABLED);
+ LOGGER.info("Class %s cannot be hot swapped.", inputFile);
return;
}
generatedClasses3Names.add(
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/JackTransform.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/JackTransform.java
index 24c5b70..2464f29 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/JackTransform.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/transforms/JackTransform.java
@@ -151,7 +151,7 @@
params.put("javaResourcesFolder", options.getResourceDirectories());
params.put("isDebugLog", options.isDebugLog());
params.put("multiDexEnabled", options.isMultiDex());
- params.put("minSdkVersion", options.getMinSdkVersion());
+ params.put("minSdkVersion", options.getMinSdkVersion().getApiString());
params.put("javaMaxHeapSize", options.getJavaMaxHeapSize());
params.put("sourceCompatibility", options.getSourceCompatibility());
params.put("buildToolsRev",
@@ -223,7 +223,9 @@
JackToolchain toolchain =
new JackToolchain(
- androidBuilder.getTargetInfo().getBuildTools(), androidBuilder.getLogger());
+ androidBuilder.getTargetInfo().getBuildTools(),
+ androidBuilder.getLogger(),
+ androidBuilder.getErrorReporter());
toolchain.convert(options, androidBuilder.getJavaProcessExecutor(), jackInProcess);
}
@@ -266,7 +268,7 @@
options.setDebuggable(isDebuggable);
options.setDexOptimize(true);
options.setMultiDex(config.isMultiDexEnabled());
- options.setMinSdkVersion(config.getMinSdkVersion().getApiLevel());
+ options.setMinSdkVersion(config.getMinSdkVersion());
options.setOutputFile(scope.getJackClassesZip());
options.setResourceDirectories(ImmutableList.of(scope.getJavaResourcesDestinationDir()));
@@ -314,18 +316,7 @@
jackInProcess = isInProcess(config.getJackOptions().isJackInProcess());
if (config.getBuildType().isTestCoverageEnabled()) {
- if (JackProcessOptions.COVERAGE_BROKEN.contains(
- androidBuilder.getTargetInfo().getBuildTools().getRevision())) {
- androidBuilder
- .getErrorReporter()
- .handleSyncWarning(
- null,
- SyncIssue.TYPE_GENERIC,
- "Test coverage is disabled for Jack. Next versions of build tools "
- + "will fix this issue.");
- } else {
- options.setCoverageMetadataFile(scope.getJackCoverageMetadataFile());
- }
+ options.setCoverageMetadataFile(scope.getJackCoverageMetadataFile());
}
if (config.isMinifyEnabled()) {
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/BaseVariantData.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/BaseVariantData.java
index b49413f..cb60cb5 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/BaseVariantData.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/BaseVariantData.java
@@ -52,7 +52,7 @@
import com.android.ide.common.blame.SourceFile;
import com.android.ide.common.res2.ResourceSet;
import com.android.utils.StringHelper;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -705,7 +705,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.addValue(variantConfiguration.getFullName())
.toString();
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/Dependency.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/Dependency.java
index d705568..a130341 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/Dependency.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/Dependency.java
@@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import com.android.annotations.NonNull;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import java.io.Serializable;
@@ -54,7 +55,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("target", target)
.add("type", type)
.toString();
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/PostProcessingData.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/PostProcessingData.java
index 2dcb86e..ae04729 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/PostProcessingData.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/shrinker/PostProcessingData.java
@@ -17,7 +17,7 @@
package com.android.build.gradle.shrinker;
import com.android.annotations.NonNull;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import java.util.Set;
@@ -84,7 +84,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("method", method)
.add("target", target)
.add("invokespecial", invokespecial)
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/BundleAtom.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/BundleAtom.java
index a7df0d5..0c502ac 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/BundleAtom.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/BundleAtom.java
@@ -30,7 +30,6 @@
import com.android.build.gradle.internal.tasks.DefaultAndroidTask;
import com.android.build.gradle.internal.tasks.FileSupplier;
import com.android.utils.FileUtils;
-import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -51,57 +50,68 @@
*/
public class BundleAtom extends DefaultAndroidTask implements FileSupplier {
+ private static void deleteDirectoryContents(@NonNull File directory) throws IOException {
+ if (!directory.exists()) {
+ FileUtils.mkdirs(directory);
+ } else if (!directory.isDirectory()) {
+ FileUtils.delete(directory);
+ FileUtils.mkdirs(directory);
+ } else {
+ FileUtils.deleteDirectoryContents(directory);
+ }
+ }
+
@TaskAction
public void taskAction() throws IOException {
- // Map of files to be bundled with their internal bundle location.
- ImmutableSet.Builder<ZipFileLocation> fileListBuilder = ImmutableSet.builder();
+ File bundleFolder = getBundleFolder();
- // Find all the native libs to be bundled.
+ // Copy all the native libs to be bundled.
+ File libBundleFolder = new File(bundleFolder, FD_NATIVE_LIBS);
+ deleteDirectoryContents(libBundleFolder);
for (File jniFolder : getJniFolders()) {
for (File lib : FileUtils.find(jniFolder, Pattern.compile("\\.so$"))) {
- fileListBuilder.add(new ZipFileLocation(lib,
- FD_NATIVE_LIBS + "/" + FileUtils.relativePath(lib, jniFolder)));
+ File destLibFile =
+ new File(libBundleFolder, FileUtils.relativePath(lib, jniFolder));
+ FileUtils.copyFile(lib, destLibFile);
}
}
- // Find all the dex files to be bundled.
+ // Copy all the dex files to be bundled.
+ File dexBundleFolder = new File(bundleFolder, FD_DEX);
+ deleteDirectoryContents(dexBundleFolder);
for (File dexFolder : getDexFolders()) {
for (File dexFile : FileUtils.find(dexFolder, Pattern.compile("\\.dex$"))) {
- fileListBuilder.add(new ZipFileLocation(dexFile,
- FD_DEX + "/" + dexFile.getName()));
+ File destDexFile = new File(dexBundleFolder, dexFile.getName());
+ FileUtils.copyFile(dexFile, destDexFile);
}
}
- // Find all the other files to be bundled.
- for (File file : FileUtils.getAllFiles(getBundleFolder())) {
- fileListBuilder.add(new ZipFileLocation(file,
- FileUtils.relativePath(file, getBundleFolder())));
+ // Copy all the java resource files to be bundled.
+ File javaResBundleFolder = new File(bundleFolder, FD_JAVA_RES);
+ deleteDirectoryContents(javaResBundleFolder);
+ for (File javaResFolder : getJavaResFolders()) {
+ for (File javaResFile : FileUtils.getAllFiles(javaResFolder)) {
+ File destJavaResFile =
+ new File(
+ javaResBundleFolder,
+ FileUtils.relativePath(javaResFile, javaResBundleFolder));
+ FileUtils.copyFile(javaResFile, destJavaResFile);
+ }
}
// Bundle all the files in the output bundle.
try (ZipOutputStream zipOutputStream =
new ZipOutputStream(new FileOutputStream(getBundleFile()))) {
- // Ensure all the directories are always created even if they are empty.
- zipOutputStream.putNextEntry(new ZipEntry(FD_JAVA_RES + "/"));
- zipOutputStream.closeEntry();
- zipOutputStream.putNextEntry(new ZipEntry(FD_RES + "/"));
- zipOutputStream.closeEntry();
- zipOutputStream.putNextEntry(new ZipEntry(FD_NATIVE_LIBS + "/"));
- zipOutputStream.closeEntry();
- zipOutputStream.putNextEntry(new ZipEntry(FD_ASSETS + "/"));
- zipOutputStream.closeEntry();
- zipOutputStream.putNextEntry(new ZipEntry(FD_DEX + "/"));
- zipOutputStream.closeEntry();
-
- for (ZipFileLocation entry : fileListBuilder.build()) {
- try (FileInputStream fileInputStream = new FileInputStream(entry.file)) {
+ // Find all the other files to be bundled.
+ for (File file : FileUtils.getAllFiles(bundleFolder)) {
+ try (FileInputStream fileInputStream = new FileInputStream(file)) {
byte[] inputBuffer = IOUtils.toByteArray(fileInputStream);
- zipOutputStream.putNextEntry(new ZipEntry(entry.path));
+ zipOutputStream.putNextEntry(
+ new ZipEntry(FileUtils.relativePath(file, bundleFolder)));
zipOutputStream.write(inputBuffer, 0, inputBuffer.length);
zipOutputStream.closeEntry();
}
}
- zipOutputStream.close();
}
}
@@ -169,16 +179,6 @@
return getBundleFile();
}
- private static class ZipFileLocation {
- private ZipFileLocation(File file, String path) {
- this.file = file;
- this.path = path;
- }
-
- private File file;
- private String path;
- }
-
public static class ConfigAction implements TaskConfigAction<BundleAtom> {
public ConfigAction(@NonNull VariantScope scope) {
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/JackPreDexTransform.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/JackPreDexTransform.java
index 7cb3e36..fd23713 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/JackPreDexTransform.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/JackPreDexTransform.java
@@ -33,6 +33,7 @@
import com.android.builder.core.JackProcessOptions;
import com.android.builder.core.JackToolchain;
import com.android.builder.internal.compiler.JackConversionCache;
+import com.android.builder.model.ApiVersion;
import com.android.ide.common.process.ProcessException;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
@@ -54,20 +55,28 @@
*/
public class JackPreDexTransform extends Transform {
- private AndroidBuilder androidBuilder;
- private String javaMaxHeapSize;
+ @NonNull private AndroidBuilder androidBuilder;
+ @Nullable private String javaMaxHeapSize;
private boolean forPackagedLibs;
@NonNull
private CoreJackOptions coreJackOptions;
+ @NonNull private ApiVersion minSdkVersion;
+
+ /** Gets the builder object for this class. */
+ public static Builder builder() {
+ return new Builder();
+ }
public JackPreDexTransform(
@NonNull AndroidBuilder androidBuilder,
@Nullable String javaMaxHeapSize,
@NonNull CoreJackOptions coreJackOptions,
+ @NonNull ApiVersion minSdkVersion,
boolean forPackagedLibs) {
this.androidBuilder = androidBuilder;
this.javaMaxHeapSize = javaMaxHeapSize;
this.coreJackOptions = coreJackOptions;
+ this.minSdkVersion = minSdkVersion;
this.forPackagedLibs = forPackagedLibs;
}
@@ -151,6 +160,7 @@
options.setOutputFile(outFile);
options.setJavaMaxHeapSize(javaMaxHeapSize);
options.setAdditionalParameters(coreJackOptions.getAdditionalParameters());
+ options.setMinSdkVersion(minSdkVersion);
JackConversionCache.getCache().convertLibrary(
androidBuilder,
@@ -188,4 +198,53 @@
public boolean isForRuntimeLibs() {
return !forPackagedLibs;
}
+
+ /** Builder class for {@link com.android.build.gradle.tasks.JackPreDexTransform}. */
+ public static class Builder {
+
+ private AndroidBuilder androidBuilder;
+ private String javaMaxHeapSize;
+ private CoreJackOptions coreJackOptions;
+ private Boolean forPackagedLibs;
+ private ApiVersion minApiVersion;
+
+ public Builder androidBuilder(@NonNull AndroidBuilder androidBuilder) {
+ this.androidBuilder = androidBuilder;
+ return this;
+ }
+
+ public Builder javaMaxHeapSize(@Nullable String javaMaxHeapSize) {
+ this.javaMaxHeapSize = javaMaxHeapSize;
+ return this;
+ }
+
+ public Builder coreJackOptions(@NonNull CoreJackOptions coreJackOptions) {
+ this.coreJackOptions = coreJackOptions;
+ return this;
+ }
+
+ public Builder forPackagedLibs() {
+ this.forPackagedLibs = true;
+ return this;
+ }
+
+ public Builder forClasspathLibs() {
+ this.forPackagedLibs = false;
+ return this;
+ }
+
+ public Builder minApiVersion(@NonNull ApiVersion minApiVersion) {
+ this.minApiVersion = minApiVersion;
+ return this;
+ }
+
+ public JackPreDexTransform create() {
+ return new JackPreDexTransform(
+ androidBuilder,
+ javaMaxHeapSize,
+ coreJackOptions,
+ minApiVersion,
+ forPackagedLibs);
+ }
+ }
}
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/external/gnumake/NdkSampleTest.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/external/gnumake/NdkSampleTest.java
index 8a4bfd5..1b95eca 100755
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/external/gnumake/NdkSampleTest.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/external/gnumake/NdkSampleTest.java
@@ -574,11 +574,16 @@
@Test
public void google_test_example() throws IOException, InterruptedException {
NativeBuildConfigValue config = checkJson("samples/google-test-example");
- assertThat(config).hasExactLibraryOutputs(
- "{NDK}/debug/obj/local/arm64-v8a/libgoogletest_static.a",
- "{NDK}/debug/obj/local/arm64-v8a/sample1_unittest",
- "{NDK}/debug/obj/local/arm64-v8a/libsample1.so",
- "{NDK}/debug/obj/local/arm64-v8a/libgoogletest_main.a");
+ assertThat(config)
+ .hasExactLibraryOutputs(
+ FileUtils.toSystemDependentPath(
+ "{NDK}/debug/obj/local/arm64-v8a/libgoogletest_static.a"),
+ FileUtils.toSystemDependentPath(
+ "{NDK}/debug/obj/local/arm64-v8a/sample1_unittest"),
+ FileUtils.toSystemDependentPath(
+ "{NDK}/debug/obj/local/arm64-v8a/libsample1.so"),
+ FileUtils.toSystemDependentPath(
+ "{NDK}/debug/obj/local/arm64-v8a/libgoogletest_main.a"));
}
@Test
@@ -636,13 +641,20 @@
@Test
public void HelloComputeNDK() throws IOException, InterruptedException {
NativeBuildConfigValue config = checkJson("samples/HelloComputeNDK");
- assertThat(config).hasExactLibraryOutputs(
- "{ndkPath}/samples/HelloComputeNDK/obj/local/x86/libhellocomputendk.so",
- "{ndkPath}/samples/HelloComputeNDK/libs/armeabi-v7a/librs.mono.so",
- "{ndkPath}/samples/HelloComputeNDK/obj/local/mips/libhellocomputendk.so",
- "{ndkPath}/samples/HelloComputeNDK/libs/mips/librs.mono.so",
- "{ndkPath}/samples/HelloComputeNDK/libs/x86/librs.mono.so",
- "{ndkPath}/samples/HelloComputeNDK/obj/local/armeabi-v7a/libhellocomputendk.so");
+ assertThat(config)
+ .hasExactLibraryOutputs(
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/obj/local/x86/libhellocomputendk.so"),
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/libs/armeabi-v7a/librs.mono.so"),
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/obj/local/mips/libhellocomputendk.so"),
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/libs/mips/librs.mono.so"),
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/libs/x86/librs.mono.so"),
+ FileUtils.toSystemDependentPath(
+ "{ndkPath}/samples/HelloComputeNDK/obj/local/armeabi-v7a/libhellocomputendk.so"));
}
// input: support-files/ndk-sample-baselines/test-libstdc++.json
@Test
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/incremental/fixture/ClassEnhancement.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/incremental/fixture/ClassEnhancement.java
index cd39a36..fd483cc 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/incremental/fixture/ClassEnhancement.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/incremental/fixture/ClassEnhancement.java
@@ -23,7 +23,6 @@
import com.android.build.gradle.internal.incremental.IncrementalChangeVisitor;
import com.android.tools.fd.runtime.AndroidInstantRuntime;
import com.android.utils.FileUtils;
-import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
@@ -96,14 +95,11 @@
Files.fileTreeTraverser()
.preOrderTraversal(outputFolder)
.filter(Files.isFile());
- Iterable<String> classNames = Iterables.transform(files, new Function<File, String>() {
- @Override
- public String apply(File file) {
+ Iterable<String> classNames = Iterables.transform(files, (File file) -> {
String relativePath = FileUtils.relativePath(file, outputFolder);
return relativePath.substring(0, relativePath.length() - 6 /*.class */)
.replace(File.separatorChar, '.');
- }
- });
+ });
for (String changedClassName : classNames) {
if (changedClassName.endsWith("$override")) {
@@ -155,13 +151,14 @@
final ClassLoader mainClassLoader,
final Map<String, File> instrumentedPatches,
final boolean tracing) {
- return Maps.transformValues(instrumentedPatches, new Function<File, ClassLoader>() {
- @Override
- public ClassLoader apply(File instrumentedPatchFolder) {
- return new IncrementalChangeClassLoader(
- classLoaderUrls, mainClassLoader, instrumentedPatchFolder, tracing);
- }
- });
+ return Maps.transformValues(
+ instrumentedPatches,
+ (File instrumentedPatchFolder) ->
+ new IncrementalChangeClassLoader(
+ classLoaderUrls,
+ mainClassLoader,
+ instrumentedPatchFolder,
+ tracing));
}
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/profile/RecordingBuildListenerTest.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/profile/RecordingBuildListenerTest.java
index 365ced0..0093034 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/profile/RecordingBuildListenerTest.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/profile/RecordingBuildListenerTest.java
@@ -121,9 +121,12 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mProject.getPath()).thenReturn(":projectName");
- when(mTask.getName()).thenReturn("taskName");
+ when(mTask.getName()).thenThrow(new AssertionError("Nothing should be using task name"));
+ when(mTask.getPath()).thenReturn(":projectName:taskName");
when(mTask.getProject()).thenReturn(mProject);
- when(mSecondTask.getName()).thenReturn("task2Name");
+ when(mSecondTask.getPath()).thenReturn(":projectName:task2Name");
+ when(mSecondTask.getName())
+ .thenThrow(new AssertionError("Nothing should be using task name"));
when(mSecondTask.getProject()).thenReturn(mProject);
mProfileProtoFile = Jimfs.newFileSystem().getPath("profile_proto");
ProcessRecorderFactory.initializeForTests(mProfileProtoFile);
@@ -184,14 +187,15 @@
listener.beforeExecute(mTask);
listener.beforeExecute(mSecondTask);
- ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING,
- ":projectName", null, new Recorder.Block<Object>() {
- @Override
- public Object call() throws Exception {
- logger.verbose("useless block");
- return null;
- }
- });
+ ThreadRecorder.get()
+ .record(
+ ExecutionType.SOME_RANDOM_PROCESSING,
+ ":projectName",
+ null,
+ () -> {
+ logger.verbose("useless block");
+ return null;
+ });
listener.afterExecute(mTask, mTaskState);
listener.afterExecute(mSecondTask, mTaskState);
@@ -216,7 +220,7 @@
TestRecorder recorder = new TestRecorder();
RecordingBuildListener listener = new RecordingBuildListener(recorder);
Task secondTask = mock(Task.class);
- when(secondTask.getName()).thenReturn("secondTaskName");
+ when(secondTask.getPath()).thenReturn(":projectName:secondTaskName");
when(secondTask.getProject()).thenReturn(mProject);
// first thread start
@@ -247,7 +251,7 @@
TestRecorder recorder = new TestRecorder();
RecordingBuildListener listener = new RecordingBuildListener(recorder);
Task secondTask = mock(Task.class);
- when(secondTask.getName()).thenReturn("secondTaskName");
+ when(secondTask.getPath()).thenReturn(":projectName:secondTaskName");
when(secondTask.getProject()).thenReturn(mProject);
// first thread start
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/transforms/FileFilterTest.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/transforms/FileFilterTest.java
index af3c212..bcb7178 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/transforms/FileFilterTest.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/transforms/FileFilterTest.java
@@ -24,20 +24,17 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.internal.dsl.PackagingOptions;
-import com.android.utils.FileUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
/**
* Tests for {@link FileFilter}
@@ -99,7 +96,7 @@
@Test
public void testSimpleExclusion() throws IOException {
- setExcludes(ImmutableSet.of(FileUtils.join("foo", "text.properties")));
+ setExcludes(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -110,7 +107,7 @@
@Test
public void testExclusionFromMultipleFiles() throws IOException {
- setExcludes(ImmutableSet.of(FileUtils.join("foo", "text.properties")));
+ setExcludes(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -122,9 +119,7 @@
@Test
public void testMultipleExclusions() throws IOException {
- setExcludes(ImmutableSet.of(
- FileUtils.join("foo", "text.properties"),
- FileUtils.join("bar", "other.properties")));
+ setExcludes(ImmutableSet.of("foo/text.properties", "bar/other.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -136,9 +131,7 @@
@Test
public void textNonExclusion() throws IOException {
- setExcludes(ImmutableSet.of(
- FileUtils.join("foo", "text.properties"),
- FileUtils.join("bar", "other.properties")));
+ setExcludes(ImmutableSet.of("foo/text.properties", "bar/other.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -153,8 +146,7 @@
@Test
public void testSingleMerge() throws IOException {
- setMerges(ImmutableSet.of(
- FileUtils.join("foo", "text.properties")));
+ setMerges(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -174,8 +166,7 @@
@Test
public void testMultipleMerges() throws IOException {
- setMerges(ImmutableSet.of(
- FileUtils.join("foo" , "text.properties")));
+ setMerges(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -196,8 +187,7 @@
@Test
public void testMergeAddon() throws IOException {
- setMerges(ImmutableSet.of(
- FileUtils.join("foo", "text.properties")));
+ setMerges(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -226,8 +216,7 @@
@Test
public void testMergeUpdate() throws IOException {
- setMerges(ImmutableSet.of(
- FileUtils.join("foo", "text.properties")));
+ setMerges(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -259,8 +248,7 @@
@Test
public void testMergeRemoval() throws IOException {
- setMerges(ImmutableSet.of(
- FileUtils.join("foo", "text.properties")));
+ setMerges(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
@@ -275,13 +263,13 @@
File mergedFile = new File(mMergedFolder, "foo/text.properties");
assertTrue(mergedFile.exists());
assertContentInAnyOrder(
- Files.asCharSource(mergedFile, Charset.defaultCharset()).read()
- , ImmutableList.of("one", "two", "three"));
+ Files.asCharSource(mergedFile, Charset.defaultCharset()).read(),
+ ImmutableList.of("one", "two", "three"));
// remove one...
assertTrue(secondFile.delete());
- mFileFilter.handleRemoved(mMergedFolder, FileUtils.join("foo", "text.properties"));
+ mFileFilter.handleRemoved(mMergedFolder, "foo/text.properties");
assertTrue(mergedFile.exists());
assertContentInAnyOrder(
@@ -353,8 +341,7 @@
@Test
public void testPickFirstRemoval() throws IOException {
- setPickFirsts(ImmutableSet.of(
- FileUtils.join("foo", "text.properties")));
+ setPickFirsts(ImmutableSet.of("foo/text.properties"));
mFileFilter = new FileFilter(
mPackagedJarExpansionSubStreams,
mPackagingOptions);
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/ExtractAnnotationsDriverTest.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/ExtractAnnotationsDriverTest.java
index ced0be0..33b94f5 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/ExtractAnnotationsDriverTest.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/ExtractAnnotationsDriverTest.java
@@ -21,26 +21,24 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import com.android.annotations.NonNull;
+import com.android.testutils.TestUtils;
import com.android.utils.FileUtils;
import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
-
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.junit.AssumptionViolatedException;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.junit.AssumptionViolatedException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
public class ExtractAnnotationsDriverTest {
@@ -64,7 +62,7 @@
public void testProGuard() throws Exception {
checkValidEcj();
- File androidJar = findAndroidJar(false);
+ File androidJar = findAndroidJar();
File project = createProject(mKeepTest, mKeepAnnotation);
@@ -115,7 +113,7 @@
public void testIncludeClassRetention() throws Exception {
checkValidEcj();
- File androidJar = findAndroidJar(false);
+ File androidJar = findAndroidJar();
File project = createProject(
mIntDefTest,
@@ -134,7 +132,6 @@
new File(project, "src").getPath(),
"--classpath",
androidJar.getPath(),
-
"--quiet",
"--language-level",
"1.6",
@@ -197,7 +194,7 @@
public void testSkipClassRetention() throws Exception {
checkValidEcj();
- File androidJar = findAndroidJar(false);
+ File androidJar = findAndroidJar();
File project = createProject(
mIntDefTest,
@@ -216,7 +213,6 @@
new File(project, "src").getPath(),
"--classpath",
androidJar.getPath(),
-
"--quiet",
"--skip-class-retention",
"--language-level",
@@ -252,7 +248,6 @@
+ "</root>\n"
+ "\n");
-
deleteFile(project);
}
@@ -260,7 +255,7 @@
public void testWriteJarRecipeFile() throws Exception {
checkValidEcj();
- File androidJar = findAndroidJar(false);
+ File androidJar = findAndroidJar();
File project = createProject(
mIntDefTest,
@@ -502,7 +497,7 @@
try {
byte[] bytes = ByteStreams.toByteArray(stream);
assertNotNull(bytes);
- String xml = new String(bytes, Charsets.UTF_8);
+ String xml = new String(bytes, Charsets.UTF_8).replace("\r\n", "\n");
assertEquals(expected, xml);
} finally {
Closeables.closeQuietly(stream);
@@ -510,19 +505,10 @@
}
@NonNull
- private static File findAndroidJar(boolean requireExists) {
- String androidHomePath = System.getenv("ANDROID_HOME");
- assertNotNull("Must set $ANDROID_HOME to run this test", androidHomePath);
- File androidHome = new File(androidHomePath);
- if (!androidHome.exists()) {
- if (!requireExists) {
- throw new AssumptionViolatedException("Android jar not present");
- }
- fail(androidHomePath + " does not exist");
- }
- File androidJar = new File(androidHome, "platforms/android-22/android.jar");
+ private static File findAndroidJar() {
+ File androidJar = TestUtils.getPlatformFile("android.jar");
assertTrue(
- androidJar + " does not exist: make sure you have Lollipop installed in your SDK",
+ androidJar + " does not exist: make sure you have android N installed in your SDK",
androidJar.exists());
return androidJar;
}
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/TypedefRemoverTest.java b/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/TypedefRemoverTest.java
index f4a9477..6043ea2 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/TypedefRemoverTest.java
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/tasks/annotations/TypedefRemoverTest.java
@@ -21,17 +21,15 @@
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
public class TypedefRemoverTest {
@Rule
@@ -119,7 +117,6 @@
assertThat(filtered).isNotNull();
assertThat(filtered).isNotSameAs(input);
byte[] rewritten = ByteStreams.toByteArray(filtered);
- Files.write(rewritten, new File("/tmp/rewritten.class"));
assertThat(rewritten).isNotEqualTo(outerClass);
assertThat(rewritten).isEqualTo(REWRITTEN_OUTER_CLASS);
diff --git a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
index f37f7b2..df26ff0 100644
--- a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
+++ b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
@@ -28,6 +28,7 @@
import org.gradle.nativeplatform.platform.NativePlatform;
+import java.util.Collection;
import java.util.Map;
/**
@@ -118,6 +119,7 @@
"-fomit-frame-pointer",
"-fstrict-aliasing"))
.putAll(SdkConstants.ABI_MIPS, ImmutableList.of(
+ "-mips32",
"-fpic",
"-fno-strict-aliasing",
"-ffunction-sections",
@@ -210,11 +212,19 @@
@Override
public Iterable<String> getLdFlags() {
- return Iterables.concat(
- getTargetFlags(),
- platform.getName().equals(SdkConstants.ABI_ARMEABI_V7A)
- ? ImmutableList.of("-Wl,--fix-cortex-a8")
- : ImmutableList.<String>of());
+ Collection<String> flags;
+
+ switch (platform.getName()) {
+ case SdkConstants.ABI_ARMEABI_V7A:
+ flags = ImmutableList.of("-Wl,--fix-cortex-a8");
+ break;
+ case SdkConstants.ABI_MIPS:
+ flags = ImmutableList.of("-mips32");
+ break;
+ default:
+ flags = ImmutableList.of();
+ }
+ return Iterables.concat(getTargetFlags(), flags);
}
private Iterable<String> getTargetFlags() {
diff --git a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
index 9b42bff..52b0af9 100644
--- a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
+++ b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
@@ -102,6 +102,7 @@
"-funswitch-loops",
"-finline-limit=300"))
.putAll(SdkConstants.ABI_MIPS, ImmutableList.of(
+ "-mips32",
"-fpic",
"-fno-strict-aliasing",
"-finline-functions",
@@ -193,7 +194,7 @@
public Iterable<String> getCFlags() {
return Iterables.concat(
RELEASE_CFLAGS.get(platform.getName()),
- (isDebugBuild ? DEBUG_CFLAGS.get(platform.getName()) : ImmutableList.<String>of()));
+ (isDebugBuild ? DEBUG_CFLAGS.get(platform.getName()) : ImmutableList.of()));
}
@Override
@@ -203,6 +204,9 @@
@Override
public Iterable<String> getLdFlags() {
+ if (platform.getName().equals(SdkConstants.ABI_MIPS)) {
+ return Iterables.concat(LDFLAGS, ImmutableList.of("-mips32"));
+ }
return LDFLAGS;
}
}
diff --git a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ToolchainConfiguration.java b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ToolchainConfiguration.java
index 6350a9c..39c1730 100644
--- a/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ToolchainConfiguration.java
+++ b/build-system/gradle-experimental/src/main/java/com/android/build/gradle/ndk/internal/ToolchainConfiguration.java
@@ -76,11 +76,14 @@
}
if (Toolchain.GCC == ndkToolchain) {
- String gccPrefix = abi.getGccExecutablePrefix();
- targetPlatform.getcCompiler().setExecutable(gccPrefix + "-gcc");
- targetPlatform.getCppCompiler().setExecutable(gccPrefix + "-g++");
- targetPlatform.getLinker().setExecutable(gccPrefix + "-g++");
- targetPlatform.getAssembler().setExecutable(gccPrefix + "-as");
+ targetPlatform.getcCompiler().setExecutable(
+ ndkHandler.getCCompiler(abi).getName());
+ targetPlatform.getCppCompiler().setExecutable(
+ ndkHandler.getCppCompiler(abi).getName());
+ targetPlatform.getLinker().setExecutable(
+ ndkHandler.getLinker(abi).getName());
+ targetPlatform.getAssembler().setExecutable(
+ ndkHandler.getAssembler(abi).getName());
}
// For clang, we use the ar from the GCC toolchain.
targetPlatform.getStaticLibArchiver().setExecutable(
diff --git a/build-system/gradle/src/main/java/com/android/build/gradle/BasePlugin.java b/build-system/gradle/src/main/java/com/android/build/gradle/BasePlugin.java
index f04b4f9..11f6fa6 100644
--- a/build-system/gradle/src/main/java/com/android/build/gradle/BasePlugin.java
+++ b/build-system/gradle/src/main/java/com/android/build/gradle/BasePlugin.java
@@ -125,7 +125,9 @@
*/
public abstract class BasePlugin implements ToolingRegistryProvider {
- private static final GradleVersion GRADLE_MIN_VERSION = GradleVersion.parse("2.14.1");
+ @VisibleForTesting
+ public static final GradleVersion GRADLE_MIN_VERSION = GradleVersion.parse("2.14.1");
+
/** default retirement age in days since its inception date for RC or beta versions. */
private static final int DEFAULT_RETIREMENT_AGE_FOR_NON_RELEASE_IN_DAYS = 40;
diff --git a/build-system/integration-test/build.gradle b/build-system/integration-test/build.gradle
index d3c83b0..c1bd94f 100755
--- a/build-system/integration-test/build.gradle
+++ b/build-system/integration-test/build.gradle
@@ -18,13 +18,15 @@
compile gradleApi()
compile localGroovy()
compile project(':analytics-library:protos')
- compile project(':base:builder-model')
compile project(':base:builder')
- compile project(':base:sdk-common')
- compile project(':base:lint')
+ compile project(':base:builder-model')
+ compile project(':base:gradle')
+ compile project(':base:gradle-experimental')
compile project(':base:instant-run:instant-run-client')
- compile project(':base:testutils')
+ compile project(':base:lint')
+ compile project(':base:sdk-common')
compile project(':base:testing-infrastructure:device-pool:device-provider')
+ compile project(':base:testutils')
compile "junit:junit:4.12"
compile 'commons-io:commons-io:2.4'
@@ -181,9 +183,11 @@
junitXml.destination "${project.buildDir}/perf-results"
}
outputs.upToDateWhen { false }
-}
-performanceTest.dependsOn test
+ testLogging {
+ exceptionFormat = 'full'
+ }
+}
task buildTestDependencies {
dependsOn ':base:gradle-core:instrumentIncrementalTestPatches',
diff --git a/build-system/integration-test/integration-test.iml b/build-system/integration-test/integration-test.iml
index 707a5a0..2137d9a 100755
--- a/build-system/integration-test/integration-test.iml
+++ b/build-system/integration-test/integration-test.iml
@@ -39,5 +39,6 @@
<orderEntry type="module" module-name="analytics-protos-base" scope="TEST" />
<orderEntry type="library" name="protobuf" level="project" />
<orderEntry type="library" name="google-api-client" level="project" />
+ <orderEntry type="module" module-name="gradle-experimental" />
</component>
</module>
\ No newline at end of file
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/BaseGradleExecutor.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/BaseGradleExecutor.java
index 2ace5cc..4ac2678 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/BaseGradleExecutor.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/BaseGradleExecutor.java
@@ -25,14 +25,12 @@
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.wireless.android.sdk.gradlelogging.proto.Logging;
-
-import org.gradle.tooling.LongRunningOperation;
-import org.gradle.tooling.ProjectConnection;
-
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+import org.gradle.tooling.LongRunningOperation;
+import org.gradle.tooling.ProjectConnection;
/**
* Common flags shared by {@link BuildModel} and {@link RunGradleTasks}.
@@ -55,7 +53,7 @@
@Nullable Logging.BenchmarkMode benchmarkMode;
- boolean enableInfoLogging = true;
+ boolean enableInfoLogging;
BaseGradleExecutor(
@NonNull ProjectConnection projectConnection,
@@ -63,6 +61,7 @@
@Nullable BenchmarkRecorder benchmarkRecorder,
@Nullable String heapSize) {
this.benchmarkRecorder = benchmarkRecorder;
+ this.enableInfoLogging = benchmarkRecorder == null;
this.projectConnection = projectConnection;
if (!buildDotGradleFile.getName().equals("build.gradle")) {
arguments.add("--build-file=" + buildDotGradleFile.getPath());
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/GradleTestProject.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/GradleTestProject.java
index 9dd0340..e7135d6 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/GradleTestProject.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/GradleTestProject.java
@@ -23,10 +23,11 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.AndroidGradleOptions;
+import com.android.build.gradle.BasePlugin;
import com.android.build.gradle.integration.performance.BenchmarkRecorder;
+import com.android.build.gradle.model.Version;
import com.android.builder.core.BuilderConstants;
import com.android.builder.model.AndroidProject;
-import com.android.builder.model.Version;
import com.android.io.StreamException;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
@@ -53,6 +54,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -87,14 +89,15 @@
public static final int LAST_JAVA6_SDK_VERSION = 19;
public static final String DEFAULT_BUILD_TOOL_VERSION;
- public static final String UPCOMING_BUILD_TOOL_VERSION = "24.0.3";
+ public static final String UPCOMING_BUILD_TOOL_VERSION = "25.0.0";
public static final String REMOTE_TEST_PROVIDER = System.getenv().get("REMOTE_TEST_PROVIDER");
- public static final String DEVICE_PROVIDER_NAME = REMOTE_TEST_PROVIDER != null ?
- REMOTE_TEST_PROVIDER : BuilderConstants.CONNECTED;
+ public static final String DEVICE_PROVIDER_NAME =
+ REMOTE_TEST_PROVIDER != null ? REMOTE_TEST_PROVIDER : BuilderConstants.CONNECTED;
- public static final String GRADLE_TEST_VERSION = "2.14.1";
- public static final String GRADLE_EXP_TEST_VERSION = "2.14.1";
+ public static final String GRADLE_TEST_VERSION;
+ public static final String GRADLE_EXP_TEST_VERSION;
+ public static final String GRADLE_NIGHTLY_VERSION = "3.3-20161020000024+0000";
public static final String ANDROID_GRADLE_PLUGIN_VERSION;
@@ -105,12 +108,20 @@
private static final int MAX_TEST_NAME_DIR_WINDOWS = 100;
static {
+ boolean useNightly =
+ Boolean.parseBoolean(System.getenv().getOrDefault("USE_GRADLE_NIGHTLY", "false"));
+ GRADLE_TEST_VERSION =
+ useNightly ? GRADLE_NIGHTLY_VERSION : BasePlugin.GRADLE_MIN_VERSION.toString();
+
+ // For now, the two are in sync.
+ GRADLE_EXP_TEST_VERSION = GRADLE_TEST_VERSION;
+
// These are some properties that we use in the integration test projects, when generating
// build.gradle files. In case you would like to change any of the parameters, for instance
// when testing cross product of versions of buildtools, compile sdks, plugin versions,
// there are corresponding system environment variable that you are able to set.
String envBuildToolVersion = Strings.emptyToNull(System.getenv("CUSTOM_BUILDTOOLS"));
- DEFAULT_BUILD_TOOL_VERSION = MoreObjects.firstNonNull(envBuildToolVersion, "24.0.3");
+ DEFAULT_BUILD_TOOL_VERSION = MoreObjects.firstNonNull(envBuildToolVersion, "25.0.0");
String envVersion = Strings.emptyToNull(System.getenv().get("CUSTOM_PLUGIN_VERSION"));
ANDROID_GRADLE_PLUGIN_VERSION =
@@ -120,7 +131,7 @@
USE_JACK = !Strings.isNullOrEmpty(envJack);
String envCustomCompileSdk = Strings.emptyToNull(System.getenv().get("CUSTOM_COMPILE_SDK"));
- DEFAULT_COMPILE_SDK_VERSION = MoreObjects.firstNonNull(envCustomCompileSdk, "23");
+ DEFAULT_COMPILE_SDK_VERSION = MoreObjects.firstNonNull(envCustomCompileSdk, "24");
}
private static final String COMMON_HEADER = "commonHeader.gradle";
@@ -304,7 +315,7 @@
if (methodDir != null) {
testDir = new File(testDir, methodDir);
}
-
+
testDir = new File(testDir, name);
buildFile = new File(testDir, "build.gradle");
@@ -316,6 +327,10 @@
FileUtils.mkdirs(testDir);
FileUtils.mkdirs(sourceDir);
+ Files.write(
+ generateVersions(),
+ new File(testDir.getParent(), COMMON_GRADLE_PLUGIN_VERSION),
+ StandardCharsets.UTF_8);
Files.copy(
new File(TEST_PROJECT_DIR, COMMON_HEADER),
new File(testDir.getParent(), COMMON_HEADER));
@@ -325,9 +340,6 @@
Files.copy(
new File(TEST_PROJECT_DIR, COMMON_BUILD_SCRIPT),
new File(testDir.getParent(), COMMON_BUILD_SCRIPT));
- Files.copy(
- new File(TEST_PROJECT_DIR, COMMON_GRADLE_PLUGIN_VERSION),
- new File(testDir.getParent(), COMMON_GRADLE_PLUGIN_VERSION));
if (testProject != null) {
testProject.write(
@@ -344,6 +356,17 @@
createGradleProp();
}
+ private static String generateVersions() {
+ return String.format(
+ "// Generated by GradleTestProject::generateVersions%n"
+ + "buildVersion = '%s'%n"
+ + "experimentalVersion = '%s'%n"
+ + "experimentalGradleVersion = '%s'%n",
+ Version.ANDROID_GRADLE_PLUGIN_VERSION,
+ Version.ANDROID_GRADLE_COMPONENT_PLUGIN_VERSION,
+ GRADLE_EXP_TEST_VERSION);
+ }
+
/**
* Create a GradleTestProject representing a subproject.
*/
@@ -480,8 +503,20 @@
}
/**
- * Returns the SDK dir
+ * Return the output atombundle file from the atom plugin for the given dimension.
+ *
+ * <p>Expected dimensions orders are: - product flavors - build type - other modifiers (e.g.
+ * "unsigned", "aligned")
*/
+ public File getAtomBundle(String... dimensions) {
+ List<String> dimensionList = Lists.newArrayListWithExpectedSize(1 + dimensions.length);
+ dimensionList.add(getName());
+ dimensionList.addAll(Arrays.asList(dimensions));
+ return getOutputFile(
+ "atombundle/" + Joiner.on("-").join(dimensionList) + SdkConstants.DOT_ATOMBUNDLE);
+ }
+
+ /** Returns the SDK dir */
public File getSdkDir() {
return sdkDir;
}
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/TemporaryProjectModification.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/TemporaryProjectModification.java
index 0b89a91..f26c396 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/TemporaryProjectModification.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/TemporaryProjectModification.java
@@ -21,7 +21,6 @@
import com.android.annotations.NonNull;
import com.android.utils.FileUtils;
import com.google.common.base.Charsets;
-import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
@@ -30,6 +29,7 @@
import java.io.File;
import java.io.IOException;
import java.util.Map;
+import java.util.function.Function;
/**
* Allows project files to be modified, but stores their original content, so it can be restored for
@@ -129,25 +129,14 @@
public void replaceFile(
@NonNull String relativePath,
@NonNull final String content) throws IOException {
- modifyFile(relativePath, new Function<String, String>() {
- @Override
- public String apply(String input) {
- return content;
- }
- });
+ modifyFile(relativePath, input -> content);
}
public void replaceInFile(
@NonNull String relativePath,
@NonNull final String search,
@NonNull final String replace) throws IOException {
- modifyFile(relativePath, new Function<String, String>() {
- @Override
- public String apply(String input) {
- return input.replaceAll(search, replace);
- }
- });
-
+ modifyFile(relativePath, input -> input.replaceAll(search, replace));
}
public void removeFile(@NonNull String relativePath) throws IOException {
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/app/AbstractAndroidTestApp.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/app/AbstractAndroidTestApp.java
index 3906c3a..1871819 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/app/AbstractAndroidTestApp.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/fixture/app/AbstractAndroidTestApp.java
@@ -19,9 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/AtomBundleSubject.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/AtomBundleSubject.java
new file mode 100644
index 0000000..5a0f029
--- /dev/null
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/AtomBundleSubject.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.build.gradle.integration.common.truth;
+
+import static com.android.SdkConstants.FN_APK_CLASSES_N_DEX;
+
+import com.android.SdkConstants;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.build.gradle.integration.common.utils.DexUtils;
+import com.android.ide.common.process.ProcessException;
+import com.android.utils.FileUtils;
+import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.SubjectFactory;
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipFile;
+import org.jf.dexlib2.dexbacked.DexBackedClassDef;
+import org.jf.dexlib2.dexbacked.DexBackedDexFile;
+
+/** Truth support for atombundle files. */
+@SuppressWarnings("NonBooleanMethodNameMayNotStartWithQuestion")
+public class AtomBundleSubject extends AbstractAndroidSubject<AtomBundleSubject> {
+
+ public static final SubjectFactory<AtomBundleSubject, File> FACTORY =
+ new SubjectFactory<AtomBundleSubject, File>() {
+ @Override
+ public AtomBundleSubject getSubject(
+ @NonNull FailureStrategy failureStrategy, @NonNull File subject) {
+ return new AtomBundleSubject(failureStrategy, subject);
+ }
+ };
+
+ public AtomBundleSubject(@NonNull FailureStrategy failureStrategy, @NonNull File subject) {
+ super(failureStrategy, subject);
+ }
+
+ @Override
+ protected boolean checkForClass(
+ @NonNull String expectedClassName, @NonNull ClassFileScope scope)
+ throws ProcessException, IOException {
+ return getDexClass(expectedClassName, scope) != null;
+ }
+
+ @Override
+ protected boolean checkForJavaResource(@NonNull String resourcePath)
+ throws ProcessException, IOException {
+ try (ZipFile zipFile = new ZipFile(getSubject())) {
+ return zipFile.getEntry(resourcePath) != null;
+ }
+ }
+
+ /**
+ * Asserts the subject contains a java resources at the given path with the specified String
+ * content.
+ *
+ * <p>Content is trimmed when compared.
+ */
+ @Override
+ public void containsJavaResourceWithContent(@NonNull String path, @NonNull String content)
+ throws IOException, ProcessException {
+ containsFileWithContent(path, content);
+ }
+
+ /**
+ * Asserts the subject contains a java resources at the given path with the specified byte array
+ * content.
+ */
+ @Override
+ public void containsJavaResourceWithContent(@NonNull String path, @NonNull byte[] content)
+ throws IOException, ProcessException {
+ containsFileWithContent(path, content);
+ }
+
+ @Nullable
+ private DexBackedClassDef getDexClass(
+ @NonNull final String className, @NonNull final ClassFileScope scope)
+ throws IOException, ProcessException {
+ if (!className.startsWith("L") || !className.endsWith(";")) {
+ throw new IllegalArgumentException("class name must be in the format Lcom/foo/Main;");
+ }
+
+ switch (scope) {
+ case MAIN:
+ byte[] classesDex =
+ extractContentAsByte(FileUtils.join(SdkConstants.FD_DEX, "classes.dex"));
+ if (classesDex == null) {
+ return null;
+ }
+ return getDexClass(classesDex, className);
+ case SECONDARY:
+ // while dexdump supports receiving directly an apk, this doesn't work for
+ // multi-dex.
+ // We're going to extract all the classes<N>.dex we find until one of them
+ // contains the class we're searching for.
+ try (ZipFile zipFile = new ZipFile(getSubject())) {
+ int index = 2;
+ String dexFileName = String.format(FN_APK_CLASSES_N_DEX, index);
+ while (zipFile.getEntry(dexFileName) != null) {
+ DexBackedClassDef result =
+ extractEntryAndRunAction(
+ FileUtils.join(SdkConstants.FD_DEX, dexFileName),
+ bytes -> getDexClass(bytes, className));
+ if (result != null) {
+ return result;
+ }
+ // not found? switch to next index.
+ index++;
+ dexFileName = String.format(FN_APK_CLASSES_N_DEX, index);
+ }
+ }
+ return null;
+ case MAIN_AND_SECONDARY:
+ DexBackedClassDef dexClass = getDexClass(className, ClassFileScope.MAIN);
+ if (dexClass != null) {
+ return dexClass;
+ }
+ return getDexClass(className, ClassFileScope.SECONDARY);
+ case INSTANT_RUN:
+ throw new IllegalArgumentException("No INSTANT_RUN scope for atombundles");
+ default:
+ throw new IllegalArgumentException("unknown class file scope " + scope);
+ }
+ }
+
+ @Nullable
+ private static DexBackedClassDef getDexClass(@NonNull byte[] classesDex, @NonNull String name) {
+ DexBackedDexFile dexFile = DexUtils.loadDex(classesDex);
+ for (DexBackedClassDef clazz : dexFile.getClasses()) {
+ if (clazz.getType().equals(name)) {
+ return clazz;
+ }
+ }
+ return null;
+ }
+}
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/FakeFailureStrategy.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/FakeFailureStrategy.java
index 73a3e1b..cad9ed4 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/FakeFailureStrategy.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/FakeFailureStrategy.java
@@ -16,7 +16,7 @@
package com.android.build.gradle.integration.common.truth;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.truth.FailureStrategy;
/**
@@ -49,7 +49,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("message", message)
.add("throwable", throwable)
.add("expected", expected)
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/LogCatMessagesSubject.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/LogCatMessagesSubject.java
index 994373c..6d3b52b 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/LogCatMessagesSubject.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/LogCatMessagesSubject.java
@@ -20,7 +20,7 @@
import com.android.annotations.Nullable;
import com.android.build.gradle.integration.common.fixture.Logcat;
import com.android.ddmlib.logcat.LogCatMessage;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.truth.FailureStrategy;
import com.google.common.truth.Subject;
import com.google.common.truth.SubjectFactory;
@@ -62,7 +62,7 @@
if (getSubject() == null) {
return super.getDisplaySubject();
}
- return Objects.toStringHelper(getSubject())
+ return MoreObjects.toStringHelper(getSubject())
.addValue(getSubject().getFilteredLogCatMessages())
.toString();
}
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/TruthHelper.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/TruthHelper.java
index d7e3f39..078015b 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/TruthHelper.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/truth/TruthHelper.java
@@ -103,6 +103,11 @@
}
@NonNull
+ public static AtomBundleSubject assertThatAtomBundle(@Nullable File atombundle) {
+ return assert_().about(AtomBundleSubject.FACTORY).that(atombundle);
+ }
+
+ @NonNull
public static ZipFileSubject assertThatZip(@Nullable File file) {
return assert_().about(ZipFileSubject.Factory.get()).that(file);
}
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/AssumeUtil.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/AssumeUtil.java
index 3c9bb4c..6530199 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/AssumeUtil.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/AssumeUtil.java
@@ -16,6 +16,7 @@
package com.android.build.gradle.integration.common.utils;
+import com.android.SdkConstants;
import com.android.build.gradle.integration.common.fixture.GradleTestProject;
import com.android.repository.Revision;
@@ -46,7 +47,19 @@
}
+ public static void assumeBuildToolsGreaterThan(Revision revision) {
+ Assume.assumeTrue(
+ "Test needs build tools higher than " + revision.toString(),
+ Revision.parseRevision(GradleTestProject.DEFAULT_BUILD_TOOL_VERSION)
+ .compareTo(revision) > 0);
+ }
+
public static void assumeNotUsingJack() {
Assume.assumeFalse(GradleTestProject.USE_JACK);
}
+
+ public static void assumeNotWindows() {
+ Assume.assumeFalse(SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS);
+ }
+
}
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/NdkHelper.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/NdkHelper.java
index 4fe3719..026327e 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/NdkHelper.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/NdkHelper.java
@@ -41,7 +41,12 @@
Revision ndkRevision = NdkHandler.findRevision(ndkDir);
int major = ndkRevision != null ? ndkRevision.getMajor() : 10;
// for r10 max platform is 21, r11 max is 24, r12 max platform is 24
- ImmutableMap<Integer, Integer> perVersion = ImmutableMap.of(10, 21, 11, 24, 12, 24, 13, 24);
+ ImmutableMap<Integer, Integer> perVersion = ImmutableMap.of(
+ 10, 21,
+ 11, 24,
+ 12, 24,
+ 13, 24,
+ 14, 24);
Integer ndkMaxVersion = perVersion.get(major);
if (maxVersion.length() == 1 && Character.isLetter(maxVersion.charAt(0))) {
// max version is a preview one, ndk supported on is def smaller
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/TestFileUtils.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/TestFileUtils.java
index b85377a..026f638 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/TestFileUtils.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/common/utils/TestFileUtils.java
@@ -30,6 +30,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -77,21 +78,27 @@
@NonNull File file,
@NonNull String search,
@NonNull String replace) throws IOException {
- String content = Files.toString(file, Charset.defaultCharset());
+ searchAndReplace(file.toPath(), search, replace);
+ }
+
+ public static void searchAndReplace(
+ @NonNull Path file, @NonNull String search, @NonNull String replace)
+ throws IOException {
+ String content = new String(java.nio.file.Files.readAllBytes(file));
String newContent = content.replaceAll(search, replace);
assertNotEquals(
- "No match in file\n - File: " + file.getPath() + "\n - Search: " + search + "\n",
+ "No match in file\n - File: " + file + "\n - Search: " + search + "\n",
content,
newContent);
// Gradle has a bug, where it may not notice rapid changes to build.gradle if the length of
// the file has not changed. Work around this by appending a new line at the end.
- if (file.getName().equals(SdkConstants.FN_BUILD_GRADLE)
+ if (file.getFileName().toString().equals(SdkConstants.FN_BUILD_GRADLE)
&& content.length() == newContent.length()) {
newContent += System.lineSeparator();
}
- Files.write(newContent, file, Charset.defaultCharset());
+ java.nio.file.Files.write(file, newContent.getBytes());
}
/**
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/BenchmarkRecorder.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/BenchmarkRecorder.java
index 7c0ce55..0b8e75e 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/BenchmarkRecorder.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/BenchmarkRecorder.java
@@ -23,6 +23,8 @@
import com.google.protobuf.Timestamp;
import com.google.protobuf.util.Timestamps;
import com.google.wireless.android.sdk.gradlelogging.proto.Logging;
+import com.google.wireless.android.sdk.gradlelogging.proto.Logging.GradleBenchmarkResult;
+import com.google.wireless.android.sdk.stats.GradleBuildProfile;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -55,8 +57,7 @@
@NonNull private final ProfileUploader uploader;
- @NonNull private final List<Logging.GradleBenchmarkResult.Builder> benchmarkResults =
- new ArrayList<>();
+ @NonNull private final List<GradleBenchmarkResult.Builder> benchmarkResults = new ArrayList<>();
public BenchmarkRecorder(
@NonNull Logging.Benchmark benchmark, @NonNull ProjectScenario projectScenario) {
@@ -73,8 +74,7 @@
this.uploader = uploader;
}
- public void recordBenchmarkResult(
- @NonNull Logging.GradleBenchmarkResult.Builder benchmarkResult) {
+ public void recordBenchmarkResult(@NonNull GradleBenchmarkResult.Builder benchmarkResult) {
benchmarkResult.setResultId(UUID.randomUUID().toString());
@@ -90,16 +90,16 @@
String buildBotBuildNumber = System.getenv("BUILDBOT_BUILDNUMBER");
if (buildBotBuildNumber != null) {
- Logging.GradleBenchmarkResult.ScheduledBuild.Builder scheduledBuild =
- Logging.GradleBenchmarkResult.ScheduledBuild.newBuilder();
+ GradleBenchmarkResult.ScheduledBuild.Builder scheduledBuild =
+ GradleBenchmarkResult.ScheduledBuild.newBuilder();
Long buildNumber = Longs.tryParse(buildBotBuildNumber);
if (buildNumber != null) {
scheduledBuild.setBuildbotBuildNumber(buildNumber);
}
benchmarkResult.setScheduledBuild(scheduledBuild);
} else {
- Logging.GradleBenchmarkResult.Experiment.Builder experiment =
- Logging.GradleBenchmarkResult.Experiment.newBuilder();
+ GradleBenchmarkResult.Experiment.Builder experiment =
+ GradleBenchmarkResult.Experiment.newBuilder();
String experimentComment = System.getenv("BENCHMARK_EXPERIMENT");
if (experimentComment != null) {
experiment.setComment(experimentComment);
@@ -107,15 +107,26 @@
benchmarkResult.setExperiment(experiment);
}
- benchmarkResult.setFlags(projectScenario.getFlags());
+ GradleBenchmarkResult.Flags.Builder flags = projectScenario.getFlags().toBuilder();
+ GradleBuildProfile profile = benchmarkResult.getProfile();
+
+ if (profile.hasGradleVersion()) {
+ if (profile.getGradleVersion().endsWith("+0000")) {
+ // Using nightly gradle version.
+ flags.setGradleVersion(GradleBenchmarkResult.Flags.GradleVersion.UPCOMING_GRADLE);
+ }
+ }
+
+ benchmarkResult.setFlags(flags);
benchmarkResult.setBenchmark(benchmark);
benchmarkResults.add(benchmarkResult);
}
public void doUploads() throws IOException {
Timestamp timestamp = Timestamps.fromMillis(System.currentTimeMillis());
- List<Logging.GradleBenchmarkResult> results =
- benchmarkResults.stream()
+ List<GradleBenchmarkResult> results =
+ benchmarkResults
+ .stream()
.map(builder -> builder.setTimestamp(timestamp).build())
.collect(Collectors.toList());
@@ -125,8 +136,8 @@
}
private static void checkAllUploadsAreDistinct(
- @NonNull List<Logging.GradleBenchmarkResult> benchmarkResults) {
- Set<Logging.GradleBenchmarkResult> benchmarkResultIds =
+ @NonNull List<GradleBenchmarkResult> benchmarkResults) {
+ Set<GradleBenchmarkResult> benchmarkResultIds =
benchmarkResults
.stream()
.map(
@@ -148,7 +159,7 @@
+ Joiner.on('\n').join(benchmarkResultIds));
}
- for (Logging.GradleBenchmarkResult benchmarkResult : benchmarkResultIds) {
+ for (GradleBenchmarkResult benchmarkResult : benchmarkResultIds) {
if (!PerformanceTestUtil.BENCHMARK_MODES.contains(benchmarkResult.getBenchmarkMode())) {
throw new IllegalStateException(
"Cannot upload benchmark result, invalid benchmark mode "
diff --git a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/GoogleStorageProfileUploader.java b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/GoogleStorageProfileUploader.java
index 10bf399..0b0ed31 100644
--- a/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/GoogleStorageProfileUploader.java
+++ b/build-system/integration-test/src/main/java/com/android/build/gradle/integration/performance/GoogleStorageProfileUploader.java
@@ -88,8 +88,12 @@
+ Version.ANDROID_GRADLE_PLUGIN_VERSION)
.setHttpRequestInitializer(
httpRequest -> {
+ // Increase the default timeouts
httpRequest.setConnectTimeout((int) UPLOAD_TIMEOUT.toMillis());
httpRequest.setReadTimeout((int) UPLOAD_TIMEOUT.toMillis());
+ // As calling setHttpRequestInitializer *replaces* the default
+ // initializer, which is implemented by the credential, we need
+ // to manually call the credential initializer.
credential.initialize(httpRequest);
})
.build();
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/AbiPureSplits.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/AbiPureSplits.groovy
index 42960f3..4ee6363 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/AbiPureSplits.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/AbiPureSplits.groovy
@@ -96,6 +96,9 @@
@Test
void "test adding an abi pure split"() throws Exception {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
AndroidProject model = project.executeAndReturnModel("clean", "assembleDebug")
// get the last modified time of the initial APKs so we can make sure incremental build
@@ -139,6 +142,9 @@
@Test
void "test deleting an abi pure split"() throws Exception {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
AndroidProject model = project.executeAndReturnModel("clean", "assembleDebug")
// record the build time of each APK to ensure we don't rebuild those in incremental mode.
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/BuildToolsTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/BuildToolsTest.groovy
index c47ca01..45d4c15 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/BuildToolsTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/BuildToolsTest.groovy
@@ -19,8 +19,8 @@
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.fixture.app.HelloWorldApp
import com.android.build.gradle.integration.common.utils.AssumeUtil
+import com.android.builder.core.AndroidBuilder
import com.android.builder.model.AndroidProject
-import com.android.repository.Revision
import com.google.common.collect.ImmutableList
import com.google.common.collect.Sets
import groovy.transform.CompileStatic
@@ -95,8 +95,8 @@
@Test
public void invalidateBuildTools() {
- // Min build tools for Jack is the latest one
- AssumeUtil.assumeNotUsingJack();
+ // We need at least 2 valid versions of the build tools for this test.
+ AssumeUtil.assumeBuildToolsGreaterThan(AndroidBuilder.MIN_BUILD_TOOLS_REV)
project.getBuildFile() << """
apply plugin: 'com.android.application'
@@ -109,7 +109,7 @@
project.execute("assemble")
- String otherBuildToolsVersion = new Revision(24,0,2);
+ String otherBuildToolsVersion = AndroidBuilder.MIN_BUILD_TOOLS_REV;
// Sanity check:
assertThat(otherBuildToolsVersion).isNotEqualTo(GradleTestProject.DEFAULT_BUILD_TOOL_VERSION)
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/CombinedAbiDensityPureSplits.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/CombinedAbiDensityPureSplits.groovy
index 98fa64f..2731ae9 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/CombinedAbiDensityPureSplits.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/CombinedAbiDensityPureSplits.groovy
@@ -15,6 +15,7 @@
*/
package com.android.build.gradle.integration.application
+
import com.android.build.OutputFile
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.utils.AssumeUtil
@@ -48,6 +49,8 @@
@BeforeClass
static void setup() {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
AssumeUtil.assumeBuildToolsAtLeast(21)
model = project.executeAndReturnModel("clean", "assembleDebug")
}
@@ -60,7 +63,6 @@
@Test
public void "test combined density and abi pure splits"() throws Exception {
-
// Load the custom model for the project
Collection<Variant> variants = model.getVariants()
assertEquals("Variant Count", 2 , variants.size())
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/NativeBuildOutputTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/NativeBuildOutputTest.groovy
index ccd752c..c766311 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/NativeBuildOutputTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/application/NativeBuildOutputTest.groovy
@@ -22,9 +22,9 @@
import com.android.builder.model.AndroidProject
import com.android.builder.model.NativeAndroidProject
import com.android.builder.model.SyncIssue
+import com.android.utils.FileUtils
import groovy.transform.CompileStatic
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@@ -405,7 +405,7 @@
project.file("CMakeLists.txt") << cmakeLists;
- checkSucceeded(["building", "x86/libhello-jni.so"], []);
+ checkSucceeded(["building", FileUtils.join("x86", "libhello-jni.so")], []);
}
private void checkSucceeded(List<String> expectInStdout, List<String> dontExpectInStdout) {
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/ndk/NdkModelTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/ndk/NdkModelTest.groovy
index efea0b4..8753ee7 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/ndk/NdkModelTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/ndk/NdkModelTest.groovy
@@ -19,6 +19,7 @@
import com.android.SdkConstants
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.fixture.app.HelloWorldJniApp
+import com.android.build.gradle.integration.common.utils.AssumeUtil
import com.android.build.gradle.integration.common.utils.ModelHelper
import com.android.build.gradle.integration.common.utils.NdkHelper
import com.android.builder.model.AndroidArtifact
@@ -76,6 +77,9 @@
@Test
void "check native libraries with splits"() {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
project.buildFile <<
"""
android {
@@ -94,6 +98,9 @@
@Test
void "check native libraries with splits and universalApk"() {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
project.buildFile <<
"""
android {
@@ -121,6 +128,9 @@
@Test
void "check native libraries with abiFilters"() {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
project.buildFile <<
"""
android {
@@ -151,6 +161,9 @@
@Test
void "check using add on string for compileSdkVersion"() {
+ // This test uses the deprecated NDK integration, which does not work properly on Windows.
+ AssumeUtil.assumeNotWindows();
+
project.buildFile <<
"""
android {
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/shrinker/HelloWorldShrinkerTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/shrinker/HelloWorldShrinkerTest.groovy
index 2ac00ac..b98d6de 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/shrinker/HelloWorldShrinkerTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/shrinker/HelloWorldShrinkerTest.groovy
@@ -15,6 +15,11 @@
*/
package com.android.build.gradle.integration.shrinker
+
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThat
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatApk
+import static com.android.build.gradle.integration.shrinker.ShrinkerTestUtils.checkShrinkerWasUsed
+
import com.android.build.gradle.integration.common.category.DeviceTests
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.fixture.app.HelloWorldApp
@@ -27,9 +32,6 @@
import org.junit.Test
import org.junit.experimental.categories.Category
-import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThat
-import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatApk
-import static com.android.build.gradle.integration.shrinker.ShrinkerTestUtils.checkShrinkerWasUsed
/**
* Tests for integration of the new class shrinker with Gradle.
*/
@@ -117,6 +119,7 @@
assertThatApk(project.getApk("debug")).containsClass("Lcom/example/helloworld/HelloWorld;")
assertThatApk(project.getApk("debug")).doesNotContainClass("Lcom/example/helloworld/Utils;")
+ long timestamp = helloWorld.lastModified();
addUtilityClass()
project.execute("assembleDebug", "assembleDebugAndroidTest")
@@ -124,7 +127,8 @@
assertThatApk(project.getApk("debug")).containsClass("Lcom/example/helloworld/HelloWorld;")
assertThatApk(project.getApk("debug")).containsClass("Lcom/example/helloworld/Utils;")
- assertThat(helloWorld).isSameAgeAs(utils)
+ assertThat(helloWorld).isNewerThan(timestamp)
+ assertThat(utils).isNewerThan(timestamp)
}
@Test
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/AnnotationProcessorTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/AnnotationProcessorTest.java
index 57d6aac..84c70a0 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/AnnotationProcessorTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/AnnotationProcessorTest.java
@@ -158,7 +158,7 @@
+ "${model_start}"
+ "android {\n"
+ " compileSdkVersion " + GradleTestProject.DEFAULT_COMPILE_SDK_VERSION + "\n"
- + " buildToolsVersion '" + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION + "'\n"
+ + " buildToolsVersion '" + GradleTestProject.DEFAULT_BUILD_TOOL_VERSION + "'\n"
+ " defaultConfig {\n"
+ " jackOptions {\n"
+ " enabled " + forJack + "\n"
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackCompilationOutputTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackCompilationOutputTest.java
index faf40c2..e32d6af 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackCompilationOutputTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackCompilationOutputTest.java
@@ -17,75 +17,118 @@
package com.android.build.gradle.integration.application;
import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThat;
-import static org.junit.Assume.assumeTrue;
import com.android.build.gradle.integration.common.fixture.GradleBuildResult;
import com.android.build.gradle.integration.common.fixture.GradleTestProject;
+import com.android.build.gradle.integration.common.runner.FilterableParameterized;
import com.android.build.gradle.integration.common.utils.TestFileUtils;
+import com.android.builder.model.AndroidProject;
import com.android.utils.FileUtils;
+import com.google.api.client.util.Charsets;
import com.google.common.collect.ImmutableList;
+import com.google.common.io.Files;
-import org.gradle.api.JavaVersion;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
+import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;
/**
* Tests to verify we process Jack compilation output properly.
*/
+@RunWith(FilterableParameterized.class)
public class JackCompilationOutputTest {
- @Rule
- public GradleTestProject sBasic = GradleTestProject.builder().withName("basic")
- .fromTestProject("basic").create();
+ @Parameters(name = "in_process = {0}")
+ public static List<Boolean> jackOptions() {
+ return ImmutableList.of(true, false);
+ }
- private static final List<String> JACK_OPTIONS = ImmutableList
- .of("-Pcom.android.build.gradle.integratonTest.useJack=true",
- "-PCUSTOM_BUILDTOOLS=" + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION);
+ @Parameter
+ public boolean inProcess;
+
+ @Rule
+ public GradleTestProject project =
+ GradleTestProject.builder().withName("basic").fromTestProject("basic").create();
+
+ @Before
+ public void updateBuildFile() throws IOException {
+ TestFileUtils.appendToFile(
+ project.getBuildFile(),
+ "\n"
+ + "android {\n"
+ + " defaultConfig {\n"
+ + " jackOptions {\n"
+ + " enabled true\n"
+ + " jackInProcess " + inProcess + "\n"
+ + " }\n"
+ + " }\n"
+ + "}\n");
+ }
@Test
public void checkErrorsAndWarningsInOutput() throws Exception {
- File main =
- FileUtils.join(
- sBasic.getMainSrcDir(), "com", "android", "tests", "basic", "Main.java");
- TestFileUtils.addMethod(main,
- "java.util.List wrong = new java.util.ArrayList();\n"
- + "int i = 10 //missing semicolon");
+ File userJava = FileUtils.join(project.getMainSrcDir(), "testing", "User.java");
+ FileUtils.mkdirs(userJava.getParentFile());
+ Files.write(
+ "package testing;\n"
+ + "import java.util.List;\n"
+ + "import java.util.ArrayList;\n"
+ + "public class User {\n"
+ + " int age =;\n"
+ + " List<String> names = new ArrayList();\n"
+ + "}\n",
+ userJava,
+ Charsets.UTF_8);
- GradleBuildResult result = sBasic.executor().withArguments(JACK_OPTIONS).expectFailure()
- .run("assembleDebug");
+ GradleBuildResult result =
+ project.executor()
+ .withProperty(AndroidProject.PROPERTY_INVOKED_FROM_IDE, "true")
+ .expectFailure()
+ .run("assembleDebug");
assertThat(result.getStderr())
.containsMatch(
Pattern.compile(
- "^ERROR:.*basic/src/main/java/com/android/tests/basic/Main"
- + "\\.java:.*:.*", Pattern.MULTILINE));
+ "^AGPBI.*error.*User.java.*\"startLine\":4.*",
+ Pattern.MULTILINE));
assertThat(result.getStdout())
.containsMatch(
Pattern.compile(
- "^WARNING:.*basic/src/main/java/com/android/tests/basic/Main"
- + "\\.java:.*:.*", Pattern.MULTILINE));
+ "^AGPBI.*warning.*User.java.*\"startLine\":5.*",
+ Pattern.MULTILINE));
}
@Test
public void checkWarningsInOutput() throws Exception {
- File main =
- FileUtils.join(
- sBasic.getMainSrcDir(), "com", "android", "tests", "basic", "Main.java");
- TestFileUtils.addMethod(main,
- "java.util.List wrong = new java.util.ArrayList();");
+ File userJava = FileUtils.join(project.getMainSrcDir(), "testing", "User.java");
+ FileUtils.mkdirs(userJava.getParentFile());
+ Files.write(
+ "package testing;\n"
+ + "import java.util.List;\n"
+ + "import java.util.ArrayList;\n"
+ + "public class User {\n"
+ + " List<String> names = new ArrayList();\n"
+ + "}\n",
+ userJava,
+ Charsets.UTF_8);
- GradleBuildResult result = sBasic.executor().withArguments(JACK_OPTIONS)
- .run("assembleDebug");
+ GradleBuildResult result =
+ project.executor()
+ .withProperty(AndroidProject.PROPERTY_INVOKED_FROM_IDE, "true")
+ .run("assembleDebug");
assertThat(result.getStdout())
.containsMatch(
Pattern.compile(
- "^WARNING:.*basic/src/main/java/com/android/tests/basic/Main"
- + "\\.java:.*:.*", Pattern.MULTILINE));
+ "^AGPBI.*warning.*User.java.*\"startLine\":4.*",
+ Pattern.MULTILINE));
}
}
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackIncrementalTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackIncrementalTest.java
index 9738798..aabd219 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackIncrementalTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackIncrementalTest.java
@@ -48,7 +48,7 @@
@Before
public void setUp() throws IOException {
TestFileUtils.appendToFile(project.getBuildFile(), "\n"
- + "android.buildToolsVersion '" + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION
+ + "android.buildToolsVersion '" + GradleTestProject.DEFAULT_BUILD_TOOL_VERSION
+ "'\n");
}
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackJava8Test.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackJava8Test.java
index f53f4cc..2b9fcae 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackJava8Test.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackJava8Test.java
@@ -19,7 +19,6 @@
import com.android.build.gradle.integration.common.fixture.GradleTestProject;
import com.android.build.gradle.integration.common.fixture.app.AndroidTestApp;
import com.android.build.gradle.integration.common.fixture.app.HelloWorldApp;
-import com.android.build.gradle.integration.common.utils.AssumeUtil;
import com.android.build.gradle.integration.common.utils.TestFileUtils;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
@@ -35,7 +34,6 @@
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
/**
@@ -80,7 +78,7 @@
TestFileUtils.appendToFile(
project.getBuildFile(),
"android {\n"
- + " buildToolsVersion '" + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION + "'\n"
+ + " buildToolsVersion '" + GradleTestProject.DEFAULT_BUILD_TOOL_VERSION + "'\n"
+ " compileSdkVersion 'android-24'\n"
+ " defaultConfig {\n"
+ minSdkVersionSpec
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackPluginsTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackPluginsTest.java
index 3004e9a..9a2baec 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackPluginsTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackPluginsTest.java
@@ -29,14 +29,12 @@
import com.android.sdklib.BuildToolInfo;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-
-import org.junit.Rule;
-import org.junit.Test;
-
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
/**
* Tests for Jack plugins that can be run as part of the Jack pipeline.
@@ -56,7 +54,7 @@
File coveragePlugin =
SdkHelper.getBuildTool(
Revision.parseRevision(
- GradleTestProject.UPCOMING_BUILD_TOOL_VERSION,
+ GradleTestProject.DEFAULT_BUILD_TOOL_VERSION,
Revision.Precision.MICRO),
BuildToolInfo.PathId.JACK_COVERAGE_PLUGIN);
updateBuildFile(
@@ -86,7 +84,7 @@
File coveragePlugin =
SdkHelper.getBuildTool(
Revision.parseRevision(
- GradleTestProject.UPCOMING_BUILD_TOOL_VERSION,
+ GradleTestProject.DEFAULT_BUILD_TOOL_VERSION,
Revision.Precision.MICRO),
BuildToolInfo.PathId.JACK_COVERAGE_PLUGIN);
updateBuildFile(ImmutableList.of(), ImmutableList.of(coveragePlugin));
@@ -101,7 +99,7 @@
File coveragePlugin =
SdkHelper.getBuildTool(
Revision.parseRevision(
- GradleTestProject.UPCOMING_BUILD_TOOL_VERSION,
+ GradleTestProject.DEFAULT_BUILD_TOOL_VERSION,
Revision.Precision.MICRO),
BuildToolInfo.PathId.JACK_COVERAGE_PLUGIN);
updateBuildFile(
@@ -123,7 +121,7 @@
File coveragePlugin =
SdkHelper.getBuildTool(
Revision.parseRevision(
- GradleTestProject.UPCOMING_BUILD_TOOL_VERSION,
+ GradleTestProject.DEFAULT_BUILD_TOOL_VERSION,
Revision.Precision.MICRO),
BuildToolInfo.PathId.JACK_COVERAGE_PLUGIN);
updateBuildFile(
@@ -142,13 +140,13 @@
pluginNames.stream().map(m -> "'" + m + "'").collect(Collectors.joining(","));
String deps = "";
for (File p : paths) {
- deps += "jackPlugin files('" + p + "')\n";
+ deps += "jackPlugin files('" + p.getAbsolutePath().replace("\\", "\\\\") + "')\n";
}
TestFileUtils.appendToFile(
mProject.getBuildFile(),
"android {\n"
+ " buildToolsVersion '"
- + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION + "'\n"
+ + GradleTestProject.DEFAULT_BUILD_TOOL_VERSION + "'\n"
+ " defaultConfig {\n"
+ " jackOptions {\n"
+ " enabled true\n"
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackSyncIssueTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackSyncIssueTest.java
index 2b61ed1..2e24310 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackSyncIssueTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackSyncIssueTest.java
@@ -61,21 +61,4 @@
SyncIssue.SEVERITY_ERROR,
SyncIssue.TYPE_JACK_REQUIRED_FOR_JAVA_8_LANGUAGE_FEATURES);
}
-
- @Test
- public void testMinimumBuildToolsError() throws IOException {
- // we require 24.0.3+ for Jack
- TestFileUtils.appendToFile(project.getBuildFile(), "\n"
- + "android {\n"
- + " buildToolsVersion '24.0.2'\n"
- + " defaultConfig.jackOptions.enabled = true"
- + "}\n");
-
- // get sync issues
- AndroidProject model = project.model().ignoreSyncIssues().getSingle();
-
- assertThat(model).hasIssue(
- SyncIssue.SEVERITY_ERROR,
- SyncIssue.TYPE_BUILD_TOOLS_TOO_LOW);
- }
}
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackTest.java
index b1699d9..f5dc09d 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/JackTest.java
@@ -79,7 +79,7 @@
+ "${model_start}"
+ "android {\n"
+ " compileSdkVersion " + GradleTestProject.DEFAULT_COMPILE_SDK_VERSION + "\n"
- + " buildToolsVersion '" + GradleTestProject.UPCOMING_BUILD_TOOL_VERSION + "'\n"
+ + " buildToolsVersion '" + GradleTestProject.DEFAULT_BUILD_TOOL_VERSION + "'\n"
+ " defaultConfig {\n"
+ " jackOptions {\n"
+ " enabled true\n"
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/MinifyWithJackTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/MinifyWithJackTest.java
index b0354e3..85d534d 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/MinifyWithJackTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/MinifyWithJackTest.java
@@ -17,7 +17,6 @@
package com.android.build.gradle.integration.application;
import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatApk;
-import static com.google.common.truth.TruthJUnit.assume;
import com.android.build.gradle.integration.common.category.DeviceTests;
import com.android.build.gradle.integration.common.fixture.GradleTestProject;
@@ -40,8 +39,10 @@
@Before
public void setUp() throws Exception {
- assume().that(GradleTestProject.USE_JACK).isTrue();
- project.execute("clean", "assembleMinified", "assembleDebugAndroidTest");
+ project
+ .executor()
+ .withProperty("com.android.build.gradle.integratonTest.useJack", "true")
+ .run("clean", "assembleMinified", "assembleDebugAndroidTest");
}
@Test
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/SourceSetsTaskTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/SourceSetsTaskTest.java
index 384f99e..7c4649a 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/SourceSetsTaskTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/application/SourceSetsTaskTest.java
@@ -20,7 +20,8 @@
import com.android.build.gradle.integration.common.fixture.GradleTestProject;
import com.android.build.gradle.integration.common.fixture.app.HelloWorldApp;
-
+import com.android.utils.FileUtils;
+import com.google.api.client.util.StringUtils;
import org.junit.Rule;
import org.junit.Test;
@@ -37,20 +38,53 @@
public void runsSuccessfully() throws Exception {
project.execute("sourceSets");
- assertThat(project.getStdout()).contains(
- "debug\n"
- + "-----\n"
- + "Compile configuration: debugCompile\n"
- + "build.gradle name: android.sourceSets.debug\n"
- + "Java sources: [src/debug/java]\n"
- + "Manifest file: src/debug/AndroidManifest.xml\n"
- + "Android resources: [src/debug/res]\n"
- + "Assets: [src/debug/assets]\n"
- + "AIDL sources: [src/debug/aidl]\n"
- + "RenderScript sources: [src/debug/rs]\n"
- + "JNI sources: [src/debug/jni]\n"
- + "JNI libraries: [src/debug/jniLibs]\n"
- + "Java-style resources: [src/debug/resources]\n"
- + "\n");
+ String expected =
+ "debug"
+ + StringUtils.LINE_SEPARATOR
+ + "-----"
+ + StringUtils.LINE_SEPARATOR
+ + "Compile configuration: debugCompile"
+ + StringUtils.LINE_SEPARATOR
+ + "build.gradle name: android.sourceSets.debug"
+ + StringUtils.LINE_SEPARATOR
+ + "Java sources: ["
+ + FileUtils.toSystemDependentPath("src/debug/java")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "Manifest file: "
+ + FileUtils.toSystemDependentPath("src/debug/AndroidManifest.xml")
+ + StringUtils.LINE_SEPARATOR
+ + "Android resources: ["
+ + FileUtils.toSystemDependentPath("src/debug/res")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "Assets: ["
+ + FileUtils.toSystemDependentPath("src/debug/assets")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "AIDL sources: ["
+ + FileUtils.toSystemDependentPath("src/debug/aidl")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "RenderScript sources: ["
+ + FileUtils.toSystemDependentPath("src/debug/rs")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "JNI sources: ["
+ + FileUtils.toSystemDependentPath("src/debug/jni")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "JNI libraries: ["
+ + FileUtils.toSystemDependentPath("src/debug/jniLibs")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + "Java-style resources: ["
+ + FileUtils.toSystemDependentPath("src/debug/resources")
+ + "]"
+ + StringUtils.LINE_SEPARATOR
+ + ""
+ + StringUtils.LINE_SEPARATOR;
+
+ assertThat(project.getStdout()).contains(expected);
}
}
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/automatic/CheckAll.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/automatic/CheckAll.java
index ba1a63b..362b91a 100755
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/automatic/CheckAll.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/automatic/CheckAll.java
@@ -110,7 +110,7 @@
"ndkRsHelloCompute",
p -> false,
- // We need buildtools 24.0.0
+ // We need build tools at least 24.0.0
"jarjarWithJack",
p ->
Revision.parseRevision(GradleTestProject.DEFAULT_BUILD_TOOL_VERSION)
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/databinding/DataBindingAtomTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/databinding/DataBindingAtomTest.java
new file mode 100644
index 0000000..5d739ba
--- /dev/null
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/databinding/DataBindingAtomTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.build.gradle.integration.databinding;
+
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThat;
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatAtomBundle;
+
+import com.android.build.gradle.integration.common.fixture.GradleTestProject;
+import com.android.build.gradle.integration.common.runner.FilterableParameterized;
+import com.android.build.gradle.integration.common.truth.AtomBundleSubject;
+import com.android.ide.common.process.ProcessException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/** DataBinding tests for atom projects. */
+@RunWith(FilterableParameterized.class)
+public class DataBindingAtomTest {
+
+ @Parameterized.Parameters(name = "withoutAdapters={0}")
+ public static Collection<Object[]> getParameters() {
+ List<Object[]> options = new ArrayList<>();
+ options.add(new Object[] {true});
+ options.add(new Object[] {false});
+ return options;
+ }
+
+ private final boolean mWithoutAdapters;
+ private final String mBuildFile;
+
+ public DataBindingAtomTest(boolean withoutAdapters) {
+ mWithoutAdapters = withoutAdapters;
+ String options = "build.atom";
+ if (withoutAdapters) {
+ options += "-withoutadapters";
+ }
+ project = GradleTestProject.builder().fromTestProject("databinding").create();
+ mBuildFile = options + ".gradle";
+ }
+
+ @Rule public final GradleTestProject project;
+
+ @Test
+ public void checkDexContainsDataBindingClasses() throws IOException, ProcessException {
+ project.setBuildFile(mBuildFile);
+ project.execute("assembleDebug");
+
+ assertThat(project.getStdout())
+ .named("Build output")
+ .contains(":dataBindingProcessLayoutsDebug");
+
+ AtomBundleSubject atombundle = assertThatAtomBundle(project.getAtomBundle("debug"));
+ atombundle.containsClass("Landroid/databinding/testapp/databinding/ActivityMainBinding;");
+ atombundle.containsClass("Landroid/databinding/DataBindingComponent;");
+ if (mWithoutAdapters) {
+ atombundle.doesNotContainClass("Landroid/databinding/adapters/Converters;");
+ } else {
+ atombundle.containsClass("Landroid/databinding/adapters/Converters;");
+ }
+ }
+}
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/AlignExternallyGeneratedApkTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/AlignExternallyGeneratedApkTest.java
index 5c8fa6c..1ec91f4 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/AlignExternallyGeneratedApkTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/AlignExternallyGeneratedApkTest.java
@@ -29,19 +29,17 @@
import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
/**
* Tests that users can align an APK externally generated.
@@ -100,17 +98,21 @@
*/
Files.append(
"afterEvaluate {\n"
- + "project ->\n"
- + "android.applicationVariants.all { variant ->\n"
- + "variant.outputs.each { output ->\n"
- + "if (output.name.equals(\"debug\")) {\n"
- + "output.createZipAlignTask(\n"
- + "\"ZA\",\n"
- + "new File(\""+ testApk.getAbsolutePath() + "\"),\n"
- + "new File(\"" + alignedApk.getAbsolutePath() + "\"));\n"
- + "}\n"
- + "}\n"
- + "}\n"
+ + " project ->\n"
+ + " android.applicationVariants.all { variant ->\n"
+ + " variant.outputs.each { output ->\n"
+ + " if (output.name.equals(\"debug\")) {\n"
+ + " output.createZipAlignTask(\n"
+ + " \"ZA\",\n"
+ + " new File(\""
+ + testApk.getAbsolutePath().replace("\\", "\\\\")
+ + "\"),\n"
+ + " new File(\""
+ + alignedApk.getAbsolutePath().replace("\\", "\\\\")
+ + "\"));\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ "}\n",
project.getBuildFile(),
Charsets.US_ASCII);
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/PackagingOptionsFilteringTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/PackagingOptionsFilteringTest.java
index ca4249e..70305af 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/PackagingOptionsFilteringTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/packaging/PackagingOptionsFilteringTest.java
@@ -26,16 +26,14 @@
import com.android.build.gradle.integration.common.truth.ApkSubject;
import com.android.utils.FileUtils;
import com.google.common.base.Charsets;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collection;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
/**
* Checks that the packaging options filtering are honored. Currently, only tests for excluding
@@ -230,21 +228,21 @@
byte[] c2 = new byte[] { 6, 7, 8 };
dummyFile(c0, "src", "main", "resources", "I_am_ign");
- dummyFile(c0, "src", "main", "resources", "sccs", "I stay");
+ dummyFile(c0, "src", "main", "resources", "ssccs", "I stay");
dummyFile(c1, "src", "main", "resources", "Ignoring", "this", "fileign");
dummyFile(c1, "src", "main", "resources", "SSensitive", "files", "may", "leak");
dummyFile(c2, "src", "main", "resources", "some", "sensitive", "files", "dont");
- dummyFile(c2, "src", "main", "resources", "pkg", "cvs", "very-sensitive-info");
+ dummyFile(c2, "src", "main", "resources", "pkg", "ccvs", "very-sensitive-info");
project.execute(":assembleDebug");
ApkSubject apk = assertThatApk(project.getApk("debug"));
apk.doesNotContainJavaResource("I_am_ign");
- apk.containsJavaResourceWithContent("sccs/I stay", c0);
+ apk.containsJavaResourceWithContent("ssccs/I stay", c0);
apk.doesNotContainJavaResource("Ignoring/this/fileign");
apk.containsJavaResourceWithContent("SSensitive/files/may/leak", c1);
apk.doesNotContainJavaResource("some/sensitive/files/dont");
- apk.containsJavaResourceWithContent("pkg/cvs/very-sensitive-info", c2);
+ apk.containsJavaResourceWithContent("pkg/ccvs/very-sensitive-info", c2);
}
/**
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/AntennaPodPerformanceMatrixTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/AntennaPodPerformanceMatrixTest.java
index afd6f15..8ecd487 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/AntennaPodPerformanceMatrixTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/AntennaPodPerformanceMatrixTest.java
@@ -105,7 +105,7 @@
TestFileUtils.searchAndReplace(
buildGradleFile,
"buildToolsVersion( =)? \"\\d+.\\d+.\\d+\"",
- "buildToolsVersion$1 \"24.0.3\"");
+ "buildToolsVersion$1 \"25.0.0\"");
}
@Test
@@ -124,10 +124,13 @@
switch (benchmarkMode) {
case EVALUATION:
+ tasks = ImmutableList.of("tasks");
+ break;
case SYNC:
- //TODO
+ project.model().recordBenchmark(BenchmarkMode.SYNC).getMulti();
continue;
case BUILD__FROM_CLEAN:
+ project.executor().withEnableInfoLogging(false).run("clean");
tasks = ImmutableList.of(":app:assembleDebug");
break;
case BUILD_INC__MAIN_PROJECT__JAVA__IMPLEMENTATION_CHANGE:
@@ -146,6 +149,7 @@
//TODO
continue;
case INSTANT_RUN_BUILD__FROM_CLEAN:
+ project.executor().withEnableInfoLogging(false).run("clean");
tasks = ImmutableList.of(":app:assembleDebug");
break;
case INSTANT_RUN_BUILD__MAIN_PROJECT__JAVA__IMPLEMENTATION_CHANGE:
@@ -168,12 +172,15 @@
//TODO
continue;
case BUILD_ANDROID_TESTS_FROM_CLEAN:
+ project.executor().withEnableInfoLogging(false).run("clean");
tasks = ImmutableList.of(":app:assembleDebugAndroidTest");
break;
case BUILD_UNIT_TESTS_FROM_CLEAN:
+ project.executor().withEnableInfoLogging(false).run("clean");
tasks = ImmutableList.of(":app:assembleDebugUnitTest");
break;
case GENERATE_SOURCES:
+ project.executor().withEnableInfoLogging(false).run("clean");
tasks = ModelHelper.getGenerateSourcesCommands(model);
break;
case NO_OP:
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/LargeGradleProjectPerformanceMatrixTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/LargeGradleProjectPerformanceMatrixTest.java
index abc330c..9de36b7 100644
--- a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/LargeGradleProjectPerformanceMatrixTest.java
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/LargeGradleProjectPerformanceMatrixTest.java
@@ -89,7 +89,7 @@
TestFileUtils.searchAndReplace(
project.file("dependencies.gradle"),
"buildToolsVersion: '\\d+.\\d+.\\d+',",
- "buildToolsVersion: '24.0.2'");
+ "buildToolsVersion: '25.0.0'");
// Fix project compilation.
TestFileUtils.searchAndReplace(
diff --git a/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/MediumGradleProjectPerformanceMatrixTest.java b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/MediumGradleProjectPerformanceMatrixTest.java
new file mode 100644
index 0000000..6b75a27
--- /dev/null
+++ b/build-system/integration-test/src/test/java/com/android/build/gradle/integration/performance/MediumGradleProjectPerformanceMatrixTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.android.build.gradle.integration.performance;
+
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThat;
+
+import com.android.annotations.NonNull;
+import com.android.build.gradle.integration.common.fixture.GradleTestProject;
+import com.android.build.gradle.integration.common.runner.FilterableParameterized;
+import com.android.build.gradle.integration.common.utils.TestFileUtils;
+import com.android.builder.model.AndroidProject;
+import com.android.utils.FileUtils;
+import com.google.common.collect.ImmutableList;
+import com.google.wireless.android.sdk.gradlelogging.proto.Logging;
+import com.google.wireless.android.sdk.gradlelogging.proto.Logging.BenchmarkMode;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(FilterableParameterized.class)
+public class MediumGradleProjectPerformanceMatrixTest {
+
+ @Rule public final GradleTestProject project;
+ @NonNull private final ProjectScenario projectScenario;
+
+ public MediumGradleProjectPerformanceMatrixTest(@NonNull ProjectScenario projectScenario) {
+ this.projectScenario = projectScenario;
+ project =
+ GradleTestProject.builder()
+ .fromExternalProject("gradle-perf-android-medium")
+ .forBenchmarkRecording(
+ new BenchmarkRecorder(
+ Logging.Benchmark.PERF_ANDROID_MEDIUM, projectScenario))
+ .withHeap("20G")
+ .create();
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> getParameters() {
+ return Arrays.asList(
+ new Object[][] { // TODO: do we want to include legacy multidex?
+ {ProjectScenario.NATIVE_MULTIDEX}, // {ProjectScenario.LEGACY_MULTIDEX},
+ });
+ }
+
+ @Before
+ public void initializeProject() throws IOException {
+
+ switch (projectScenario) {
+ case NATIVE_MULTIDEX:
+ break;
+ case LEGACY_MULTIDEX:
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown project scenario" + projectScenario);
+ }
+
+ Files.copy(
+ project.file("gradle.properties-example").toPath(),
+ project.file("gradle.properties").toPath());
+ Files.copy(
+ project.file("WordPress/gradle.properties-example").toPath(),
+ project.file("WordPress/gradle.properties").toPath());
+
+ Files.write(
+ project.file("local.properties").toPath(),
+ ImmutableList.of("sdk.dir=" + System.getenv("ANDROID_HOME")));
+
+ TestFileUtils.appendToFile(
+ project.getBuildFile(),
+ "buildscript {\n"
+ + " repositories {\n"
+ + " maven { url '"
+ + FileUtils.toSystemIndependentPath(System.getenv("CUSTOM_REPO"))
+ + "' }"
+ + " }\n"
+ + " dependencies {\n"
+ + " classpath 'com.android.tools.build:gradle:"
+ + GradleTestProject.ANDROID_GRADLE_PLUGIN_VERSION
+ + "'\n"
+ + " }\n"
+ + "}");
+
+ List<Path> buildGradleFiles =
+ ImmutableList.of(
+ "libs/utils/WordPressUtils/build.gradle",
+ "libs/networking/WordPressNetworking/build.gradle",
+ "libs/analytics/WordPressAnalytics/build.gradle")
+ .stream()
+ .map(name -> project.file(name).toPath())
+ .collect(Collectors.toList());
+
+ for (Path file : buildGradleFiles) {
+ TestFileUtils.searchAndReplace(
+ file, "classpath 'com\\.android\\.tools\\.build:gradle:\\d+.\\d+.\\d+'", "");
+
+ TestFileUtils.searchAndReplace(
+ file,
+ "jcenter\\(\\)",
+ "maven { url '"
+ + FileUtils.toSystemIndependentPath(System.getenv("CUSTOM_REPO"))
+ + "'}\njcenter()");
+ }
+
+ TestFileUtils.searchAndReplace(
+ project.file("WordPress/build.gradle"),
+ "classpath 'com\\.android\\.tools\\.build:gradle:\\d+.\\d+.\\d+'",
+ "");
+
+ TestFileUtils.searchAndReplace(
+ project.file("WordPress/build.gradle"),
+ "jcenter\\(\\)",
+ "maven { url '"
+ + FileUtils.toSystemIndependentPath(System.getenv("CUSTOM_REPO"))
+ + "'} \njcenter()");
+
+ //TODO: Upstream some of this?
+
+ TestFileUtils.searchAndReplace(
+ project.file("libs/utils/WordPressUtils/build.gradle"),
+ "classpath 'com\\.novoda:bintray-release:0\\.3\\.4'",
+ "");
+ TestFileUtils.searchAndReplace(
+ project.file("libs/utils/WordPressUtils/build.gradle"),
+ "apply plugin: 'com\\.novoda\\.bintray-release'",
+ "");
+ TestFileUtils.searchAndReplace(
+ project.file("libs/utils/WordPressUtils/build.gradle"),
+ "publish \\{[\\s\\S]*\\}",
+ "");
+
+ TestFileUtils.searchAndReplace(
+ project.file("libs/networking/WordPressNetworking/build.gradle"),
+ "maven \\{ url 'http://wordpress-mobile\\.github\\.io/WordPress-Android' \\}",
+ "");
+
+ TestFileUtils.searchAndReplace(
+ project.file("libs/networking/WordPressNetworking/build.gradle"),
+ "compile 'org\\.wordpress:utils:1\\.11\\.0'",
+ "releaseCompile "
+ + "project(path:':libs:utils:WordPressUtils', configuration: 'release')\n"
+ + " debugCompile "
+ + "project(path:':libs:utils:WordPressUtils', configuration: 'debug')\n");
+ TestFileUtils.searchAndReplace(
+ project.file("libs/analytics/WordPressAnalytics/build.gradle"),
+ "compile 'org\\.wordpress:utils:1\\.11\\.0'",
+ "releaseCompile "
+ + "project(path:':libs:utils:WordPressUtils', configuration: 'release')\n"
+ + " debugCompile "
+ + "project(path:':libs:utils:WordPressUtils', configuration: 'debug')\n");
+ }
+
+ @Test
+ public void runBenchmarks() throws Exception {
+ project.model().getMulti();
+
+ project.executor().run("assemble");
+ project.executor().run("clean");
+
+ Map<String, AndroidProject> model =
+ project.model().recordBenchmark(BenchmarkMode.SYNC).getMulti();
+ assertThat(model.keySet()).contains(":WordPress");
+
+ project.executor()
+ .recordBenchmark(BenchmarkMode.BUILD__FROM_CLEAN)
+ .run("assembleVanillaDebug");
+
+ project.executor().recordBenchmark(BenchmarkMode.NO_OP).run("assembleVanillaDebug");
+ }
+}
diff --git a/build-system/integration-test/test-projects/build.gradle b/build-system/integration-test/test-projects/build.gradle
deleted file mode 100644
index a492fa1..0000000
--- a/build-system/integration-test/test-projects/build.gradle
+++ /dev/null
@@ -1,10 +0,0 @@
-task("printTasks") << {
- project.tasks.each { t ->
- print("${t.name} -> ")
- t.dependsOn.each { t2 ->
- if (t2 instanceof Task)
- print("${t2.name}, ")
- }
- println("")
- }
-}
\ No newline at end of file
diff --git a/build-system/integration-test/test-projects/commonBuildScript.gradle b/build-system/integration-test/test-projects/commonBuildScript.gradle
index 5e87795..3239b4d 100644
--- a/build-system/integration-test/test-projects/commonBuildScript.gradle
+++ b/build-system/integration-test/test-projects/commonBuildScript.gradle
@@ -18,7 +18,7 @@
String buildVersion
String experimentalVersion
String experimentalGradleVersion
-};
+}
def commonScriptFolder = buildscript.sourceFile.parent
apply from: "$commonScriptFolder/commonGradlePluginVersion.gradle", to: env
@@ -27,10 +27,7 @@
apply from: "$commonScriptFolder/commonLocalRepo.gradle", to:buildscript
dependencies {
classpath "com.android.tools.build:gradle:$env.buildVersion"
- if (env.experimentalGradleVersion != null
- && project.gradle.gradleVersion.startsWith(env.experimentalGradleVersion)) {
- classpath "com.android.tools.build:gradle-experimental:$env.experimentalVersion"
- }
+ classpath "com.android.tools.build:gradle-experimental:$env.experimentalVersion"
classpath 'com.android.tools.internal.build.test:devicepool:0.1'
}
}
diff --git a/build-system/integration-test/test-projects/commonGradlePluginVersion.gradle b/build-system/integration-test/test-projects/commonGradlePluginVersion.gradle
deleted file mode 100644
index 300c6dd..0000000
--- a/build-system/integration-test/test-projects/commonGradlePluginVersion.gradle
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.
- */
-
-buildVersion = System.env.CUSTOM_PLUGIN_VERSION
-experimentalVersion = System.env.CUSTOM_EXPERIMENTAL_PLUGIN_VERSION
-experimentalGradleVersion = System.env.CUSTOM_EXPERIMENTAL_GRADLE
-
-if (buildVersion == null && System.env.CUSTOM_REPO != null) {
- // Extract the version from the top level buildSrc, relative to CUSTOM_REPO.
- // Have a fake environment for buildSrc/base/version.gradle can insert the version info into.
- def env = new Object() {
- Object project = new Object() {
- Object ext = new Object() {
- String buildVersion
- String baseVersion
- String experimentalVersion
- String experimentalGradleVersion
- String apiVersion
- String nativeApiVersion
- String versionModifier
- }
- }
- }
- apply from: "$System.env.CUSTOM_REPO/../../tools/buildSrc/base/version.gradle", to: env
- buildVersion = env.project.ext.buildVersion
- experimentalVersion = env.project.ext.experimentalVersion
- experimentalGradleVersion = env.project.ext.experimentalGradleVersion
-}
-
-if (buildVersion == null) {
- throw new RuntimeException(
- "Unknown Android Gradle plugin version. Set 'CUSTOM_REPO' or " +
- "'CUSTOM_PLUGIN_VERSION' to proceed.")
-}
diff --git a/build-system/integration-test/test-projects/commonHeader.gradle b/build-system/integration-test/test-projects/commonHeader.gradle
index f7961c0..bb997a8 100644
--- a/build-system/integration-test/test-projects/commonHeader.gradle
+++ b/build-system/integration-test/test-projects/commonHeader.gradle
@@ -27,8 +27,8 @@
}
ext {
- buildToolsVersion = [System.env.CUSTOM_BUILDTOOLS, project.properties["CUSTOM_BUILDTOOLS"], '24.0.3'].find()
- latestCompileSdk = [System.env.CUSTOM_COMPILE_SDK, project.properties["CUSTOM_COMPILE_SDK"], 23].find() as int
+ buildToolsVersion = [System.env.CUSTOM_BUILDTOOLS, project.properties["CUSTOM_BUILDTOOLS"], '25.0.0'].find()
+ latestCompileSdk = [System.env.CUSTOM_COMPILE_SDK, project.properties["CUSTOM_COMPILE_SDK"], 24].find() as int
// Last SDK that contained java 6 bytecode.
java6BasedSdk = 19
diff --git a/build-system/integration-test/test-projects/databinding/build.atom-withoutadapters.gradle b/build-system/integration-test/test-projects/databinding/build.atom-withoutadapters.gradle
new file mode 100644
index 0000000..be35b19
--- /dev/null
+++ b/build-system/integration-test/test-projects/databinding/build.atom-withoutadapters.gradle
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.
+ */
+
+
+apply from: "../commonHeader.gradle"
+buildscript { apply from: "../commonBuildScript.gradle" }
+apply plugin: 'com.android.atom'
+
+apply from: "../commonLocalRepo.gradle"
+
+android {
+ compileSdkVersion rootProject.latestCompileSdk
+ buildToolsVersion = rootProject.buildToolsVersion
+ defaultConfig {
+ versionCode 1
+ versionName "1.0"
+ }
+ dataBinding {
+ enabled = true
+ addDefaultAdapters = false
+ }
+}
diff --git a/build-system/integration-test/test-projects/databinding/build.atom.gradle b/build-system/integration-test/test-projects/databinding/build.atom.gradle
new file mode 100644
index 0000000..2dd1868
--- /dev/null
+++ b/build-system/integration-test/test-projects/databinding/build.atom.gradle
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.
+ */
+apply from: "../commonHeader.gradle"
+buildscript { apply from: "../commonBuildScript.gradle" }
+apply plugin: 'com.android.atom'
+
+apply from: "../commonLocalRepo.gradle"
+
+android {
+ compileSdkVersion rootProject.latestCompileSdk
+ buildToolsVersion = rootProject.buildToolsVersion
+ defaultConfig {
+ versionCode 1
+ versionName "1.0"
+ }
+ dataBinding {
+ enabled = true
+ addDefaultAdapters = true
+ }
+}
diff --git a/build-system/manifest-merger/src/main/java/com/android/manifmerger/Actions.java b/build-system/manifest-merger/src/main/java/com/android/manifmerger/Actions.java
index d0d7674..631b68d 100644
--- a/build-system/manifest-merger/src/main/java/com/android/manifmerger/Actions.java
+++ b/build-system/manifest-merger/src/main/java/com/android/manifmerger/Actions.java
@@ -24,7 +24,7 @@
import com.android.ide.common.blame.SourceFile;
import com.android.ide.common.blame.SourceFilePosition;
import com.android.utils.ILogger;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -291,7 +291,7 @@
@NonNull
@Override
public String toString() {
- return Objects.toStringHelper(this).add("Id", mTargetId)
+ return MoreObjects.toStringHelper(this).add("Id", mTargetId)
.add("actionType=",getActionType())
.add("location", getActionLocation())
.add("opType", getOperationType()).toString();
diff --git a/build-system/manifest-merger/src/main/java/com/android/manifmerger/ManifestMerger2.java b/build-system/manifest-merger/src/main/java/com/android/manifmerger/ManifestMerger2.java
index fce0184..1ed9ca9 100644
--- a/build-system/manifest-merger/src/main/java/com/android/manifmerger/ManifestMerger2.java
+++ b/build-system/manifest-merger/src/main/java/com/android/manifmerger/ManifestMerger2.java
@@ -261,7 +261,7 @@
// been overridden so the problem was transient. However, with the final document
// ready, all placeholders values must have been provided.
performPlaceHolderSubstitution(loadedMainManifestInfo, xmlDocumentOptional.get(),
- mergingReportBuilder);
+ mergingReportBuilder, mMergeType);
if (mergingReportBuilder.hasErrors()) {
return mergingReportBuilder.build();
}
@@ -489,15 +489,17 @@
// perform place holder substitution, this is necessary to do so early in case placeholders
// are used in key attributes.
- performPlaceHolderSubstitution(manifestInfo, xmlDocument, builder);
+ performPlaceHolderSubstitution(manifestInfo, xmlDocument, builder, mMergeType);
return new LoadedManifestInfo(manifestInfo,
Optional.fromNullable(originalPackageName), xmlDocument);
}
- private void performPlaceHolderSubstitution(@NonNull ManifestInfo manifestInfo,
+ private void performPlaceHolderSubstitution(
+ @NonNull ManifestInfo manifestInfo,
@NonNull XmlDocument xmlDocument,
- @NonNull MergingReport.Builder mergingReportBuilder) {
+ @NonNull MergingReport.Builder mergingReportBuilder,
+ @NonNull MergeType mergeType) {
if (mOptionalFeatures.contains(Invoker.Feature.NO_PLACEHOLDER_REPLACEMENT)) {
return;
@@ -522,7 +524,7 @@
}
}
builder.put(PlaceholderHandler.PACKAGE_NAME, packageName);
- if (mMergeType != MergeType.LIBRARY) {
+ if (mergeType != MergeType.LIBRARY) {
builder.put(PlaceholderHandler.APPLICATION_ID, packageName);
}
finalPlaceHolderValues = builder.build();
@@ -531,7 +533,7 @@
KeyBasedValueResolver<String> placeHolderValueResolver =
new MapBasedKeyBasedValueResolver<String>(finalPlaceHolderValues);
PlaceholderHandler.visit(
- mMergeType,
+ mergeType,
xmlDocument,
placeHolderValueResolver,
mergingReportBuilder);
@@ -606,7 +608,8 @@
// substitutions so feed it with a fake merging report.
MergingReport.Builder builder = new MergingReport.Builder(mergingReportBuilder.getLogger());
builder.getActionRecorder().recordDefaultNodeAction(libraryDocument.getRootNode());
- performPlaceHolderSubstitution(manifestInfo, libraryDocument, builder);
+ performPlaceHolderSubstitution(
+ manifestInfo, libraryDocument, builder, MergeType.LIBRARY);
if (builder.hasErrors()) {
// we log the errors but continue, in case the error is of no consequence
// to the application consuming the library.
@@ -648,7 +651,7 @@
APPLICATION,
/**
- * Library merging typee is used when packaging a library. The resulting android manifest
+ * Library merging type is used when packaging a library. The resulting android manifest
* file will not merge in all the imported libraries this library depends on. Also the tools
* annotations will not be removed as they can be useful when later importing the resulting
* merged android manifest into an application.
diff --git a/build-system/profile/src/main/java/com/android/builder/tasks/BooleanLatch.java b/build-system/profile/src/main/java/com/android/builder/tasks/BooleanLatch.java
index d5dab3b..69d1a47 100644
--- a/build-system/profile/src/main/java/com/android/builder/tasks/BooleanLatch.java
+++ b/build-system/profile/src/main/java/com/android/builder/tasks/BooleanLatch.java
@@ -16,7 +16,7 @@
package com.android.builder.tasks;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
@@ -54,7 +54,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("signaled", isSignalled())
.toString();
diff --git a/build-system/profile/src/main/java/com/android/builder/tasks/Job.java b/build-system/profile/src/main/java/com/android/builder/tasks/Job.java
index 786b08a..5894376 100644
--- a/build-system/profile/src/main/java/com/android/builder/tasks/Job.java
+++ b/build-system/profile/src/main/java/com/android/builder/tasks/Job.java
@@ -18,7 +18,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -87,7 +87,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("\ntitle", mJobTitle)
.add("\ntask", mTask)
.add("\nlatch", mBooleanLatch)
diff --git a/chunkio-processor/BUILD b/chunkio-processor/BUILD
index 71c2a92..70a8718 100644
--- a/chunkio-processor/BUILD
+++ b/chunkio-processor/BUILD
@@ -3,7 +3,6 @@
iml_module(
name = "studio.chunkio-processor",
srcs = ["src"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
deps = ["//tools/base/chunkio:studio.chunkio[module]"],
diff --git a/chunkio/BUILD b/chunkio/BUILD
index a3593ab..fb6df76 100644
--- a/chunkio/BUILD
+++ b/chunkio/BUILD
@@ -3,7 +3,6 @@
iml_module(
name = "studio.chunkio",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
)
diff --git a/common/BUILD b/common/BUILD
index 55bc738..f88e45c 100644
--- a/common/BUILD
+++ b/common/BUILD
@@ -3,14 +3,15 @@
iml_module(
name = "studio.common",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:guava-tools",
"//tools/base/annotations:studio.android-annotations",
],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:guava-tools",
"//tools/idea/.idea/libraries:JUnit4[test]",
diff --git a/common/src/main/java/com/android/SdkConstants.java b/common/src/main/java/com/android/SdkConstants.java
index f43ac23..9a4f09e 100644
--- a/common/src/main/java/com/android/SdkConstants.java
+++ b/common/src/main/java/com/android/SdkConstants.java
@@ -1366,6 +1366,8 @@
public static final String EXT_AAR = "aar"; //$NON-NLS-1$
/** Extension for Android atom files. */
public static final String EXT_ATOM = "atom"; //$NON-NLS-1$
+ /** Extension for Android atombundle files. */
+ public static final String EXT_ATOMBUNDLE = "atombundle"; //$NON-NLS-1$
/** Extension of java files, i.e. "java" */
public static final String EXT_JAVA = "java"; //$NON-NLS-1$
/** Extension of compiled java files, i.e. "class" */
@@ -1411,6 +1413,8 @@
public static final String DOT_AAR = DOT + EXT_AAR; //$NON-NLS-1$
/** Dot-Extension for Android atom files. */
public static final String DOT_ATOM = DOT + EXT_ATOM; //$NON-NLS-1$
+ /** Dot-Extension for Android atombundle files. */
+ public static final String DOT_ATOMBUNDLE = DOT + EXT_ATOMBUNDLE; //$NON-NLS-1$
/** Dot-Extension of aidl files, i.e. ".aidl" */
public static final String DOT_AIDL = DOT + EXT_AIDL;
/** Dot-Extension of renderscript files, i.e. ".rs" */
@@ -1460,6 +1464,7 @@
public static final String FN_BUILD_CONFIG = FN_BUILD_CONFIG_BASE + DOT_JAVA;
public static final String DRAWABLE_FOLDER = "drawable"; //$NON-NLS-1$
+ public static final String MIPMAP_FOLDER = "mipmap"; //$NON-NLS-1$
public static final String DRAWABLE_XHDPI = "drawable-xhdpi"; //$NON-NLS-1$
public static final String DRAWABLE_XXHDPI = "drawable-xxhdpi"; //$NON-NLS-1$
public static final String DRAWABLE_XXXHDPI = "drawable-xxxhdpi"; //$NON-NLS-1$
diff --git a/common/src/main/java/com/android/ide/common/blame/Message.java b/common/src/main/java/com/android/ide/common/blame/Message.java
index 180448d..d7b8259 100644
--- a/common/src/main/java/com/android/ide/common/blame/Message.java
+++ b/common/src/main/java/com/android/ide/common/blame/Message.java
@@ -19,6 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.concurrency.Immutable;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
@@ -204,8 +205,8 @@
@Override
public String toString() {
- Objects.ToStringHelper toStringHelper =
- Objects.toStringHelper(this).add("kind", mKind).add("text", mText)
+ MoreObjects.ToStringHelper toStringHelper =
+ MoreObjects.toStringHelper(this).add("kind", mKind).add("text", mText)
.add("sources", mSourceFilePositions);
if (!mText.equals(mRawMessage)) {
toStringHelper.add("original message", mRawMessage);
diff --git a/common/src/main/java/com/android/prefs/AndroidLocation.java b/common/src/main/java/com/android/prefs/AndroidLocation.java
index 5c0038e..2894166 100644
--- a/common/src/main/java/com/android/prefs/AndroidLocation.java
+++ b/common/src/main/java/com/android/prefs/AndroidLocation.java
@@ -215,8 +215,7 @@
return findValidPath(EnvVar.USER_HOME, EnvVar.HOME);
}
- private static String findHomeFolder()
- throws AndroidLocationException {
+ private static String findHomeFolder() throws AndroidLocationException {
String home = findValidPath(EnvVar.ANDROID_SDK_HOME, EnvVar.USER_HOME, EnvVar.HOME);
// if the above failed, we throw an exception.
diff --git a/common/src/main/java/com/android/utils/FileUtils.java b/common/src/main/java/com/android/utils/FileUtils.java
index d3a67ce..ed162e7 100644
--- a/common/src/main/java/com/android/utils/FileUtils.java
+++ b/common/src/main/java/com/android/utils/FileUtils.java
@@ -18,7 +18,6 @@
import static com.google.common.base.Preconditions.checkArgument;
-import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
@@ -30,12 +29,10 @@
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
-
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
-import java.nio.charset.StandardCharsets;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.regex.Pattern;
@@ -365,6 +362,22 @@
return path;
}
+ /**
+ * Returns an absolute path that can be open by system APIs for all platforms.
+ *
+ * @param file The file whose path needs to be converted.
+ * @return On non-Windows platforms, the absolute path of the file. On Windows, the absolute
+ * path preceded by "\\?\". This ensures that Windows API calls can open the path even if it
+ * is more than 260 characters long.
+ */
+ @NonNull
+ public static String toExportableSystemDependentPath(@NonNull File file) {
+ if (File.separatorChar != '/' && !file.getAbsolutePath().startsWith("\\\\?\\")) {
+ return "\\\\?\\" + file.getAbsolutePath();
+ }
+ return file.getAbsolutePath();
+ }
+
@NonNull
public static String sha1(@NonNull File file) throws IOException {
return Hashing.sha1().hashBytes(Files.toByteArray(file)).toString();
@@ -476,80 +489,6 @@
}
/**
- * Returns a valid file name modified from the requested file name. This method guarantees that
- * there is a one-to-one mapping between the requested file names and the returned file names
- * (i.e., if the input file names are different, the returned file names will also be
- * different). The file name consists of a base name and an extension (which is an empty string
- * if there is no extension). A directory where the file is located is also provided to check
- * the length of the file path and keep both the file name and file path's lengths within limit.
- *
- * @param baseName the base name of the requested file name
- * @param extension the extension of the requested file name (empty string if not available)
- * @param directory the directory where the file will be located
- * @throws IOException if the requested file name or file path is too long
- */
- @NonNull
- public static String getValidFileName(
- @NonNull String baseName, @NonNull String extension, @NonNull File directory)
- throws IOException {
- String fileName = (extension.isEmpty() ? baseName : (baseName + "." + extension));
-
- String validBaseName = baseName.replaceAll("[^a-zA-Z0-9]", "_");
- String validExtension = extension.replaceAll("[^a-zA-Z0-9]", "_");
- String validExtensionWithDot = (validExtension.isEmpty() ? "" : ("." + validExtension));
- String validFileName = validBaseName + validExtensionWithDot;
-
- // Add a hash code to the returned file name to avoid accidental collision (when two
- // different requested file names produce the same returned file name)
- String fileHash = Hashing.sha1().hashString(fileName, StandardCharsets.UTF_8).toString();
- if (!validFileName.equals(fileName)) {
- validFileName = validBaseName + "_" + fileHash + validExtensionWithDot;
- }
-
- // If the file name/file path is too long, retain the hash code only and also keep the
- // extension
- if (isFilePathTooLong(validFileName, directory)) {
- validFileName = fileHash + validExtensionWithDot;
-
- // If the file name/file path is still too long, throw a RuntimeException
- if (isFilePathTooLong(validFileName, directory)) {
- throw new IOException("File name or file path is too long: "
- + new File(directory, validFileName).getAbsolutePath());
- }
- }
-
- return validFileName;
- }
-
- /**
- * Returns <code>true</code> if the file name is too long.
- *
- * @param fileName the file name
- */
- public static boolean isFileNameTooLong(@NonNull String fileName) {
- return fileName.length() > 255;
- }
-
- /**
- * Returns <code>true</code> if the file name or file path is too long.
- *
- * @param fileName the file name
- * @param directory the directory where the file will be located
- */
- public static boolean isFilePathTooLong(@NonNull String fileName, @NonNull File directory) {
- if (isFileNameTooLong(fileName)) {
- return true;
- }
-
- int filePathLength = new File(directory, fileName).getAbsolutePath().length();
- if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- return filePathLength > 260;
- } else {
- return filePathLength > 4096;
- }
- }
-
- /**
* Returns the modified canonical path of a file with consideration of the case sensitivity of
* the underlying file system.
*
diff --git a/common/src/test/java/com/android/utils/FileUtilsTest.java b/common/src/test/java/com/android/utils/FileUtilsTest.java
index 670dd2b..35e135c 100644
--- a/common/src/test/java/com/android/utils/FileUtilsTest.java
+++ b/common/src/test/java/com/android/utils/FileUtilsTest.java
@@ -18,12 +18,9 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import com.android.SdkConstants;
-import com.google.common.base.Strings;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
@@ -77,95 +74,6 @@
}
@Test
- public void testGetValidFileName() throws IOException {
- File directory = new File("/Users/foo");
-
- // Test the "normal" case
- assertThat(FileUtils.getValidFileName("foo", "txt", directory)).isEqualTo("foo.txt");
-
- // Test real-world file path
- assertThat(
- FileUtils.getValidFileName(
- "com.android.support/design/23.3.0/jars/classes.jar"
- + "_build=23.0_jumbo=false_multidex=true_optimize=false",
- "jar",
- directory))
- .isEqualTo(
- "com_android_support_design_23_3_0_jars_classes_jar"
- + "_build_23_0_jumbo_false_multidex_true_optimize_false"
- + "_0979f3a79bbb13e755cfaa70190a4dbc116600f5.jar");
-
- // Test Windows-based file path
- assertThat(
- FileUtils.getValidFileName(
- "com.android.support\\design\\23.3.0\\jars\\classes.jar"
- + "_build=23.0_jumbo=false_multidex=true_optimize=false",
- "jar",
- directory))
- .isEqualTo(
- "com_android_support_design_23_3_0_jars_classes_jar"
- + "_build_23_0_jumbo_false_multidex_true_optimize_false"
- + "_48d7fda3351450337c26a2990bef21df95f65685.jar");
-
- // Test unusual file name
- assertThat(
- FileUtils.getValidFileName(
- "foo`-=[]\\\\;',./~!@#$%^&*()_+{}|:\\\"<>?", "...!@#", directory))
- .isEqualTo(
- "foo__________________________________"
- + "_387e0d11003e554ddceaeca12af15839dbd51643.______");
-
- // Test empty extension
- assertThat(FileUtils.getValidFileName("foo", "", directory)).isEqualTo("foo");
-
- // Test long file name
- assertThat(FileUtils.getValidFileName(Strings.repeat("a", 252), "txt", directory))
- .isEqualTo("7d872a53e320bcdb5adce13b87a7e7671fef6780.txt");
-
- // Test long file path
- try {
- FileUtils.getValidFileName("foo", "txt", new File("/", Strings.repeat("a", 4088)));
- fail("expected IOException");
- } catch (IOException exception) {
- assertTrue(exception.getMessage().startsWith("File name or file path is too long: "));
- }
- }
-
- @Test
- public void testIsFileNameTooLong() throws IOException {
- assertFalse(FileUtils.isFileNameTooLong(Strings.repeat("a", 255)));
- assertTrue(FileUtils.isFileNameTooLong(Strings.repeat("a", 256)));
- }
-
- @Test
- public void testIsFilePathTooLong() throws IOException {
- File directory = new File("/Users/foo");
- assertFalse(FileUtils.isFilePathTooLong("bar", directory));
-
- assertFalse(FileUtils.isFilePathTooLong(Strings.repeat("a", 255), directory));
- assertTrue(FileUtils.isFilePathTooLong(Strings.repeat("a", 256), directory));
-
- if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- assertFalse(
- FileUtils.isFilePathTooLong(
- "foo.txt", new File("C:\\", Strings.repeat("a", 249))));
- assertTrue(
- FileUtils.isFilePathTooLong(
- "foo.txt", new File("C:\\", Strings.repeat("a", 250))));
- } else {
- assertFalse(
- FileUtils.isFilePathTooLong(
- "foo.txt", new File("/", Strings.repeat("a", 4087))));
- assertTrue(
- FileUtils.isFilePathTooLong(
- "foo.txt", new File("/", Strings.repeat("a", 4088))));
- }
-
- // Test Windows-based file path
- assertFalse(FileUtils.isFilePathTooLong("bar", new File("C:\\Users\\foo")));
- }
-
- @Test
public void testGetCaseSensitivityAwareCanonicalPath() throws IOException {
assertThat(FileUtils.getCaseSensitivityAwareCanonicalPath(new File("foo/bar/..")))
.isEqualTo(FileUtils.getCaseSensitivityAwareCanonicalPath(new File("foo")));
@@ -187,10 +95,26 @@
File inputDir = new File("/folders/1/5/main");
File folder = new File(inputDir, "com/obsidian/v4/tv/home/playback");
File fileToProcess = new File(folder, "CameraPlaybackGlue$1.class");
- assertEquals("com/obsidian/v4/tv/home/playback/CameraPlaybackGlue$1.class",
+ assertEquals(
+ FileUtils.join(
+ "com",
+ "obsidian",
+ "v4",
+ "tv",
+ "home",
+ "playback",
+ "CameraPlaybackGlue$1.class"),
FileUtils.relativePossiblyNonExistingPath(fileToProcess, inputDir));
fileToProcess = new File(folder, "CameraPlaybackGlue$CameraPlaybackHost.class");
- assertEquals("com/obsidian/v4/tv/home/playback/CameraPlaybackGlue$CameraPlaybackHost.class",
+ assertEquals(
+ FileUtils.join(
+ "com",
+ "obsidian",
+ "v4",
+ "tv",
+ "home",
+ "playback",
+ "CameraPlaybackGlue$CameraPlaybackHost.class"),
FileUtils.relativePossiblyNonExistingPath(fileToProcess, inputDir));
}
}
diff --git a/ddmlib/BUILD b/ddmlib/BUILD
index fa8aeac..db849be 100644
--- a/ddmlib/BUILD
+++ b/ddmlib/BUILD
@@ -3,29 +3,30 @@
iml_module(
name = "studio.ddmlib",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_data = ["//prebuilts/studio/sdk:platform-tools"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/base/common:studio.common",
"//tools/idea/.idea/libraries:kxml2",
],
+ # do not sort: must match IML order
deps = [
"//tools/base/common:studio.common[module]",
"//tools/idea/.idea/libraries:kxml2",
"//tools/idea/.idea/libraries:easymock-tools[test]",
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/base/testutils:studio.testutils[module, test]",
+ "//tools/idea/.idea/libraries:truth[test]",
],
)
java_library(
name = "tools.ddmlib",
srcs = glob(["src/main/java/**"]),
- javacopts = ["-extra_checks:off"],
visibility = ["//visibility:public"],
deps = [
"//tools/base/annotations",
@@ -39,15 +40,15 @@
name = "tools.tests",
srcs = glob(["src/test/java/**"]),
data = ["//prebuilts/studio/sdk:platform-tools"],
- javacopts = ["-extra_checks:off"],
jvm_flags = ["-Dtest.suite.jar=tools.tests.jar"],
test_class = "com.android.testutils.JarTestSuite",
deps = [
":tools.ddmlib",
"//tools/base/annotations",
- "//tools/base/third_party:com.google.guava_guava",
- "//tools/base/third_party:org.easymock_easymock",
- "//tools/base/third_party:junit_junit",
"//tools/base/testutils:tools.testutils",
+ "//tools/base/third_party:com.google.guava_guava",
+ "//tools/base/third_party:com.google.truth_truth",
+ "//tools/base/third_party:junit_junit",
+ "//tools/base/third_party:org.easymock_easymock",
],
)
diff --git a/ddmlib/ddmlib.iml b/ddmlib/ddmlib.iml
index 0485663..c807298 100644
--- a/ddmlib/ddmlib.iml
+++ b/ddmlib/ddmlib.iml
@@ -16,5 +16,6 @@
<orderEntry type="library" scope="TEST" name="easymock-tools" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testutils" scope="TEST" />
+ <orderEntry type="library" scope="TEST" name="truth" level="project" />
</component>
</module>
\ No newline at end of file
diff --git a/ddmlib/src/test/java/com/android/ddmlib/AdbVersionTest.java b/ddmlib/src/test/java/com/android/ddmlib/AdbVersionTest.java
index 6f1c51f..2273333 100644
--- a/ddmlib/src/test/java/com/android/ddmlib/AdbVersionTest.java
+++ b/ddmlib/src/test/java/com/android/ddmlib/AdbVersionTest.java
@@ -15,36 +15,38 @@
*/
package com.android.ddmlib;
+import static com.google.common.truth.Truth.assertThat;
+
import junit.framework.TestCase;
public class AdbVersionTest extends TestCase {
public void testParser() {
AdbVersion version = AdbVersion.parseFrom("Android Debug Bridge version 1.0.32");
- assertEquals("1.0.32", version.toString());
+ assertThat(version.toString()).isEqualTo("1.0.32");
version = AdbVersion.parseFrom("Android Debug Bridge version 1.0.32 8b22c293a0e5-android");
- assertEquals(AdbVersion.parseFrom("1.0.32"), version);
+ assertThat(version).isEqualTo(AdbVersion.parseFrom("1.0.32"));
version = AdbVersion.parseFrom("1.0.unknown");
- assertEquals(AdbVersion.UNKNOWN, version);
+ assertThat(version).isEqualTo(AdbVersion.UNKNOWN);
}
public void testComponents() {
AdbVersion version = AdbVersion
.parseFrom("Android Debug Bridge version 1.23.32 8b22c293a0e5-android");
- assertEquals(1, version.major);
- assertEquals(23, version.minor);
- assertEquals(32, version.micro);
+ assertThat(version.major).isEqualTo(1);
+ assertThat(version.minor).isEqualTo(23);
+ assertThat(version.micro).isEqualTo(32);
}
public void testComparison() {
AdbVersion min = AdbVersion.parseFrom("1.0.20");
AdbVersion now = AdbVersion.parseFrom("1.0.32");
- assertTrue(now.compareTo(min) > 0);
- assertTrue(min.compareTo(now) < 0);
- assertTrue(now.compareTo(now) == 0);
+ assertThat(now).isGreaterThan(min);
+ assertThat(min).isLessThan(now);
+ assertThat(now).isEquivalentAccordingToCompareTo(now);
AdbVersion f = AdbVersion.parseFrom("2.0.32");
- assertTrue(f.compareTo(now) > 0);
+ assertThat(f).isGreaterThan(now);
}
}
diff --git a/ddmlib/src/test/java/com/android/ddmlib/AndroidDebugBridgeTest.java b/ddmlib/src/test/java/com/android/ddmlib/AndroidDebugBridgeTest.java
index 46c0e1f..24ee76d 100644
--- a/ddmlib/src/test/java/com/android/ddmlib/AndroidDebugBridgeTest.java
+++ b/ddmlib/src/test/java/com/android/ddmlib/AndroidDebugBridgeTest.java
@@ -35,7 +35,7 @@
@Before
public void setUp() throws Exception {
- mAdbPath = TestUtils.getSdkFile("platform-tools/adb");
+ mAdbPath = new File(TestUtils.getSdk(), "platform-tools/adb");
AndroidDebugBridge.initIfNeeded(false);
}
diff --git a/ddmlib/src/test/java/com/android/ddmlib/FakeAdbServerTest.java b/ddmlib/src/test/java/com/android/ddmlib/FakeAdbServerTest.java
index a19257f..62508d2 100644
--- a/ddmlib/src/test/java/com/android/ddmlib/FakeAdbServerTest.java
+++ b/ddmlib/src/test/java/com/android/ddmlib/FakeAdbServerTest.java
@@ -118,7 +118,7 @@
server.start();
// Start up ADB.
- File adbPath = TestUtils.getSdkFile("platform-tools/adb");
+ File adbPath = new File(TestUtils.getSdk(), "platform-tools/adb");
AndroidDebugBridge.initIfNeeded(false);
AndroidDebugBridge bridge = AndroidDebugBridge
.createBridge(adbPath.getCanonicalPath(), false);
diff --git a/device_validator/BUILD b/device_validator/BUILD
index 5318fba..ed2e377 100644
--- a/device_validator/BUILD
+++ b/device_validator/BUILD
@@ -2,11 +2,11 @@
iml_module(
name = "studio.dvlib",
+ # do not sort: must match IML order
srcs = [
"dvlib/src/main/java",
"dvlib/src/main/resources",
],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/base/common:studio.common"],
diff --git a/draw9patch/BUILD b/draw9patch/BUILD
index 4198ca5..60d6fd3 100644
--- a/draw9patch/BUILD
+++ b/draw9patch/BUILD
@@ -2,11 +2,11 @@
iml_module(
name = "studio.draw9patch",
+ # do not sort: must match IML order
srcs = [
"src/main/java",
"src/main/resources",
],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
diff --git a/instant-run/BUILD b/instant-run/BUILD
index 29be463..b085678 100644
--- a/instant-run/BUILD
+++ b/instant-run/BUILD
@@ -3,7 +3,6 @@
iml_module(
name = "studio.instant-run-common",
srcs = ["instant-run-common/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
deps = ["//tools/base/annotations:studio.android-annotations[module]"],
@@ -12,11 +11,11 @@
iml_module(
name = "studio.instant-run-client",
srcs = ["instant-run-client/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["instant-run-client/src/test/resources"],
test_srcs = ["instant-run-client/src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/base/instant-run:studio.instant-run-common[module]",
"//tools/base/ddmlib:studio.ddmlib[module]",
diff --git a/jack/jack-api/build.gradle b/jack/jack-api/build.gradle
index f73296c..cb3ab48 100644
--- a/jack/jack-api/build.gradle
+++ b/jack/jack-api/build.gradle
@@ -2,7 +2,7 @@
group = 'com.android.tools.jack'
archivesBaseName = 'jack-api'
-version = '0.12.0'
+version = '0.13.0'
configurations {
provided
diff --git a/jack/jack-api/src/main/java/com/android/jack/api/v03/Api03Config.java b/jack/jack-api/src/main/java/com/android/jack/api/v03/Api03Config.java
index 49e653b..1dcac9b 100644
--- a/jack/jack-api/src/main/java/com/android/jack/api/v03/Api03Config.java
+++ b/jack/jack-api/src/main/java/com/android/jack/api/v03/Api03Config.java
@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.jack.api.v03;
import com.android.jack.api.v01.ConfigurationException;
import com.android.jack.api.v02.Api02Config;
import java.io.File;
-import java.util.Collection;
+import java.util.List;
import javax.annotation.Nonnull;
@@ -33,12 +32,12 @@
* @param pluginNames Plugin names, each name must be unique
* @throws ConfigurationException if something is wrong in Jack's configuration
*/
- void setPluginNames(@Nonnull Collection<String> pluginNames) throws ConfigurationException;
+ void setPluginNames(@Nonnull List<String> pluginNames) throws ConfigurationException;
/**
* Sets the path where to find Jack plugins.
- * @param pluginPath A collection of jar files where Jack plugins reside
+ * @param pluginPath The plugin path as a list
* @throws ConfigurationException if something is wrong in Jack's configuration
*/
- void setPluginPath(@Nonnull Collection<File> pluginPath) throws ConfigurationException;
+ void setPluginPath(@Nonnull List<File> pluginPath) throws ConfigurationException;
}
\ No newline at end of file
diff --git a/layoutlib-api/BUILD b/layoutlib-api/BUILD
index 7d2bf23..7d7f85a 100644
--- a/layoutlib-api/BUILD
+++ b/layoutlib-api/BUILD
@@ -3,15 +3,16 @@
iml_module(
name = "studio.layoutlib-api",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:kxml2",
"//tools/idea/.idea/libraries:JUnit4",
"//tools/base/annotations:studio.android-annotations",
],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:kxml2",
"//tools/idea/.idea/libraries:JUnit4[test]",
@@ -23,7 +24,6 @@
java_library(
name = "tools.layoutlib-api",
srcs = glob(["src/main/java/**"]),
- javacopts = ["-extra_checks:off"],
visibility = ["//visibility:public"],
deps = [
"//tools/base/annotations",
diff --git a/layoutlib-api/src/main/java/com/android/ide/common/rendering/api/ItemResourceValue.java b/layoutlib-api/src/main/java/com/android/ide/common/rendering/api/ItemResourceValue.java
index fc9263c..609d05c 100644
--- a/layoutlib-api/src/main/java/com/android/ide/common/rendering/api/ItemResourceValue.java
+++ b/layoutlib-api/src/main/java/com/android/ide/common/rendering/api/ItemResourceValue.java
@@ -41,7 +41,7 @@
*/
public ItemResourceValue(String attributeName, boolean isFrameworkAttr, String value,
boolean isFrameworkStyle) {
- this(attributeName, isFrameworkStyle, value, isFrameworkStyle, null);
+ this(attributeName, isFrameworkAttr, value, isFrameworkStyle, null);
}
/**
diff --git a/layoutlib-api/src/main/java/com/android/resources/Density.java b/layoutlib-api/src/main/java/com/android/resources/Density.java
index 80c44b4..1e74c67 100644
--- a/layoutlib-api/src/main/java/com/android/resources/Density.java
+++ b/layoutlib-api/src/main/java/com/android/resources/Density.java
@@ -33,7 +33,10 @@
DPI_400("400dpi", "400 DPI Density", 400, 1), //$NON-NLS-1$
DPI_360("360dpi", "360 DPI Density", 360, 23), //$NON-NLS-1$
XHIGH( "xhdpi", "X-High Density", 320, 8), //$NON-NLS-1$
+ DPI_260("260dpi", "260 DPI Density", 260, 25), //$NON-NLS-1$
DPI_280("280dpi", "280 DPI Density", 280, 22), //$NON-NLS-1$
+ DPI_300("300dpi", "300 DPI Density", 300, 25), //$NON-NLS-1$
+ DPI_340("340dpi", "340 DPI Density", 340, 25), //$NON-NLS-1$
HIGH( "hdpi", "High Density", 240, 4), //$NON-NLS-1$
TV( "tvdpi", "TV Density", 213, 13), //$NON-NLS-1$
MEDIUM( "mdpi", "Medium Density", 160, 4), //$NON-NLS-1$
@@ -144,7 +147,10 @@
public boolean isRecommended() {
switch (this) {
case TV:
+ case DPI_260:
case DPI_280:
+ case DPI_300:
+ case DPI_340:
case DPI_360:
case DPI_400:
case DPI_420:
diff --git a/layoutlib-api/src/test/java/com/android/resources/DensityTest.java b/layoutlib-api/src/test/java/com/android/resources/DensityTest.java
new file mode 100644
index 0000000..4ea2be5
--- /dev/null
+++ b/layoutlib-api/src/test/java/com/android/resources/DensityTest.java
@@ -0,0 +1,24 @@
+package com.android.resources;
+
+import junit.framework.TestCase;
+
+public class DensityTest extends TestCase {
+ public void testMethods() {
+ assertTrue(Density.MEDIUM.isRecommended());
+ assertTrue(Density.MEDIUM.isValidValueForDevice());
+ assertFalse(Density.MEDIUM.isFakeValue());
+ assertEquals("Medium Density", Density.MEDIUM.getLongDisplayValue());
+ assertEquals("Medium Density", Density.MEDIUM.getShortDisplayValue());
+ assertEquals(160, Density.MEDIUM.getDpiValue());
+ assertEquals(4, Density.MEDIUM.since());
+ assertEquals("mdpi", Density.MEDIUM.getResourceValue());
+
+ assertTrue(Density.MEDIUM.compareTo(Density.HIGH) > 0);
+ assertTrue(Density.HIGH.compareTo(Density.MEDIUM) < 0);
+ }
+
+ public void testDpiDensities() {
+ assertFalse(Density.DPI_300.isRecommended());
+ assertTrue(Density.DPI_300.isValidValueForDevice());
+ }
+}
\ No newline at end of file
diff --git a/lint/BUILD b/lint/BUILD
index 7e067a4..029bce8 100644
--- a/lint/BUILD
+++ b/lint/BUILD
@@ -3,25 +3,26 @@
iml_module(
name = "studio.lint-api",
srcs = ["libs/lint-api/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/idea/.idea/libraries:asm-tools",
"//tools/idea/.idea/libraries:lombok-ast",
- "//tools/idea/.idea/libraries:builder-model",
"//tools/base/annotations:studio.android-annotations",
"//tools/idea/.idea/libraries:guava-tools",
+ "//tools/base/build-system/builder-model:studio.builder-model",
"//tools/base/sdk-common:studio.sdk-common",
"//tools/base/layoutlib-api:studio.layoutlib-api",
"//tools:idea.java-psi-api",
],
+ # do not sort: must match IML order
deps = [
"//tools/idea/.idea/libraries:asm-tools",
"//tools/idea/.idea/libraries:lombok-ast",
- "//tools/idea/.idea/libraries:builder-model",
"//tools/base/annotations:studio.android-annotations[module]",
"//tools/idea/.idea/libraries:guava-tools",
+ "//tools/base/build-system/builder-model:studio.builder-model[module]",
"//tools/base/common:studio.common[module]",
"//tools/base/sdklib:studio.sdklib[module]",
"//tools/base/sdk-common:studio.sdk-common[module]",
@@ -40,6 +41,7 @@
),
visibility = ["//visibility:public"],
deps = [
+ "//prebuilts/tools/common/uast:uast-145.597.3",
"//tools/base/annotations",
"//tools/base/build-system/builder-model",
"//tools/base/common:tools.common",
@@ -47,7 +49,6 @@
"//tools/base/repository:tools.repository",
"//tools/base/sdk-common:tools.sdk-common",
"//tools/base/sdklib:tools.sdklib",
- "//tools/base/third_party:com.android.tools.external.com-intellij_uast",
"//tools/base/third_party:com.android.tools.external.lombok_lombok-ast",
"//tools/base/third_party:org.ow2.asm_asm",
"//tools/base/third_party:org.ow2.asm_asm-tree",
@@ -57,7 +58,6 @@
iml_module(
name = "studio.lint-checks",
srcs = ["libs/lint-checks/src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
exports = ["//tools/base/lint:studio.lint-api"],
@@ -75,6 +75,7 @@
visibility = ["//visibility:public"],
deps = [
":tools.lint-api",
+ "//prebuilts/tools/common/uast:uast-145.597.3",
"//tools/base/annotations",
"//tools/base/build-system/builder-model",
"//tools/base/common:tools.common",
@@ -82,7 +83,6 @@
"//tools/base/repository:tools.repository",
"//tools/base/sdk-common:tools.sdk-common",
"//tools/base/sdklib:tools.sdklib",
- "//tools/base/third_party:com.android.tools.external.com-intellij_uast",
"//tools/base/third_party:com.google.code.gson_gson",
"//tools/base/third_party:com.google.guava_guava",
"//tools/base/third_party:net.sf.kxml_kxml2",
diff --git a/lint/libs/lint-api/build.gradle b/lint/libs/lint-api/build.gradle
index cbbf1dc6..1f3a9bd7 100644
--- a/lint/libs/lint-api/build.gradle
+++ b/lint/libs/lint-api/build.gradle
@@ -9,9 +9,9 @@
dependencies {
compile project(':base:sdk-common')
compile project(':base:builder-model')
+ compile project(':base:uast')
compile 'com.android.tools.external.lombok:lombok-ast:0.2.3'
- compile 'com.android.tools.external.com-intellij:uast:145.597.3'
compile 'org.ow2.asm:asm:5.0.4'
compile 'org.ow2.asm:asm-tree:5.0.4'
}
diff --git a/lint/libs/lint-api/lint-api.iml b/lint/libs/lint-api/lint-api.iml
index c4f92e8..0b64204 100644
--- a/lint/libs/lint-api/lint-api.iml
+++ b/lint/libs/lint-api/lint-api.iml
@@ -11,9 +11,9 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="library" exported="" name="asm-tools" level="project" />
<orderEntry type="library" exported="" name="lombok-ast" level="project" />
- <orderEntry type="library" exported="" name="builder-model" level="project" />
<orderEntry type="module" module-name="android-annotations" exported="" />
<orderEntry type="library" exported="" name="guava-tools" level="project" />
+ <orderEntry type="module" module-name="builder-model" exported="" />
<orderEntry type="module" module-name="common" />
<orderEntry type="module" module-name="sdklib" />
<orderEntry type="module" module-name="sdk-common" exported="" />
diff --git a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ApiDetector.java b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ApiDetector.java
index 0e95122..48e3d0c 100644
--- a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ApiDetector.java
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ApiDetector.java
@@ -672,6 +672,7 @@
return ATTR_LABEL_FOR.equals(name)
|| ATTR_TEXT_IS_SELECTABLE.equals(name)
|| "textAlignment".equals(name)
+ || "roundIcon".equals(name)
|| ATTR_FULL_BACKUP_CONTENT.equals(name);
}
diff --git a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/BuiltinIssueRegistry.java
index b398c18..2f0e1e5 100644
--- a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/BuiltinIssueRegistry.java
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/BuiltinIssueRegistry.java
@@ -31,7 +31,7 @@
public class BuiltinIssueRegistry extends IssueRegistry {
private static final List<Issue> sIssues;
- static final int INITIAL_CAPACITY = 287;
+ static final int INITIAL_CAPACITY = 289;
static {
List<Issue> issues = new ArrayList<>(INITIAL_CAPACITY);
@@ -146,6 +146,8 @@
issues.add(IconDetector.ICON_MIX_9PNG);
issues.add(IconDetector.ICON_NODPI);
issues.add(IconDetector.ICON_XML_AND_PNG);
+ issues.add(IconDetector.WEBP_ELIGIBLE);
+ issues.add(IconDetector.WEBP_UNSUPPORTED);
issues.add(IncludeDetector.ISSUE);
issues.add(InefficientWeightDetector.BASELINE_WEIGHTS);
issues.add(InefficientWeightDetector.INEFFICIENT_WEIGHT);
diff --git a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/GradleDetector.java b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/GradleDetector.java
index 650a7c7..3af3757 100644
--- a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/GradleDetector.java
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/GradleDetector.java
@@ -32,6 +32,7 @@
import com.android.builder.model.AndroidArtifact;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.Dependencies;
+import com.android.builder.model.JavaLibrary;
import com.android.builder.model.MavenCoordinates;
import com.android.builder.model.Variant;
import com.android.ide.common.repository.GradleCoordinate;
@@ -58,7 +59,7 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
-
+import com.google.common.collect.Sets;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -304,7 +305,8 @@
/** Group ID for GMS */
public static final String GMS_GROUP_ID = "com.google.android.gms";
public static final String GOOGLE_SUPPORT_GROUP_ID = "com.google.android.support";
- public static final String ANDROID_WEAR_GROUP_ID = "com.google.android.support";
+ public static final String ANDROID_WEAR_GROUP_ID = "com.google.android.wearable";
+ private static final String WEARABLE_ARTIFACT_ID = "wearable";
private static final GradleCoordinate PLAY_SERVICES_V650 = GradleCoordinate
.parseCoordinateString(GradleDetector.GMS_GROUP_ID + ":play-services:6.5.0");
@@ -940,8 +942,8 @@
report(context, cookie, COMPATIBILITY, message);
} else if (context.isEnabled(BUNDLED_GMS)
- && PLAY_SERVICES_V650.isSameArtifact(dependency)
- && COMPARE_PLUS_HIGHER.compare(dependency, PLAY_SERVICES_V650) >= 0) {
+ && PLAY_SERVICES_V650.isSameArtifact(dependency)
+ && COMPARE_PLUS_HIGHER.compare(dependency, PLAY_SERVICES_V650) >= 0) {
// Play services 6.5.0 is the first version to allow un-bundling, so if the user is
// at or above 6.5.0, recommend un-bundling
String message = "Avoid using bundled version of Google Play services SDK.";
@@ -1257,6 +1259,13 @@
*/
private boolean mCheckedSupportLibs;
+ /**
+ * If incrementally editing a single build.gradle file, tracks whether we've already
+ * transitively checked wearable library versions such that we don't flag the same
+ * error on every single dependency declaration
+ */
+ private boolean mCheckedWearableLibs;
+
private void checkPlayServices(Context context, GradleCoordinate dependency, Object cookie) {
String groupId = dependency.getGroupId();
String artifactId = dependency.getArtifactId();
@@ -1274,14 +1283,27 @@
repository);
}
- if (!mCheckedGms) {
- mCheckedGms = true;
- // Incremental analysis only? If so, tie the check to
- // a specific GMS play dependency if only, such that it's highlighted
- // in the editor
- if (!context.getScope().contains(Scope.ALL_RESOURCE_FILES)) {
- // Incremental editing: try flagging them in this file!
- checkConsistentPlayServices(context, cookie);
+ if (GMS_GROUP_ID.equals(dependency.getGroupId())) {
+ if (!mCheckedGms) {
+ mCheckedGms = true;
+ // Incremental analysis only? If so, tie the check to
+ // a specific GMS play dependency if only, such that it's highlighted
+ // in the editor
+ if (!context.getScope().contains(Scope.ALL_RESOURCE_FILES)) {
+ // Incremental editing: try flagging them in this file!
+ checkConsistentPlayServices(context, cookie);
+ }
+ }
+ } else {
+ if (!mCheckedWearableLibs) {
+ mCheckedWearableLibs = true;
+ // Incremental analysis only? If so, tie the check to
+ // a specific GMS play dependency if only, such that it's highlighted
+ // in the editor
+ if (!context.getScope().contains(Scope.ALL_RESOURCE_FILES)) {
+ // Incremental editing: try flagging them in this file!
+ checkConsistentWearableLibraries(context, cookie);
+ }
}
}
}
@@ -1296,34 +1318,126 @@
checkConsistentLibraries(context, cookie, GMS_GROUP_ID);
}
+ private void checkConsistentWearableLibraries(@NonNull Context context,
+ @Nullable Object cookie) {
+ // Make sure we have both
+ // compile 'com.google.android.support:wearable:2.0.0-alpha3'
+ // provided 'com.google.android.wearable:wearable:2.0.0-alpha3'
+ Project project = context.getMainProject();
+ if (!project.isGradleProject()) {
+ return;
+ }
+ Set<String> supportVersions = Sets.newHashSet();
+ Set<String> wearableVersions = Sets.newHashSet();
+ for (AndroidLibrary library : getAndroidLibraries(project)) {
+ MavenCoordinates coordinates = library.getResolvedCoordinates();
+ if (WEARABLE_ARTIFACT_ID.equals(coordinates.getArtifactId()) &&
+ GOOGLE_SUPPORT_GROUP_ID.equals(coordinates.getGroupId())) {
+ supportVersions.add(coordinates.getVersion());
+ }
+ }
+ for (JavaLibrary library : getJavaLibraries(project)) {
+ MavenCoordinates coordinates = library.getResolvedCoordinates();
+ if (WEARABLE_ARTIFACT_ID.equals(coordinates.getArtifactId()) &&
+ ANDROID_WEAR_GROUP_ID.equals(coordinates.getGroupId())) {
+ if (!library.isProvided()) {
+ if (cookie != null) {
+ String message = "This dependency should be marked as "
+ + "`provided`, not `compile`";
+
+ report(context, cookie, COMPATIBILITY, message);
+ } else {
+ String message = String.format("The %1$s:%2$s dependency should be "
+ + "marked as `provided`, not `compile`",
+ ANDROID_WEAR_GROUP_ID,
+ WEARABLE_ARTIFACT_ID);
+ context.report(COMPATIBILITY, guessGradleLocation(context.getProject()),
+ message);
+ }
+ }
+ wearableVersions.add(coordinates.getVersion());
+ }
+ }
+
+ if (!supportVersions.isEmpty()) {
+ if (wearableVersions.isEmpty()) {
+ List<String> list = Lists.newArrayList(supportVersions);
+ String first = Collections.min(list);
+ String message = String.format("Project depends on %1$s:%2$s:%3$s, so it must "
+ + "also depend (as a provided dependency) on %4$s:%5$s:%6$s",
+ GOOGLE_SUPPORT_GROUP_ID,
+ WEARABLE_ARTIFACT_ID,
+ first,
+ ANDROID_WEAR_GROUP_ID,
+ WEARABLE_ARTIFACT_ID,
+ first);
+ if (cookie != null) {
+ report(context, cookie, COMPATIBILITY, message);
+ } else {
+ context.report(COMPATIBILITY, guessGradleLocation(context.getProject()),
+ message);
+ }
+ } else {
+ // Check that they have the same versions
+ if (!supportVersions.equals(wearableVersions)) {
+ List<String> sortedSupportVersions = Lists.newArrayList(supportVersions);
+ Collections.sort(sortedSupportVersions);
+ List<String> supportedWearableVersions = Lists.newArrayList(wearableVersions);
+ Collections.sort(supportedWearableVersions);
+ String message = String.format("The wearable libraries for %1$s and %2$s " +
+ "must use *exactly* the same versions; found %3$s " +
+ "and %4$s",
+ GOOGLE_SUPPORT_GROUP_ID,
+ ANDROID_WEAR_GROUP_ID,
+ sortedSupportVersions.size() == 1 ? sortedSupportVersions.get(0)
+ : sortedSupportVersions.toString(),
+ supportedWearableVersions.size() == 1 ? supportedWearableVersions.get(0)
+ : supportedWearableVersions.toString());
+ if (cookie != null) {
+ report(context, cookie, COMPATIBILITY, message);
+ } else {
+ context.report(COMPATIBILITY, guessGradleLocation(context.getProject()),
+ message);
+ }
+ }
+ }
+ }
+ }
+
private void checkConsistentLibraries(@NonNull Context context,
@Nullable Object cookie, @NonNull String groupId) {
// Make sure we're using a consistent version across all play services libraries
// (b/22709708)
Project project = context.getMainProject();
- if (!project.isGradleProject()) {
- return;
- }
- Variant variant = project.getCurrentVariant();
- if (variant == null) {
- return;
- }
- AndroidArtifact artifact = variant.getMainArtifact();
- GradleVersion version = project.getGradleModelVersion();
- Collection<AndroidLibrary> libraries;
- Dependencies compileDependencies = getCompileDependencies(artifact, version);
- libraries = compileDependencies.getLibraries();
Multimap<String, MavenCoordinates> versionToCoordinate = ArrayListMultimap.create();
- for (AndroidLibrary library : libraries) {
- addLibraryVersions(versionToCoordinate, library, groupId);
+ for (AndroidLibrary library : getAndroidLibraries(project)) {
+ MavenCoordinates coordinates = library.getResolvedCoordinates();
+ if (coordinates.getGroupId().equals(groupId)
+ // Historically the multidex library ended up in the support package but
+ // decided to do its own numbering (and isn't tied to the rest in terms
+ // of implementation dependencies)
+ && !coordinates.getArtifactId().equals("multidex")) {
+ versionToCoordinate.put(coordinates.getVersion(), coordinates);
+ }
}
+
+ for (JavaLibrary library : getJavaLibraries(project)) {
+ MavenCoordinates coordinates = library.getResolvedCoordinates();
+ if (coordinates.getGroupId().equals(groupId)
+ // The Android annotations library is decoupled from the rest and doesn't
+ // need to be matched to the other exact support library versions
+ && !coordinates.getArtifactId().equals("support-annotations")) {
+ versionToCoordinate.put(coordinates.getVersion(), coordinates);
+ }
+ }
+
Set<String> versions = versionToCoordinate.keySet();
if (versions.size() > 1) {
List<String> sortedVersions = Lists.newArrayList(versions);
Collections.sort(sortedVersions, Collections.reverseOrder());
- MavenCoordinates c1 = versionToCoordinate.get(sortedVersions.get(0)).iterator().next();
- MavenCoordinates c2 = versionToCoordinate.get(sortedVersions.get(1)).iterator().next();
+ MavenCoordinates c1 = findFirst(versionToCoordinate.get(sortedVersions.get(0)));
+ MavenCoordinates c2 = findFirst(versionToCoordinate.get(sortedVersions.get(1)));
// Not using toString because in the IDE, these are model proxies which display garbage output
String example1 = c1.getGroupId() + ":" + c1.getArtifactId() + ":" + c1 .getVersion();
String example2 = c2.getGroupId() + ":" + c2.getArtifactId() + ":" + c2 .getVersion();
@@ -1340,19 +1454,53 @@
}
}
- private static void addLibraryVersions(@NonNull Multimap<String, MavenCoordinates> versions,
- @NonNull AndroidLibrary library, @NonNull String groupId) {
- MavenCoordinates coordinates = library.getResolvedCoordinates();
- if (coordinates.getGroupId().equals(groupId)
- // Historically the multidex library ended up in the support package but
- // decided to do its own numbering (and isn't tied to the rest in terms
- // of implementation dependencies)
- && !coordinates.getArtifactId().equals("multidex")) {
- versions.put(coordinates.getVersion(), coordinates);
+ private static MavenCoordinates findFirst(@NonNull Collection<MavenCoordinates> coordinates) {
+ return Collections.min(coordinates, (o1, o2) -> o1.toString().compareTo(o2.toString()));
+ }
+
+ @NonNull
+ public static Collection<AndroidLibrary> getAndroidLibraries(@NonNull Project project) {
+ Dependencies compileDependencies = getCompileDependencies(project);
+ if (compileDependencies == null) {
+ return Collections.emptyList();
}
- for (AndroidLibrary dependency : library.getLibraryDependencies()) {
- addLibraryVersions(versions, dependency, groupId);
+ Set<AndroidLibrary> allLibraries = Sets.newHashSet();
+ addIndirectAndroidLibraries(compileDependencies.getLibraries(), allLibraries);
+ return allLibraries;
+ }
+
+ @NonNull
+ public static Collection<JavaLibrary> getJavaLibraries(@NonNull Project project) {
+ Dependencies compileDependencies = getCompileDependencies(project);
+ if (compileDependencies == null) {
+ return Collections.emptyList();
+ }
+
+ Set<JavaLibrary> allLibraries = Sets.newHashSet();
+ addIndirectJavaLibraries(compileDependencies.getJavaLibraries(), allLibraries);
+ return allLibraries;
+ }
+
+ private static void addIndirectAndroidLibraries(
+ @NonNull Collection<? extends AndroidLibrary> libraries,
+ @NonNull Set<AndroidLibrary> result) {
+ for (AndroidLibrary library : libraries) {
+ if (!result.contains(library)) {
+ result.add(library);
+ addIndirectAndroidLibraries(library.getLibraryDependencies(), result);
+ }
+ }
+ }
+
+ private static void addIndirectJavaLibraries(
+ @NonNull Collection<? extends JavaLibrary> libraries,
+ @NonNull Set<JavaLibrary> result) {
+ for (JavaLibrary library : libraries) {
+ if (!result.contains(library)) {
+ result.add(library);
+ addIndirectJavaLibraries(library.getDependencies(), result);
+ }
}
}
@@ -1363,6 +1511,7 @@
context.getScope().contains(Scope.ALL_RESOURCE_FILES)) {
checkConsistentPlayServices(context, null);
checkConsistentSupportLibraries(context, null);
+ checkConsistentWearableLibraries(context, null);
}
}
@@ -1450,6 +1599,21 @@
return null;
}
+ @Nullable
+ public static Dependencies getCompileDependencies(@NonNull Project project) {
+ if (!project.isGradleProject()) {
+ return null;
+ }
+ Variant variant = project.getCurrentVariant();
+ if (variant == null) {
+ return null;
+ }
+
+ AndroidArtifact artifact = variant.getMainArtifact();
+ GradleVersion version = project.getGradleModelVersion();
+ return getCompileDependencies(artifact, version);
+ }
+
@NonNull
public static Dependencies getCompileDependencies(@NonNull AndroidArtifact artifact,
@Nullable GradleVersion version) {
diff --git a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/IconDetector.java b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/IconDetector.java
index 407cd0f..8f8008a 100644
--- a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/IconDetector.java
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/IconDetector.java
@@ -34,6 +34,7 @@
import static com.android.SdkConstants.DRAWABLE_XHDPI;
import static com.android.SdkConstants.DRAWABLE_XXHDPI;
import static com.android.SdkConstants.DRAWABLE_XXXHDPI;
+import static com.android.SdkConstants.MIPMAP_FOLDER;
import static com.android.SdkConstants.TAG_ACTIVITY;
import static com.android.SdkConstants.TAG_APPLICATION;
import static com.android.SdkConstants.TAG_ITEM;
@@ -41,12 +42,14 @@
import static com.android.SdkConstants.TAG_RECEIVER;
import static com.android.SdkConstants.TAG_SERVICE;
import static com.android.tools.lint.detector.api.LintUtils.endsWith;
+import static com.android.utils.SdkUtils.endsWithIgnoreCase;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.builder.model.ProductFlavor;
import com.android.builder.model.ProductFlavorContainer;
import com.android.ide.common.resources.ResourceUrl;
+import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.resources.Density;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
@@ -69,6 +72,7 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
+import com.google.common.io.Closeables;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.JavaRecursiveElementVisitor;
import com.intellij.psi.PsiAnonymousClass;
@@ -87,13 +91,15 @@
import java.awt.Dimension;
import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -134,7 +140,7 @@
+ (INCLUDE_LDPI ? "|ldpi" : "") + ")$"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/** Pattern for icon names that include their dp size as part of the name */
- private static final Pattern DP_NAME_PATTERN = Pattern.compile(".+_(\\d+)dp\\.png"); //$NON-NLS-1$
+ private static final Pattern DP_NAME_PATTERN = Pattern.compile(".+_(\\d+)dp\\.[a-zA-Z]+"); //$NON-NLS-1$
/** Cache for {@link #getRequiredDensityFolders(Context)} */
private List<String> mCachedRequiredDensities;
@@ -377,6 +383,31 @@
IMPLEMENTATION_JAVA).addMoreInfo(
"http://developer.android.com/design/style/iconography.html"); //$NON-NLS-1$
+ /** Switch to webp? */
+ public static final Issue WEBP_ELIGIBLE = Issue.create(
+ "ConvertToWebp", //$NON-NLS-1$
+ "Convert to WebP",
+
+ "The WebP format is typically more compact than PNG and JPEG. As of Android 4.2.1 " +
+ "it supports transparency and lossless conversion as well. Note that there is a " +
+ "quickfix in the IDE which lets you perform conversion.",
+ Category.ICONS,
+ 6,
+ Severity.WARNING,
+ IMPLEMENTATION_JAVA);
+
+ /** Webp unsupported? */
+ public static final Issue WEBP_UNSUPPORTED = Issue.create(
+ "WebpUnsupported", //$NON-NLS-1$
+ "WebP Unsupported",
+
+ "The WebP format requires Android 4.0 (API 15). Certain features, such as lossless " +
+ "encoding and transparency, requires Android 4.2.1 (API 18; API 17 is 4.2.0.)",
+ Category.ICONS,
+ 6,
+ Severity.ERROR,
+ IMPLEMENTATION_JAVA);
+
/** Constructs a new {@link IconDetector} check */
public IconDetector() {
}
@@ -416,24 +447,25 @@
boolean checkDipSizes = context.isEnabled(ICON_DIP_SIZE);
boolean checkDuplicates = context.isEnabled(DUPLICATES_NAMES)
|| context.isEnabled(DUPLICATES_CONFIGURATIONS);
+ boolean checkWebp = context.isEnabled(WEBP_ELIGIBLE);
Map<File, Dimension> pixelSizes = null;
Map<File, Long> fileSizes = null;
- if (checkDipSizes || checkDuplicates) {
- pixelSizes = new HashMap<File, Dimension>();
- fileSizes = new HashMap<File, Long>();
+ if (checkDipSizes || checkDuplicates || checkWebp) {
+ pixelSizes = new HashMap<>();
+ fileSizes = new HashMap<>();
}
- Map<File, Set<String>> folderToNames = new HashMap<File, Set<String>>();
- Map<File, Set<String>> nonDpiFolderNames = new HashMap<File, Set<String>>();
+ Map<File, Set<String>> folderToNames = new HashMap<>();
+ Map<File, Set<String>> nonDpiFolderNames = new HashMap<>();
for (File folder : folders) {
String folderName = folder.getName();
- if (folderName.startsWith(DRAWABLE_FOLDER)) {
+ if (folderName.startsWith(DRAWABLE_FOLDER) || folderName.startsWith(MIPMAP_FOLDER)) {
File[] files = folder.listFiles();
if (files != null) {
checkDrawableDir(context, folder, files, pixelSizes, fileSizes);
if (checkFolders && DENSITY_PATTERN.matcher(folderName).matches()) {
- Set<String> names = new HashSet<String>(files.length);
+ Set<String> names = new HashSet<>(files.length);
for (File f : files) {
String name = f.getName();
if (isDrawableFile(name)) {
@@ -442,7 +474,7 @@
}
folderToNames.put(folder, names);
} else if (checkFolders) {
- Set<String> names = new HashSet<String>(files.length);
+ Set<String> names = new HashSet<>(files.length);
for (File f : files) {
String name = f.getName();
if (isDrawableFile(name)) {
@@ -466,6 +498,41 @@
if (checkFolders && !folderToNames.isEmpty()) {
checkDensities(context, res, folderToNames, nonDpiFolderNames);
}
+
+ // Report webp-conversion-eligible images
+ // We only check for 17 here, which supports transparency and lossless
+ // encoding. We could also offer this for API 15, but in that case we'd need to
+ // (1) skip images with alpha, and (2) make it clear that only lossy conversion
+ // should be used.
+
+ if (checkWebp && context.getMainProject().getMinSdkVersion().getApiLevel() >= 17) {
+ // (1) See if we have any png or jpeg images
+ // (2) Use the location of the largest such image
+ File largest = null;
+ long size = 0;
+ for (Entry<File, Long> entry : fileSizes.entrySet()) {
+ File f = entry.getKey();
+ String name = f.getName();
+ if (endsWithIgnoreCase(name, DOT_PNG)
+ && !endsWithIgnoreCase(name, DOT_9PNG) ||
+ endsWithIgnoreCase(name, DOT_JPG) ||
+ endsWithIgnoreCase(name, DOT_JPEG)) {
+ Long sizeLong = entry.getValue();
+ if (sizeLong != null && sizeLong > size) {
+ size = sizeLong;
+ largest = f;
+ }
+ }
+ }
+
+ if (largest != null) {
+ Location location = Location.create(largest);
+ String message = "One or more images in this project can be converted to "
+ + "the WebP format which typically results in smaller file sizes, "
+ + "even for lossless conversion.";
+ context.report(WEBP_ELIGIBLE, location, message);
+ }
+ }
}
}
}
@@ -483,15 +550,15 @@
// needs to check actual file contents on a small subset of the available files.
private static void checkDuplicates(Context context, Map<File, Dimension> pixelSizes,
Map<File, Long> fileSizes) {
- Map<Long, Set<File>> sameSizes = new HashMap<Long, Set<File>>();
- Map<Long, File> seenSizes = new HashMap<Long, File>(fileSizes.size());
+ Map<Long, Set<File>> sameSizes = new HashMap<>();
+ Map<Long, File> seenSizes = new HashMap<>(fileSizes.size());
for (Map.Entry<File, Long> entry : fileSizes.entrySet()) {
File file = entry.getKey();
Long size = entry.getValue();
if (seenSizes.containsKey(size)) {
Set<File> set = sameSizes.get(size);
if (set == null) {
- set = new HashSet<File>();
+ set = new HashSet<>();
set.add(seenSizes.get(size));
sameSizes.put(size, set);
}
@@ -511,15 +578,15 @@
// we don't have file sizes for ninepatch files.
Collection<Set<File>> candidateLists = sameSizes.values();
for (Set<File> candidates : candidateLists) {
- Map<Dimension, Set<File>> sameDimensions = new HashMap<Dimension, Set<File>>(
- candidates.size());
- List<File> noSize = new ArrayList<File>();
+ Map<Dimension, Set<File>> sameDimensions = new HashMap<>(
+ candidates.size());
+ List<File> noSize = new ArrayList<>();
for (File file : candidates) {
Dimension dimension = pixelSizes.get(file);
if (dimension != null) {
Set<File> set = sameDimensions.get(dimension);
if (set == null) {
- set = new HashSet<File>();
+ set = new HashSet<>();
sameDimensions.put(dimension, set);
}
set.add(file);
@@ -538,7 +605,7 @@
}
} else {
// Must just test the noSize elements against themselves
- HashSet<File> noSizeSet = new HashSet<File>(noSize);
+ HashSet<File> noSizeSet = new HashSet<>(noSize);
sets = Collections.<Set<File>>singletonList(noSizeSet);
}
}
@@ -546,7 +613,7 @@
// Map from file to actual byte contents of the file.
// We store this in a map such that for repeated files, such as noSize files
// which can appear in multiple buckets, we only need to read them once
- Map<File, byte[]> fileContents = new HashMap<File, byte[]>();
+ Map<File, byte[]> fileContents = new HashMap<>();
// Now we're ready for the final check where we actually check the
// bits. We have to partition the files into buckets of files that
@@ -572,12 +639,12 @@
// Map where the key file is known to be equal to the value file.
// After we check individual files for equality this will be used
// to look for transitive equality.
- Map<File, File> equal = new HashMap<File, File>();
+ Map<File, File> equal = new HashMap<>();
// Now go and compare all the files. This isn't an efficient algorithm
// but the number of candidates should be very small
- List<File> files = new ArrayList<File>(set);
+ List<File> files = new ArrayList<>(set);
Collections.sort(files);
for (int i = 0; i < files.size() - 1; i++) {
for (int j = i + 1; j < files.size(); j++) {
@@ -611,8 +678,8 @@
}
if (!equal.isEmpty()) {
- Map<File, Set<File>> partitions = new HashMap<File, Set<File>>();
- List<Set<File>> sameSets = new ArrayList<Set<File>>();
+ Map<File, Set<File>> partitions = new HashMap<>();
+ List<Set<File>> sameSets = new ArrayList<>();
for (Map.Entry<File, File> entry : equal.entrySet()) {
File file1 = entry.getKey();
File file2 = entry.getValue();
@@ -623,7 +690,7 @@
} else if (set2 != null) {
set2.add(file1);
} else {
- set = new HashSet<File>();
+ set = new HashSet<>();
sameSets.add(set);
set.add(file1);
set.add(file2);
@@ -634,20 +701,15 @@
// We've computed the partitions of equal files. Now sort them
// for stable output.
- List<List<File>> lists = new ArrayList<List<File>>();
+ List<List<File>> lists = new ArrayList<>();
for (Set<File> same : sameSets) {
assert !same.isEmpty();
- ArrayList<File> sorted = new ArrayList<File>(same);
+ ArrayList<File> sorted = new ArrayList<>(same);
Collections.sort(sorted);
lists.add(sorted);
}
// Sort overall partitions by the first item in each list
- Collections.sort(lists, new Comparator<List<File>>() {
- @Override
- public int compare(List<File> list1, List<File> list2) {
- return list1.get(0).compareTo(list2.get(0));
- }
- });
+ lists.sort((list1, list2) -> list1.get(0).compareTo(list2.get(0)));
// Allow one specific scenario of duplicated icon contents:
// Checking in different size icons (within a single density
@@ -730,18 +792,18 @@
// creates a map from filename (such as foo.png) to a list of files
// providing that icon in various folders: drawable-mdpi/foo.png, drawable-hdpi/foo.png
// etc.
- Map<String, List<File>> nameToFiles = new HashMap<String, List<File>>();
+ Map<String, List<File>> nameToFiles = new HashMap<>();
for (File file : pixelSizes.keySet()) {
String name = file.getName();
List<File> list = nameToFiles.get(name);
if (list == null) {
- list = new ArrayList<File>();
+ list = new ArrayList<>();
nameToFiles.put(name, list);
}
list.add(file);
}
- ArrayList<String> names = new ArrayList<String>(nameToFiles.keySet());
+ ArrayList<String> names = new ArrayList<>(nameToFiles.keySet());
Collections.sort(names);
// We have to partition the files further because it's possible for the project
@@ -755,8 +817,7 @@
// the drawable-{density} icons are consistent.
// Map from name to list of map from parent folder to list of files
- Map<String, Map<String, List<File>>> configMap =
- new HashMap<String, Map<String,List<File>>>();
+ Map<String, Map<String, List<File>>> configMap = new HashMap<>();
for (Map.Entry<String, List<File>> entry : nameToFiles.entrySet()) {
String name = entry.getKey();
List<File> files = entry.getValue();
@@ -781,13 +842,13 @@
Map<String, List<File>> folderMap = configMap.get(name);
if (folderMap == null) {
- folderMap = new HashMap<String,List<File>>();
+ folderMap = new HashMap<>();
configMap.put(name, folderMap);
}
// Map from name to a map from parent folder to files
List<File> list = folderMap.get(parentName);
if (list == null) {
- list = new ArrayList<File>();
+ list = new ArrayList<>();
folderMap.put(parentName, list);
}
list.add(file);
@@ -807,7 +868,7 @@
List<File> files = entry.getValue();
// Ensure that all the dip sizes are *roughly* the same
- Map<File, Dimension> dipSizes = new HashMap<File, Dimension>();
+ Map<File, Dimension> dipSizes = new HashMap<>();
int dipWidthSum = 0; // Incremental computation of average
int dipHeightSum = 0; // Incremental computation of average
int count = 0;
@@ -874,24 +935,18 @@
StringBuilder sb = new StringBuilder(100);
// Sort entries by decreasing dip size
- List<Map.Entry<File, Dimension>> entries =
- new ArrayList<Map.Entry<File,Dimension>>();
+ List<Map.Entry<File, Dimension>> entries = new ArrayList<>();
for (Map.Entry<File, Dimension> entry2 : dipSizes.entrySet()) {
entries.add(entry2);
}
- Collections.sort(entries,
- new Comparator<Map.Entry<File, Dimension>>() {
- @Override
- public int compare(Entry<File, Dimension> e1,
- Entry<File, Dimension> e2) {
- Dimension d1 = e1.getValue();
- Dimension d2 = e2.getValue();
- if (d1.width != d2.width) {
- return d2.width - d1.width;
- }
-
- return d2.height - d1.height;
+ entries.sort((e1, e2) -> {
+ Dimension d1 = e1.getValue();
+ Dimension d2 = e2.getValue();
+ if (d1.width != d2.width) {
+ return d2.width - d1.width;
}
+
+ return d2.height - d1.height;
});
for (Map.Entry<File, Dimension> entry2 : entries) {
if (sb.length() > 0) {
@@ -933,7 +988,7 @@
// TODO: Use the matrix to check out if we can eliminate densities based
// on the target screens?
- Set<String> definedDensities = new HashSet<String>();
+ Set<String> definedDensities = new HashSet<>();
for (File f : folderToNames.keySet()) {
definedDensities.add(f.getName());
}
@@ -941,13 +996,22 @@
// Look for missing folders -- if you define say drawable-mdpi then you
// should also define -hdpi and -xhdpi.
if (context.isEnabled(ICON_MISSING_FOLDER)) {
- List<String> missing = new ArrayList<String>();
- for (String density : getRequiredDensityFolders(context)) {
+ List<String> missing = new ArrayList<>();
+ List<String> requiredDensityFolders = getRequiredDensityFolders(context);
+
+ boolean foundSome = false;
+ for (String density : requiredDensityFolders) {
if (!definedDensities.contains(density)) {
missing.add(density);
+ } else {
+ // Make sure the we have at least one of the folders required
+ // (e.g. we might only have mipmap folders as well as drawable/ or
+ // drawable-nodpi)
+ foundSome = true;
}
}
- if (!missing.isEmpty()) {
+
+ if (!missing.isEmpty() && foundSome) {
context.report(
ICON_MISSING_FOLDER,
Location.create(res),
@@ -958,7 +1022,7 @@
}
if (context.isEnabled(ICON_NODPI)) {
- Set<String> noDpiNames = new HashSet<String>();
+ Set<String> noDpiNames = new HashSet<>();
for (Map.Entry<File, Set<String>> entry : folderToNames.entrySet()) {
if (isNoDpiFolder(entry.getKey())) {
noDpiNames.addAll(entry.getValue());
@@ -966,8 +1030,8 @@
}
if (!noDpiNames.isEmpty()) {
// Make sure that none of the nodpi names appear in a non-nodpi folder
- Set<String> inBoth = new HashSet<String>();
- List<File> files = new ArrayList<File>();
+ Set<String> inBoth = new HashSet<>();
+ List<File> files = new ArrayList<>();
for (Map.Entry<File, Set<String>> entry : folderToNames.entrySet()) {
File folder = entry.getKey();
String folderName = folder.getName();
@@ -982,7 +1046,7 @@
}
if (!inBoth.isEmpty()) {
- List<String> list = new ArrayList<String>(inBoth);
+ List<String> list = new ArrayList<>(inBoth);
Collections.sort(list);
// Chain locations together
@@ -1041,7 +1105,7 @@
}
}
}
- List<String> sorted = new ArrayList<String>(map.keySet());
+ List<String> sorted = new ArrayList<>(map.keySet());
Collections.sort(sorted);
for (String name : sorted) {
List<File> lists = Lists.newArrayList(map.get(name));
@@ -1073,7 +1137,7 @@
if (context.isEnabled(ICON_DENSITIES)) {
// Look for folders missing some of the specific assets
- Set<String> allNames = new HashSet<String>();
+ Set<String> allNames = new HashSet<>();
for (Entry<File,Set<String>> entry : folderToNames.entrySet()) {
if (!isNoDpiFolder(entry.getKey())) {
Set<String> names = entry.getValue();
@@ -1088,7 +1152,7 @@
}
Set<String> names = entry.getValue();
if (names.size() != allNames.size()) {
- List<String> delta = new ArrayList<String>(nameDifferences(allNames, names));
+ List<String> delta = new ArrayList<>(nameDifferences(allNames, names));
if (delta.isEmpty()) {
continue;
}
@@ -1096,7 +1160,7 @@
String foundIn = "";
if (delta.size() == 1) {
// Produce list of where the icon is actually defined
- List<String> defined = new ArrayList<String>();
+ List<String> defined = new ArrayList<>();
String name = delta.get(0);
for (Map.Entry<File, Set<String>> e : folderToNames.entrySet()) {
if (e.getValue().contains(name)) {
@@ -1179,11 +1243,11 @@
* file extensions</b> and return the result <b>with</b>..
*/
private static Set<String> nameDifferences(Set<String> a, Set<String> b) {
- Set<String> names1 = new HashSet<String>(a.size());
+ Set<String> names1 = new HashSet<>(a.size());
for (String s : a) {
names1.add(LintUtils.getBaseName(s));
}
- Set<String> names2 = new HashSet<String>(b.size());
+ Set<String> names2 = new HashSet<>(b.size());
for (String s : b) {
names2.add(LintUtils.getBaseName(s));
}
@@ -1192,7 +1256,7 @@
if (!names1.isEmpty()) {
// Map filenames back to original filenames with extensions
- Set<String> result = new HashSet<String>(names1.size());
+ Set<String> result = new HashSet<>(names1.size());
for (String s : a) {
if (names1.contains(LintUtils.getBaseName(s))) {
result.add(s);
@@ -1216,11 +1280,11 @@
* file extensions</b> and return the result <b>with</b>.
*/
private static Set<String> nameIntersection(Set<String> a, Set<String> b) {
- Set<String> names1 = new HashSet<String>(a.size());
+ Set<String> names1 = new HashSet<>(a.size());
for (String s : a) {
names1.add(LintUtils.getBaseName(s));
}
- Set<String> names2 = new HashSet<String>(b.size());
+ Set<String> names2 = new HashSet<>(b.size());
for (String s : b) {
names2.add(LintUtils.getBaseName(s));
}
@@ -1229,7 +1293,7 @@
if (!names1.isEmpty()) {
// Map filenames back to original filenames with extensions
- Set<String> result = new HashSet<String>(names1.size());
+ Set<String> result = new HashSet<>(names1.size());
for (String s : a) {
if (names1.contains(LintUtils.getBaseName(s))) {
result.add(s);
@@ -1288,6 +1352,7 @@
} else if (endsWith(name, DOT_PNG)
|| endsWith(name, DOT_JPG)
|| endsWith(name, DOT_JPEG)
+ || endsWith(name, DOT_WEBP)
|| endsWith(name, DOT_GIF)) {
context.report(ICON_LOCATION,
Location.create(file),
@@ -1362,7 +1427,7 @@
String fileName = file.getName();
if (endsWith(fileName, DOT_PNG) || endsWith(fileName, DOT_JPG)
- || endsWith(fileName, DOT_JPEG)) {
+ || endsWith(fileName, DOT_JPEG) || endsWith(fileName, DOT_WEBP)) {
// Only scan .png files (except 9-patch png's) and jpg files for
// dip sizes. Duplicate checks can also be performed on ninepatch files.
if (pixelSizes != null && !endsWith(fileName, DOT_9PNG)
@@ -1377,9 +1442,42 @@
}
}
+ if (context.isEnabled(WEBP_UNSUPPORTED) && files.length > 0) {
+ checkWebpSupported(context, files);
+ }
+
mImageCache = null;
}
+ private static void checkWebpSupported(@NonNull Context context, @NonNull File[] files) {
+ // all files in this folder have the same folder minSdkVersion
+ int minSdk = Math.max(context.getMainProject().getMinSdk(),
+ context.getDriver().getResourceFolderVersion(files[0]));
+ if (minSdk >= 18) {
+ return;
+ }
+
+ for (File file : files) {
+ String name = file.getPath();
+ if (!endsWithIgnoreCase(name, DOT_WEBP)) {
+ continue;
+ }
+ WebpHeader header = WebpHeader.getWebpHeader(file);
+ if (header != null && header.format != null) {
+ boolean simpleFormat = "VP8".equals(header.format);
+ int required = simpleFormat ? 15 : 18;
+ if (required > minSdk) {
+ Location location = Location.create(file);
+ String message = simpleFormat ?
+ "WebP requires Android 4.0 (API 15)" :
+ "WebP extended or lossless format requires Android 4.2.1 (API 18)";
+ message += "; " + "current minSdkVersion is " + minSdk;
+ context.report(WEBP_UNSUPPORTED, location, message);
+ }
+ }
+ }
+ }
+
/**
* Check that launcher icons do not fill every pixel in the image
*/
@@ -1531,6 +1629,21 @@
if (input != null) {
try {
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
+ if (!readers.hasNext() && !endsWithIgnoreCase(file.getPath(), DOT_WEBP)) {
+ // Check WEBP: No decoder available outside of Android Studio
+ // See if it's a WEBP file without a webp extension
+ //noinspection VariableNotUsedInsideIf
+ if (WebpHeader.getWebpHeader(file) != null) {
+ String extension = file.getName();
+ extension = extension.substring(extension.lastIndexOf('.') + 1);
+ String message = String.format(
+ "Misleading file extension; named `.%1$s` but the " +
+ "file format is `%2$s`", extension, "webp");
+ Location location = Location.create(file);
+ context.report(ICON_EXTENSION, location, message);
+ }
+ }
+
while (readers.hasNext()) {
ImageReader reader = readers.next();
try {
@@ -1566,6 +1679,7 @@
}
} catch (IOException e) {
// Pass -- we can't handle all image types, warn about those we can
+ System.out.println("foo");
}
}
@@ -1585,7 +1699,7 @@
Set<String> conflictSet = null;
for (Entry<File, Set<String>> entry : folderToNames.entrySet()) {
- Set<String> baseNames = new HashSet<String>();
+ Set<String> baseNames = new HashSet<>();
Set<String> names = entry.getValue();
for (String name : names) {
assert isDrawableFile(name) : name;
@@ -1631,7 +1745,7 @@
}
assert conflicts != null && !conflicts.isEmpty() : conflictSet;
- List<String> names = new ArrayList<String>(conflicts.keySet());
+ List<String> names = new ArrayList<>(conflicts.keySet());
Collections.sort(names);
for (String name : names) {
List<File> files = conflicts.get(name);
@@ -1664,6 +1778,7 @@
String folderName = folder.getName();
int folderVersion = context.getDriver().getResourceFolderVersion(files[0]);
+ FolderConfiguration folderConfig = FolderConfiguration.getConfigForFolder(folderName);
for (File file : files) {
String name = file.getName();
@@ -1677,25 +1792,25 @@
if (isLauncherIcon(baseName)) {
// Launcher icons
- checkSize(context, folderName, file, 48, 48, true /*exact*/);
+ checkSize(context, folderName, file, 48, 48, true, /*exact*/folderConfig);
} else if (isActionBarIcon(baseName)) {
- checkSize(context, folderName, file, 32, 32, true /*exact*/);
+ checkSize(context, folderName, file, 32, 32, true, /*exact*/folderConfig);
} else if (name.startsWith("ic_dialog_")) { //$NON-NLS-1$
// Dialog
- checkSize(context, folderName, file, 32, 32, true /*exact*/);
+ checkSize(context, folderName, file, 32, 32, true, /*exact*/folderConfig);
} else if (name.startsWith("ic_tab_")) { //$NON-NLS-1$
// Tab icons
- checkSize(context, folderName, file, 32, 32, true /*exact*/);
+ checkSize(context, folderName, file, 32, 32, true, /*exact*/folderConfig);
} else if (isNotificationIcon(baseName)) {
// Notification icons
if (isAndroid30(context, folderVersion)) {
- checkSize(context, folderName, file, 24, 24, true /*exact*/);
+ checkSize(context, folderName, file, 24, 24, true, /*exact*/folderConfig);
} else if (isAndroid23(context, folderVersion)) {
- checkSize(context, folderName, file, 16, 25, false /*exact*/);
+ checkSize(context, folderName, file, 16, 25, false, /*exact*/folderConfig);
} else {
// Android 2.2 or earlier
// TODO: Should this be done for each folder size?
- checkSize(context, folderName, file, 25, 25, true /*exact*/);
+ checkSize(context, folderName, file, 25, 25, true, /*exact*/folderConfig);
}
} else if (name.startsWith("ic_menu_")) { //$NON-NLS-1$
if (isAndroid30(context, folderVersion)) {
@@ -1703,16 +1818,16 @@
// However the table halfway down the page on
// http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
// and the README in the icon template download says that convention is ic_menu
- checkSize(context, folderName, file, 32, 32, true);
+ checkSize(context, folderName, file, 32, 32, true, folderConfig);
} else if (isAndroid23(context, folderVersion)) {
// The icon should be 32x32 inside the transparent image; should
// we check that this is mostly the case (a few pixels are allowed to
// overlap for anti-aliasing etc)
- checkSize(context, folderName, file, 48, 48, true /*exact*/);
+ checkSize(context, folderName, file, 48, 48, true, /*exact*/folderConfig);
} else {
// Android 2.2 or earlier
// TODO: Should this be done for each folder size?
- checkSize(context, folderName, file, 48, 48, true /*exact*/);
+ checkSize(context, folderName, file, 48, 48, true, /*exact*/folderConfig);
}
}
// TODO: ListView icons?
@@ -1768,10 +1883,12 @@
}
private static void checkSize(Context context, String folderName, File file,
- int mdpiWidth, int mdpiHeight, boolean exactMatch) {
+ int mdpiWidth, int mdpiHeight, boolean exactMatch,
+ @Nullable FolderConfiguration folderConfig) {
String fileName = file.getName();
// Only scan .png files (except 9-patch png's) and jpg files
if (!((endsWith(fileName, DOT_PNG) && !endsWith(fileName, DOT_9PNG)) ||
+ endsWith(fileName, DOT_WEBP) ||
endsWith(fileName, DOT_JPG) || endsWith(fileName, DOT_JPEG))) {
return;
}
@@ -1798,6 +1915,11 @@
} else if (folderName.startsWith(DRAWABLE_LDPI)) {
width = Math.round(mdpiWidth * 3f / 4);
height = Math.round(mdpiHeight * 3f / 4);
+ } else if (folderConfig != null && folderConfig.getDensityQualifier() != null
+ && !folderConfig.getDensityQualifier().hasFakeValue()) {
+ Density density = folderConfig.getDensityQualifier().getValue();
+ width = mdpiWidth * density.getDpiValue() / Density.DEFAULT_DENSITY;
+ height = mdpiHeight * density.getDpiValue() / Density.DEFAULT_DENSITY;
} else {
return;
}
@@ -1824,7 +1946,7 @@
}
}
- public static Dimension getSize(File file) {
+ public static Dimension getSize(@NonNull File file) {
try {
ImageInputStream input = ImageIO.createImageInputStream(file);
if (input != null) {
@@ -1844,6 +1966,15 @@
}
}
+ // WEBP custom file header decoding, not available via ImageReaders outside
+ // of Android Studio since that requires native code around libwebp
+ if (endsWithIgnoreCase(file.getPath(), DOT_WEBP)) {
+ WebpHeader header = WebpHeader.getWebpHeader(file);
+ if (header != null && header.width > 0) {
+ return new Dimension(header.width, header.height);
+ }
+ }
+
// Fallback: read the image using the normal means
BufferedImage image = ImageIO.read(file);
if (image != null) {
@@ -1857,6 +1988,200 @@
}
}
+ @Nullable
+ private static String getWebpFormat(@NonNull File file) {
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(file));
+
+ // WEBP header:
+ //
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | 'R' | 'I' | 'F' | 'F' |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | File Size |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | 'W' | 'E' | 'B' | 'P' |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ //noinspection DuplicateCondition
+ if (is.read() != 'R' || is.read() != 'I' || is.read() != 'F' || is.read() != 'F' ||
+ is.read() == -1 || is.read() == -1 || is.read() == -1 || is.read() == -1 ||
+ is.read() != 'W' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') {
+ return null;
+ }
+
+ //See https://developers.google.com/speed/webp/docs/riff_container
+
+ if (is.read() != 'V' || is.read() != 'P' || is.read() != '8') {
+ return null;
+ }
+
+ // Found WEBP header. API level 15 is required for the simple format; extended
+ // or lossless formats require API 18.
+ int format = is.read();
+ if (format == 'L') {
+ return "VP8L";
+ } else if (format == 'X') {
+ return "VP8X";
+ } else if (format == ' ') {
+ return "VP8";
+ }
+ } catch (IOException ignore) {
+ } finally {
+ Closeables.closeQuietly(is);
+ }
+ return null;
+ }
+
+ private static class WebpHeader {
+ public String format;
+ int width;
+ int height;
+
+ @Nullable
+ private static WebpHeader getWebpHeader(@NonNull File file) {
+ try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {
+ // WEBP header:
+ //
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | 'R' | 'I' | 'F' | 'F' |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | File Size |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | 'W' | 'E' | 'B' | 'P' |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ //noinspection DuplicateCondition
+ if (is.read() != 'R' || is.read() != 'I' || is.read() != 'F' || is.read() != 'F' ||
+ is.read() == -1 || is.read() == -1 || is.read() == -1 || is.read() == -1 ||
+ is.read() != 'W' || is.read() != 'E' || is.read() != 'B'
+ || is.read() != 'P') {
+ return null;
+ }
+
+ // See https://developers.google.com/speed/webp/docs/riff_container
+
+ if (is.read() != 'V' || is.read() != 'P' || is.read() != '8') {
+ return null;
+ }
+
+ // Found WEBP header. API level 15 is required for the simple format; extended
+ // or lossless formats require API 18.
+ int format = is.read();
+ WebpHeader data = new WebpHeader();
+
+ if (format == 'L') {
+ data.format = "VP8L";
+
+ // https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#2_riff_header
+ // So far we've read up to number 5.
+ // "5. A little-endian 32-bit value of the number of bytes in the lossless
+ // stream."
+ for (int i = 0; i < 4; i++) {
+ //noinspection ResultOfMethodCallIgnored
+ is.read();
+ }
+
+ // "6. One byte signature 0x2f."
+ if (is.read() == 0x2f) { // signature
+ // "The first 28 bits of the bitstream specify the width and height of the
+ // image. Width and height are decoded as 14-bit integers as follows:
+ // int image_width = ReadBits(14) + 1;
+ // int image_height = ReadBits(14) + 1;"
+ int byte1 = is.read();
+ int byte2 = is.read();
+ int byte3 = is.read();
+ int byte4 = is.read();
+ if (is.read() != -1) {
+ data.width = ((byte2 & 0b111111) << 8 | byte1) + 1;
+ data.height = ((byte4 & 0b1111) << 10 | byte3 << 2 |
+ (byte2 & 0b11000000) >> 6) + 1;
+ } // else already reached end somehow: invalid file
+ }
+ return data;
+ } else if (format == 'X') {
+ // VP8X - extended file format
+ data.format = "VP8X";
+
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | WebP file header (12 bytes) |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | ChunkHeader('VP8X') |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |Rsv|I|L|E|X|A|R| Reserved |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Canvas Width Minus One | ...
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // ... Canvas Height Minus One |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ // Skip flags
+ for (int i = 0; i < 8; i++) {
+ //noinspection ResultOfMethodCallIgnored
+ is.read();
+ }
+
+ int byte1 = is.read();
+ int byte2 = is.read();
+ int byte3 = is.read();
+ int byte4 = is.read();
+ int byte5 = is.read();
+ int byte6 = is.read();
+
+ if (is.read() != -1) {
+ data.width = (byte1 | byte2 << 8 | byte3 << 16) + 1;
+ data.height = (byte4 | byte5 << 8 | byte6 << 16) + 1;
+ } // else already reached end somehow: invalid file
+
+ return data;
+ } else if (format == ' ') {
+ data.format = "VP8";
+
+ // https://tools.ietf.org/html/rfc6386#section-9
+
+ for (int i = 0; i < 7; i++) {
+ //noinspection ResultOfMethodCallIgnored
+ is.read();
+ }
+
+ // ---- Begin code block --------------------------------------
+ //
+ // Start code byte 0 0x9d
+ // Start code byte 1 0x01
+ // Start code byte 2 0x2a
+ //
+ // 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
+ // 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
+ //
+ // ---- End code block ----------------------------------------
+
+ if (is.read() == 0x9d && is.read() == 0x01 && is.read() == 0x2a) {
+ int byte1 = is.read();
+ int byte2 = is.read();
+ int byte3 = is.read();
+ int byte4 = is.read();
+ if (is.read() != -1) {
+ data.width = byte1 | ((byte2 & 0b111111) << 8);
+ data.height = byte3 | ((byte4 & 0b111111) << 8);
+ } // else already reached end somehow: invalid file
+ }
+
+ return data;
+ } else {
+ return null;
+ }
+ } catch (IOException ignore) {
+ }
+ return null;
+ }
+ }
private Set<String> mActionBarIcons;
private Set<String> mNotificationIcons;
@@ -1976,7 +2301,7 @@
@Override
public List<Class<? extends PsiElement>> getApplicablePsiTypes() {
- List<Class<? extends PsiElement>> types = new ArrayList<Class<? extends PsiElement>>(2);
+ List<Class<? extends PsiElement>> types = new ArrayList<>(2);
types.add(PsiNewExpression.class);
types.add(PsiMethod.class);
return types;
diff --git a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ManifestResourceDetector.java b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ManifestResourceDetector.java
index b2ff361..3aff8f0 100644
--- a/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ManifestResourceDetector.java
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/ManifestResourceDetector.java
@@ -33,6 +33,8 @@
import com.android.ide.common.res2.AbstractResourceRepository;
import com.android.ide.common.res2.ResourceItem;
import com.android.ide.common.resources.ResourceUrl;
+import com.android.ide.common.resources.configuration.DensityQualifier;
+import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.VersionQualifier;
import com.android.resources.FolderTypeRelationship;
import com.android.resources.ResourceFolderType;
@@ -211,8 +213,27 @@
continue;
}
- // Version qualifier is okay
- if (VersionQualifier.getQualifier(qualifiers) != null) {
+ // Version qualifier is okay, as is density qualifiers (or both)
+ int qualifierCount = 1;
+ for (int i = 0, n = qualifiers.length(); i < n; i++) {
+ if (qualifiers.charAt(i) == '-') {
+ qualifierCount++;
+ }
+ }
+ FolderConfiguration configuration = item.getConfiguration();
+ if (configuration == null) {
+ // shouldn't happen, but don't throw NPE on invalid projects
+ continue;
+ }
+ DensityQualifier densityQualifier = configuration.getDensityQualifier();
+ VersionQualifier versionQualifier = configuration.getVersionQualifier();
+ if (qualifierCount == 1 &&
+ (versionQualifier != null && versionQualifier.isValid()
+ || densityQualifier != null && densityQualifier.isValid())) {
+ continue;
+ } else if (qualifierCount == 2 &&
+ densityQualifier != null && densityQualifier.isValid() &&
+ versionQualifier != null && versionQualifier.isValid()) {
continue;
}
diff --git a/lint/libs/lint-tests/BUILD b/lint/libs/lint-tests/BUILD
index 19aa1b7..16d523c 100644
--- a/lint/libs/lint-tests/BUILD
+++ b/lint/libs/lint-tests/BUILD
@@ -6,9 +6,9 @@
"//tools/base/annotations",
"//tools/base/common:tools.common",
"//tools/base/layoutlib-api:tools.layoutlib-api",
- "//tools/base/lint/cli",
"//tools/base/lint:tools.lint-api",
"//tools/base/lint:tools.lint-checks",
+ "//tools/base/lint/cli",
"//tools/base/sdk-common:tools.sdk-common",
"//tools/base/sdklib:tools.sdklib",
"//tools/base/testutils:tools.testutils",
@@ -24,7 +24,10 @@
java_test(
name = "tests",
srcs = glob(["src/test/java/**"]),
- javacopts = ["-extra_checks:off"],
+ data = [
+ "//prebuilts/studio/sdk:platform-tools",
+ "//prebuilts/studio/sdk:platforms/latest",
+ ],
jvm_flags = ["-Dtest.suite.jar=tests.jar"],
test_class = "com.android.tools.lint.LintBazelSuite",
deps = [
@@ -33,9 +36,9 @@
"//tools/base/build-system/builder-model",
"//tools/base/common:tools.common",
"//tools/base/layoutlib-api:tools.layoutlib-api",
- "//tools/base/lint/cli",
"//tools/base/lint:tools.lint-api",
"//tools/base/lint:tools.lint-checks",
+ "//tools/base/lint/cli",
"//tools/base/repository:tools.repository",
"//tools/base/sdk-common:tools.sdk-common",
"//tools/base/sdklib:tools.sdklib",
@@ -43,6 +46,7 @@
"//tools/base/third_party:com.android.tools.external.com-intellij_uast",
"//tools/base/third_party:com.android.tools.external.lombok_lombok-ast",
"//tools/base/third_party:com.google.code.gson_gson",
+ "//tools/base/third_party:com.google.truth_truth",
"//tools/base/third_party:com.intellij_annotations",
"//tools/base/third_party:net.sf.kxml_kxml2",
"//tools/base/third_party:org.codehaus.groovy_groovy-all",
@@ -50,8 +54,4 @@
"//tools/base/third_party:org.mockito_mockito-all",
"//tools/base/third_party:org.ow2.asm_asm-tree",
],
- data = [
- "//prebuilts/studio/sdk:platforms/latest",
- "//prebuilts/studio/sdk:platform-tools",
- ]
)
diff --git a/lint/libs/lint-tests/lint-tests.iml b/lint/libs/lint-tests/lint-tests.iml
index 2e740a8..a8fbd0b 100644
--- a/lint/libs/lint-tests/lint-tests.iml
+++ b/lint/libs/lint-tests/lint-tests.iml
@@ -23,5 +23,6 @@
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
<orderEntry type="library" name="ecj" level="project" />
<orderEntry type="module" module-name="sdk-common-base" />
+ <orderEntry type="library" scope="TEST" name="truth" level="project" />
</component>
</module>
\ No newline at end of file
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/LintBazelSuite.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/LintBazelSuite.java
index 745d8f2..c8323ba 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/LintBazelSuite.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/LintBazelSuite.java
@@ -25,6 +25,8 @@
import com.android.tools.lint.checks.SupportAnnotationDetectorTest;
import com.android.tools.lint.checks.TypoDetectorTest;
import com.android.tools.lint.checks.TypoLookupTest;
+import com.android.tools.lint.checks.UnpackedNativeCodeDetectorTest;
+import com.android.tools.lint.client.api.CustomRuleTest;
import org.junit.runner.RunWith;
@@ -36,6 +38,7 @@
AnnotationDetectorTest.class,
ApiDetectorTest.class,
CallSuperDetectorTest.class,
+ CustomRuleTest.class,
JavaScriptInterfaceDetectorTest.class,
LintBazelSuite.class,
MainTest.class,
@@ -43,5 +46,6 @@
SupportAnnotationDetectorTest.class,
TypoDetectorTest.class,
TypoLookupTest.class,
+ UnpackedNativeCodeDetectorTest.class,
})
public class LintBazelSuite {}
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiDetectorTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiDetectorTest.java
index d26c0ac..ff9b10e 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiDetectorTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiDetectorTest.java
@@ -191,7 +191,32 @@
+ "0 errors, 1 warnings\n",
lintProject(
- manifest().minSdk(4),
+ xml("AndroidManifest.xml", ""
+ + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ + " package=\"test.pkg\" >\n"
+ + "\n"
+ + " <uses-sdk\n"
+ + " android:minSdkVersion=\"4\"\n"
+ + " android:targetSdkVersion=\"25\" />\n"
+ + "\n"
+ + " <application\n"
+ + " android:allowBackup=\"true\"\n"
+ + " android:icon=\"@mipmap/ic_launcher\"\n"
+ + " android:label=\"@string/app_name\"\n"
+ + " android:roundIcon=\"@mipmap/ic_launcher_round\"\n"
+ + " android:supportsRtl=\"true\"\n"
+ + " android:theme=\"@style/AppTheme\" >\n"
+ + " <activity android:name=\".MainActivity\" >\n"
+ + " <intent-filter>\n"
+ + " <action android:name=\"android.intent.action.MAIN\" />\n"
+ + "\n"
+ + " <category android:name=\"android.intent.category.LAUNCHER\" />\n"
+ + " </intent-filter>\n"
+ + " </activity>\n"
+ + " </application>\n"
+ + "\n"
+ + "</manifest>"),
xml("res/layout/labelfor.xml", ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiLookupTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiLookupTest.java
index 4c1c91f..adfe6fb 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiLookupTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ApiLookupTest.java
@@ -259,13 +259,8 @@
raf.close();
lookup = ApiLookup.get(new LookupTestClient());
// This data is now truncated: lookup returns the wrong size.
- try {
- assertNotNull(lookup);
- lookup.getFieldVersion("android/R$attr", "actionMenuTextAppearance");
- fail("Can't look up bogus data");
- } catch (Throwable t) {
- // Expected this: the database is corrupted.
- }
+ assertNotNull(lookup);
+ lookup.getFieldVersion("android/R$attr", "actionMenuTextAppearance");
assertTrue(message.contains("Please delete the file and restart the IDE/lint:"));
assertTrue(message.contains(mCacheDir.getPath()));
ApiLookup.dispose();
@@ -296,7 +291,9 @@
assertEquals(desc, expected, actual);
}
- public void testFindEverything() throws Exception {
+ // Flaky test - http://b.android.com/225879
+ @SuppressWarnings("unused")
+ public void ignoredTestFindEverything() throws Exception {
// Load the API versions file and look up every single method/field/class in there
// (provided since != 1) and also check the deprecated calls.
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/GradleDetectorTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/GradleDetectorTest.java
index a713b9b..c0f1cac 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/GradleDetectorTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/GradleDetectorTest.java
@@ -43,6 +43,7 @@
import com.android.builder.model.AndroidArtifact;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.Dependencies;
+import com.android.builder.model.JavaLibrary;
import com.android.builder.model.MavenCoordinates;
import com.android.builder.model.Variant;
import com.android.ide.common.repository.GradleCoordinate;
@@ -883,6 +884,66 @@
+ " compile \"com.android.support:preference-v7:25.0-SNAPSHOT\""
+ " compile \"com.android.support:cardview-v7:24.2\""
+ " compile \"com.android.support:multidex:1.0.1\""
+ + " compile \"com.android.support:support-annotations:25.0.0\""
+ + "}\n")));
+ }
+
+ public void testWearableConsistency1() throws Exception {
+ // Regression test 1 for b/29006320.
+ // Requires custom model mocks
+ mEnabled = Collections.singleton(COMPATIBILITY);
+ assertEquals(""
+ + "build.gradle:4: Error: Project depends on com.google.android.support:wearable:2.0.0-alpha3, so it must also depend (as a provided dependency) on com.google.android.wearable:wearable:2.0.0-alpha3 [GradleCompatible]\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ + "1 errors, 0 warnings\n",
+
+ lintProjectIncrementally("build.gradle",
+ source("build.gradle", ""
+ + "apply plugin: 'android'\n"
+ + "\n"
+ + "dependencies {\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + "}\n")));
+ }
+
+ public void testWearableConsistency2() throws Exception {
+ // Regression test 2 for b/29006320.
+ // Requires custom model mocks
+ mEnabled = Collections.singleton(COMPATIBILITY);
+ assertEquals(""
+ + "build.gradle:4: Error: The wearable libraries for com.google.android.support and com.google.android.wearable must use exactly the same versions; found 2.0.0-alpha3 and 2.0.0-alpha4 [GradleCompatible]\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ + "1 errors, 0 warnings\n",
+
+ lintProjectIncrementally("build.gradle",
+ source("build.gradle", ""
+ + "apply plugin: 'android'\n"
+ + "\n"
+ + "dependencies {\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + " provided \"com.google.android.wearable:wearable:2.0.0-alpha4\"\n"
+ + "}\n")));
+ }
+
+ public void testWearableConsistency3() throws Exception {
+ // Regression test 3 for b/29006320.
+ // Requires custom model mocks
+ mEnabled = Collections.singleton(COMPATIBILITY);
+ assertEquals(""
+ + "build.gradle:4: Error: This dependency should be marked as provided, not compile [GradleCompatible]\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ + "1 errors, 0 warnings\n",
+
+ lintProjectIncrementally("build.gradle",
+ source("build.gradle", ""
+ + "apply plugin: 'android'\n"
+ + "\n"
+ + "dependencies {\n"
+ + " compile \"com.google.android.support:wearable:2.0.0-alpha3\"\n"
+ + " compile \"com.google.android.wearable:wearable:2.0.0-alpha3\"\n"
+ "}\n")));
}
@@ -1186,6 +1247,7 @@
when(dependencies.getLibraries()).thenReturn(libraries);
AndroidArtifact artifact = mock(AndroidArtifact.class);
+ //noinspection deprecation
when(artifact.getDependencies()).thenReturn(dependencies);
when(artifact.getCompileDependencies()).thenReturn(dependencies);
@@ -1234,6 +1296,70 @@
};
}
+ if (getName().startsWith("testWearableConsistency")) {
+ return new Project(this, dir, referenceDir) {
+ @Override
+ public boolean isGradleProject() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Variant getCurrentVariant() {
+ // Simulate variant which has an AndroidLibrary various combinations
+ // of the com.google.android.support:wearable and
+ // com.google.android.wearable libraries, which must be in sync.
+ // See b/29006320.
+ List<AndroidLibrary> androidLibraries;
+ List<JavaLibrary> javaLibraries;
+ if ("testWearableConsistency1".equals(GradleDetectorTest.this.getName())) {
+ // Missing wearable library: not ok
+ androidLibraries = Collections.singletonList(
+ createMockLibrary(
+ "com.google.android.support:wearable:2.0.0-alpha3")
+ );
+ javaLibraries = Collections.emptyList();
+ } else if ("testWearableConsistency2".equals(GradleDetectorTest.this.getName())) {
+ // Different versions: not ok
+ androidLibraries = Collections.singletonList(
+ createMockLibrary(
+ "com.google.android.support:wearable:2.0.0-alpha3")
+ );
+ javaLibraries = Collections.singletonList(
+ createMockJavaLibrary("com.google.android.wearable:wearable:2.0.0-alpha4", true)
+ );
+ } else if ("testWearableConsistency3".equals(GradleDetectorTest.this.getName())) {
+ // Same versions, but wear library wasn't reported
+ androidLibraries = Collections.singletonList(
+ createMockLibrary(
+ "com.google.android.support:wearable:2.0.0-alpha3")
+ );
+ javaLibraries = Collections.singletonList(
+ createMockJavaLibrary(
+ "com.google.android.wearable:wearable:2.0.0-alpha3", false)
+ );
+ } else {
+ fail("Unexpected test " + getName());
+ return null;
+ }
+
+
+ Dependencies dependencies = mock(Dependencies.class);
+ when(dependencies.getLibraries()).thenReturn(androidLibraries);
+ when(dependencies.getJavaLibraries()).thenReturn(javaLibraries);
+
+ AndroidArtifact artifact = mock(AndroidArtifact.class);
+ //noinspection deprecation
+ when(artifact.getDependencies()).thenReturn(dependencies);
+ when(artifact.getCompileDependencies()).thenReturn(dependencies);
+
+ Variant variant = mock(Variant.class);
+ when(variant.getMainArtifact()).thenReturn(artifact);
+ return variant;
+ }
+ };
+ }
+
if ("testSupportLibraryConsistency".equals(getName())
|| "testSupportLibraryConsistencyNonIncremental".equals(getName())) {
return new Project(this, dir, referenceDir) {
@@ -1245,15 +1371,16 @@
@Nullable
@Override
public Variant getCurrentVariant() {
- /*
- Simulate variant which has an AndroidLibrary with
- resolved coordinates
+ /*
+ Simulate variant which has an AndroidLibrary with
+ resolved coordinates
- compile "com.android.support:appcompat-v7:24.2"
- compile "com.android.support:support-v13:24.1"
- compile "com.android.support:preference-v7:25.0-SNAPSHOT"
- compile "com.android.support:cardview-v7:24.2"
- */
+ compile "com.android.support:appcompat-v7:24.2"
+ compile "com.android.support:support-v13:24.1"
+ compile "com.android.support:preference-v7:25.0-SNAPSHOT"
+ compile "com.android.support:cardview-v7:24.2"
+ compile "com.android.support:support-annotations:25.0.0" // allowed
+ */
List<AndroidLibrary> libraries = Arrays.asList(
createMockLibrary("com.android.support:appcompat-v7:24.2"),
createMockLibrary("com.android.support:support-v13:24.1"),
@@ -1261,11 +1388,16 @@
createMockLibrary("com.android.support:cardview-v7:24.2"),
createMockLibrary("com.android.support:multidex:1.0.1")
);
+ List<JavaLibrary> javaLibraries = Collections.singletonList(
+ createMockJavaLibrary(
+ "com.android.support:support-annotations:25.0.0"));
Dependencies dependencies = mock(Dependencies.class);
when(dependencies.getLibraries()).thenReturn(libraries);
+ when(dependencies.getJavaLibraries()).thenReturn(javaLibraries);
AndroidArtifact artifact = mock(AndroidArtifact.class);
+ //noinspection deprecation
when(artifact.getDependencies()).thenReturn(dependencies);
when(artifact.getCompileDependencies()).thenReturn(dependencies);
@@ -1280,6 +1412,10 @@
}
private AndroidLibrary createMockLibrary(String s) {
+ return createMockLibrary(s, false);
+ }
+
+ private AndroidLibrary createMockLibrary(String s, boolean isProvided) {
GradleCoordinate coordinate = GradleCoordinate.parseCoordinateString(s);
assertNotNull(coordinate);
MavenCoordinates mavenCoordinates = mock(MavenCoordinates.class);
@@ -1291,6 +1427,27 @@
AndroidLibrary library1 = mock(AndroidLibrary.class);
when(library1.getResolvedCoordinates()).thenReturn(mavenCoordinates);
when(library1.getLintJar()).thenReturn(new File("lint.jar"));
+ when(library1.isProvided()).thenReturn(isProvided);
+
+ return library1;
+ }
+
+ private JavaLibrary createMockJavaLibrary(String s) {
+ return createMockJavaLibrary(s, false);
+ }
+
+ private JavaLibrary createMockJavaLibrary(String s, boolean isProvided) {
+ GradleCoordinate coordinate = GradleCoordinate.parseCoordinateString(s);
+ assertNotNull(coordinate);
+ MavenCoordinates mavenCoordinates = mock(MavenCoordinates.class);
+ when(mavenCoordinates.getGroupId()).thenReturn(coordinate.getGroupId());
+ when(mavenCoordinates.getArtifactId()).thenReturn(coordinate.getArtifactId());
+ when(mavenCoordinates.getVersion()).thenReturn(coordinate.getRevision());
+ when(mavenCoordinates.toString()).thenReturn(s);
+
+ JavaLibrary library1 = mock(JavaLibrary.class);
+ when(library1.getResolvedCoordinates()).thenReturn(mavenCoordinates);
+ when(library1.isProvided()).thenReturn(isProvided);
return library1;
}
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/IconDetectorTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/IconDetectorTest.java
index f7904eb..aa4716f 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/IconDetectorTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/IconDetectorTest.java
@@ -34,6 +34,7 @@
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Project;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -72,6 +73,8 @@
ALL.add(IconDetector.ICON_XML_AND_PNG);
ALL.add(IconDetector.ICON_LAUNCHER_SHAPE);
ALL.add(IconDetector.ICON_MIX_9PNG);
+ ALL.add(IconDetector.WEBP_ELIGIBLE);
+ ALL.add(IconDetector.WEBP_UNSUPPORTED);
}
@Override
@@ -255,6 +258,18 @@
+ "</selector>\n")));
}
+ public void testNoWarningForMipmapsOnly() throws Exception {
+ // Regression test for https://code.google.com/p/android/issues/detail?id=162958
+ mEnabled = ImmutableSet.of(IconDetector.ICON_MISSING_FOLDER);
+ assertEquals("No warnings.",
+
+ lintProject(
+ xml("res/drawable/foo.xml", "<bitmap/>"),
+ image("res/drawable-nodpi/file1.png", 472, 290).fill(0xFFFFFFFF).fill(10, 10, 362, 280, 0x00000000),
+ image("res/mipmap-hdpi/frame.png", 472, 290).fill(0xFFFFFFFF).fill(10, 10, 362, 280, 0x00000000),
+ image("res/mipmap-mdpi/frame.png", 472, 290).fill(0xFFFFFFFF).fill(10, 10, 362, 280, 0x00000000)));
+ }
+
public void testMixedFormat() throws Exception {
mEnabled = ALL;
// Test having a mixture of .xml and .png resources for the same name
@@ -331,6 +346,22 @@
image("res/drawable-mdpi/sample_icon.png", 48, 48).format("GIF").fill(10, 10, 20, 20, 0xFF00FFFF)));
}
+ public void testMisleadingWebpFileName() throws Exception {
+ mEnabled = Collections.singleton(IconDetector.ICON_EXTENSION);
+ assertEquals(""
+ + "res/drawable-mdpi/foo.png: Warning: Misleading file extension; named .png but the file format is webp [IconExtension]\n"
+ + "0 errors, 1 warnings\n",
+
+ lintProject(
+ base64gzip("res/drawable-mdpi/foo.png", ""
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA=="),
+ base64gzip("res/drawable-mdpi/ok.webp", ""
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA==")
+ ));
+ }
+
public void testColors() throws Exception {
mEnabled = Collections.singleton(IconDetector.ICON_COLORS);
//noinspection all // Sample code
@@ -462,6 +493,23 @@
));
}
+ public void testExpectedSizeMipmap() throws Exception {
+ mEnabled = Collections.singleton(IconDetector.ICON_EXPECTED_SIZE);
+ //noinspection all // Sample code
+ assertEquals(""
+ + "res/mipmap-mdpi/ic_launcher.png: Warning: Incorrect icon size for mipmap-mdpi/ic_launcher.png: expected 48x48, but was 24x24 [IconExpectedSize]\n"
+ + "0 errors, 1 warnings\n",
+
+ lintProject(
+ manifest().minSdk(14),
+ // 3 wrong-sized icons:
+ image("res/mipmap-mdpi/ic_launcher.png", 24, 24),
+
+ // OK sizes
+ image("res/mipmap-xxhdpi/ic_launcher2.png", 144, 144).fill(10, 10, 20, 20, 0xFF00FFFF)
+ ));
+ }
+
public void testAbbreviate() throws Exception {
mEnabled = Collections.singleton(IconDetector.ICON_DENSITIES);
//noinspection all // Sample code
@@ -626,6 +674,34 @@
));
}
+ public void testClaimedSizeWebp() throws Exception {
+ // Check size decoding of webp headers
+ mEnabled = Collections.singleton(IconDetector.ICON_DIP_SIZE);
+ assertEquals(""
+ + "res/drawable-mdpi/my_lossless_72dp.webp: Warning: Suspicious file name my_lossless_72dp.webp: The implied 72 dp size does not match the actual dp size (pixel size 58×56 in a drawable-mdpi folder computes to 58×56 dp) [IconDipSize]\n"
+ + "res/mipmap-mdpi/my_lossy2_72dp.webp: Warning: Suspicious file name my_lossy2_72dp.webp: The implied 72 dp size does not match the actual dp size (pixel size 58×56 in a mipmap-mdpi folder computes to 58×56 dp) [IconDipSize]\n"
+ + "res/drawable-mdpi/my_lossy_72dp.webp: Warning: Suspicious file name my_lossy_72dp.webp: The implied 72 dp size does not match the actual dp size (pixel size 58×56 in a drawable-mdpi folder computes to 58×56 dp) [IconDipSize]\n"
+ + "0 errors, 3 warnings\n",
+ lintProject(
+ manifest().minSdk(1),
+ base64gzip("res/drawable-mdpi/my_lossy_72dp.webp", ""
+ // Lossy
+ + "H4sIAAAAAAAAAAvydHPzYGBgCHd1CggLsFCwAbIvMDPMZdSyYrBgsJvoscBH"
+ + "dYmykhIHwwYhzkyGMgYGhbxlC7g+chcxMPw7vf3/Wx8ht6D//wV23zjUANTK"
+ + "AADVeQHzUAAAAA=="),
+ base64gzip("res/mipmap-mdpi/my_lossy2_72dp.webp", ""
+ // Lossy
+ + "H4sIAAAAAAAAAAvydHPzYGBgCHd1CggLsFCwAbIvMDPMZdSyYrBgsJvoscBH"
+ + "dYmykhIHwwYhzkyGMgYGhbxlC7g+chcxMPw7vf3/Wx8ht6D//wV23zjUANTK"
+ + "AADVeQHzUAAAAA=="),
+
+ base64gzip("res/drawable-mdpi/my_lossless_72dp.webp", ""
+ // Lossless
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA==")
+ ));
+ }
+
public void testResConfigs1() throws Exception {
// resConfigs in the Gradle model sets up the specific set of resource configs
// that are included in the packaging: we use this to limit the set of required
@@ -673,6 +749,67 @@
image("res/drawable-xlarge-nodpi-v11/frame.png", 472, 290).fill(0xFFFFFFFF).fill(10, 10, 362, 280, 0x00000000)));
}
+ public void testWebpEligible() throws Exception {
+ mEnabled = ImmutableSet.of(IconDetector.WEBP_ELIGIBLE);
+
+ assertEquals(""
+ + "res/drawable/ic_launcher.png: Warning: One or more images in this project can be converted to the WebP format which typically results in smaller file sizes, even for lossless conversion. [ConvertToWebp]\n"
+ + "0 errors, 1 warnings\n",
+
+ lintProject(
+ manifest().minSdk(17),
+ image("res/drawable/ic_launcher.png", 48, 48).fill(10, 10, 20, 20, 0xFF00FFFF)));
+ }
+
+ public void testWebpUnsupported() throws Exception {
+ mEnabled = ImmutableSet.of(IconDetector.WEBP_ELIGIBLE, IconDetector.WEBP_UNSUPPORTED);
+ assertEquals(""
+ + "res/mipmap-mdpi/my_lossless.webp: Error: WebP extended or lossless format requires Android 4.2.1 (API 18); current minSdkVersion is 10 [WebpUnsupported]\n"
+ + "res/drawable-mdpi-v13/my_lossless.webp: Error: WebP extended or lossless format requires Android 4.2.1 (API 18); current minSdkVersion is 13 [WebpUnsupported]\n"
+ + "res/drawable-mdpi/my_lossy.webp: Error: WebP requires Android 4.0 (API 15); current minSdkVersion is 10 [WebpUnsupported]\n"
+ + "3 errors, 0 warnings\n",
+
+ lintProject(
+ manifest().minSdk(10),
+ // "PNG" format: cheating since we don't have a WEBP encoder outside of
+ // Studio, but we know lint won't actually look inside these files
+ // yet
+
+ // OK: lossy webp okay in API 15 and up
+ base64gzip("res/drawable-mdpi-v15/my_lossy.webp", ""
+ + "H4sIAAAAAAAAAAvydHPzYGBgCHd1CggLsFCwAbIvMDPMZdSyYrBgsJvoscBH"
+ + "dYmykhIHwwYhzkyGMgYGhbxlC7g+chcxMPw7vf3/Wx8ht6D//wV23zjUANTK"
+ + "AADVeQHzUAAAAA=="),
+
+ // Error: requires API level 15
+ base64gzip("res/drawable-mdpi/my_lossy.webp", ""
+ + "H4sIAAAAAAAAAAvydHPzYGBgCHd1CggLsFCwAbIvMDPMZdSyYrBgsJvoscBH"
+ + "dYmykhIHwwYhzkyGMgYGhbxlC7g+chcxMPw7vf3/Wx8ht6D//wV23zjUANTK"
+ + "AADVeQHzUAAAAA=="),
+
+ // Error: requires API level 18
+ base64gzip("res/mipmap-mdpi/my_lossless.webp", ""
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA=="),
+
+ // Error: requires API level 18; has minSdk 13
+ base64gzip("res/drawable-mdpi-v13/my_lossless.webp", ""
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA=="),
+
+ // OK: requires API 15 but is in v16 folder
+ base64gzip("res/drawable-mdpi-v16/my_lossless.webp", "" // still not okay needs 18
+ + "H4sIAAAAAAAAAAvydHPzYGBgCHd1CggLsFCwAbIvMDPMZdSyYrBgsJvoscBH"
+ + "dYmykhIHwwYhzkyGMgYGhbxlC7g+chcxMPw7vf3/Wx8ht6D//wV23zjUANTK"
+ + "AADVeQHzUAAAAA=="),
+
+ // OK: requires API 18 but is in v18 folder
+ base64gzip("res/drawable-mdpi-v18/my_lossless.webp", "" // OK 18
+ + "H4sIAAAAAAAAAAvydHNTYWBgCHd1CggLsPARB7L1LQ/wMrBf2O/3ddt/RgXF"
+ + "P/XrXb/Yf2VkAABv2HPZLAAAAA==")
+ ));
+ }
+
@Override
protected TestLintClient createClient() {
String testName = getName();
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ManifestResourceDetectorTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ManifestResourceDetectorTest.java
index 3c0d081..f603034 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ManifestResourceDetectorTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/ManifestResourceDetectorTest.java
@@ -292,4 +292,43 @@
+ "</resources>")
));
}
+
+ public void testRoundIcon() throws Exception {
+ // Allow round icons in density folders
+ // Regression test for https://code.google.com/p/android/issues/detail?id=225711
+ assertEquals("No warnings.",
+ lintProjectIncrementally(
+ "AndroidManifest.xml",
+ xml("AndroidManifest.xml", ""
+ + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ + " package=\"webp.test.tools.android.com.myapplication\" >\n"
+ + " <application\n"
+ + " android:roundIcon=\"@mipmap/round_icon\" />\n"
+ + "</manifest>"),
+ image("res/mipmap-mdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-hdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-xhdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-xxhdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-xxxhdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF)
+ ));
+ }
+
+ public void testAnyDensity() throws Exception {
+ // Allow round icons in density folders
+ assertEquals("No warnings.",
+ lintProjectIncrementally(
+ "AndroidManifest.xml",
+ xml("AndroidManifest.xml", ""
+ + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ + " package=\"webp.test.tools.android.com.myapplication\" >\n"
+ + " <application\n"
+ + " android:randomAttribute=\"@mipmap/round_icon\" />\n"
+ + "</manifest>"),
+ image("res/mipmap-mdpi/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-hdpi-v4/round_icon.png", 472, 290).fill(0xFFFFFFFF),
+ image("res/mipmap-v21/round_icon.png", 472, 290).fill(0xFFFFFFFF)
+ ));
+ }
}
\ No newline at end of file
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.java
index 7b24da8..74fd6e2 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.java
@@ -26,16 +26,17 @@
import com.android.tools.lint.detector.api.Speed;
import java.io.File;
+import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
@SuppressWarnings("SpellCheckingInspection")
public class JarFileIssueRegistryTest extends AbstractCheckTest {
- public void testError() {
+ public void testError() throws Exception {
try {
JarFileIssueRegistry.get(createClient(), new File("bogus"));
fail("Expected exception for bogus path");
- } catch (Throwable t) {
+ } catch (IOException expected) {
// pass
}
}
diff --git a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/detector/api/SeverityTest.java b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/detector/api/SeverityTest.java
index 5baa65e..9d5183d 100644
--- a/lint/libs/lint-tests/src/test/java/com/android/tools/lint/detector/api/SeverityTest.java
+++ b/lint/libs/lint-tests/src/test/java/com/android/tools/lint/detector/api/SeverityTest.java
@@ -16,36 +16,38 @@
package com.android.tools.lint.detector.api;
+import static com.google.common.truth.Truth.assertThat;
+
import junit.framework.TestCase;
public class SeverityTest extends TestCase {
public void testGetName() {
- assertEquals("ERROR", Severity.ERROR.getName());
- assertEquals("WARNING", Severity.WARNING.getName());
+ assertThat(Severity.ERROR.getName()).isEqualTo("ERROR");
+ assertThat(Severity.WARNING.getName()).isEqualTo("WARNING");
}
public void testGetDescription() {
- assertEquals("Error", Severity.ERROR.getDescription());
- assertEquals("Warning", Severity.WARNING.getDescription());
+ assertThat(Severity.ERROR.getDescription()).isEqualTo("Error");
+ assertThat(Severity.WARNING.getDescription()).isEqualTo("Warning");
}
public void testFromString() {
- assertSame(Severity.ERROR, Severity.fromName("ERROR"));
- assertSame(Severity.ERROR, Severity.fromName("error"));
- assertSame(Severity.ERROR, Severity.fromName("Error"));
- assertSame(Severity.WARNING, Severity.fromName("WARNING"));
- assertSame(Severity.WARNING, Severity.fromName("warning"));
- assertSame(Severity.FATAL, Severity.fromName("FATAL"));
- assertSame(Severity.INFORMATIONAL, Severity.fromName("Informational"));
- assertSame(Severity.IGNORE, Severity.fromName("ignore"));
- assertSame(Severity.IGNORE, Severity.fromName("IGNORE"));
+ assertThat(Severity.fromName("ERROR")).isSameAs(Severity.ERROR);
+ assertThat(Severity.fromName("error")).isSameAs(Severity.ERROR);
+ assertThat(Severity.fromName("Error")).isSameAs(Severity.ERROR);
+ assertThat(Severity.fromName("WARNING")).isSameAs(Severity.WARNING);
+ assertThat(Severity.fromName("warning")).isSameAs(Severity.WARNING);
+ assertThat(Severity.fromName("FATAL")).isSameAs(Severity.FATAL);
+ assertThat(Severity.fromName("Informational")).isSameAs(Severity.INFORMATIONAL);
+ assertThat(Severity.fromName("ignore")).isSameAs(Severity.IGNORE);
+ assertThat(Severity.fromName("IGNORE")).isSameAs(Severity.IGNORE);
}
public void testCompare() {
- assertTrue(Severity.IGNORE.compareTo(Severity.ERROR) > 0);
- assertTrue(Severity.WARNING.compareTo(Severity.ERROR) > 0);
- assertTrue(Severity.ERROR.compareTo(Severity.ERROR) == 0);
- assertTrue(Severity.FATAL.compareTo(Severity.ERROR) < 0);
- assertTrue(Severity.WARNING.compareTo(Severity.ERROR) > 0);
+ assertThat(Severity.IGNORE).isGreaterThan(Severity.ERROR);
+ assertThat(Severity.WARNING).isGreaterThan(Severity.ERROR);
+ assertThat(Severity.ERROR).isEquivalentAccordingToCompareTo(Severity.ERROR);
+ assertThat(Severity.FATAL).isLessThan(Severity.ERROR);
+ assertThat(Severity.WARNING).isGreaterThan(Severity.ERROR);
}
}
diff --git a/lint/libs/uast/NOTICE b/lint/libs/uast/NOTICE
new file mode 100644
index 0000000..4c4a741
--- /dev/null
+++ b/lint/libs/uast/NOTICE
@@ -0,0 +1,202 @@
+
+ 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 2000-2016 JetBrains s.r.o.
+
+ 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.
diff --git a/lint/libs/uast/build.gradle b/lint/libs/uast/build.gradle
new file mode 100644
index 0000000..dc4a322
--- /dev/null
+++ b/lint/libs/uast/build.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'java'
+
+group = 'com.android.tools.external.intellij'
+archivesBaseName = 'uast'
+version = '145.597.3'
+
+jar {
+ from zipTree("../../../../../prebuilts/tools/common/uast/uast-" + version + ".jar")
+}
+
+project.ext.pomName = 'IntelliJ IDEA AST API (PSI) Subset'
+project.ext.pomDesc = 'A subset of IntelliJ IDEA\'s AST APIs and implementation, focusing on the read-only aspects, intended for use by Android Lint when running outside of the IDE (typically from Gradle.). Based on IntelliJ IDEA tag idea/' + version + '.'
+
+apply from: "$rootDir/buildSrc/base/publish.gradle"
+apply from: "$rootDir/buildSrc/base/bintray.gradle"
+apply from: "$rootDir/buildSrc/base/javadoc.gradle"
+
diff --git a/lint/libs/uast/src/main/java/com/android/tools/external/intellij/uast/Main.java b/lint/libs/uast/src/main/java/com/android/tools/external/intellij/uast/Main.java
new file mode 100644
index 0000000..62ada69
--- /dev/null
+++ b/lint/libs/uast/src/main/java/com/android/tools/external/intellij/uast/Main.java
@@ -0,0 +1,13 @@
+package com.android.tools.external.intellij.uast;
+
+/**
+ * This is a dummy place-holder class for the PSI/UAST library
+ * used by lint. The bytecode for this library is not generated
+ * from source; it's extracted from an IDE installation by the
+ * bytecode manipulation code found in tools/base/misc/psi-extractor.
+ */
+public class Main {
+ public static void main(String[] args) {
+ // This class is here to make the packaging and javadoc tasks happy
+ }
+}
diff --git a/ninepatch/BUILD b/ninepatch/BUILD
index c9c37a6..975480d 100644
--- a/ninepatch/BUILD
+++ b/ninepatch/BUILD
@@ -3,7 +3,6 @@
iml_module(
name = "studio.ninepatch",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = [
"src/test/java",
diff --git a/perflib/BUILD b/perflib/BUILD
index 798e2bb..3b8eeac 100644
--- a/perflib/BUILD
+++ b/perflib/BUILD
@@ -3,16 +3,17 @@
iml_module(
name = "studio.perflib",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/base/ddmlib:studio.ddmlib[module]",
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/idea/.idea/libraries:Trove4j",
"//tools/base/testutils:studio.testutils[module, test]",
"//tools/idea/.idea/libraries:mockito[test]",
+ "//tools/idea/.idea/libraries:truth[test]",
],
)
diff --git a/perflib/build.gradle b/perflib/build.gradle
deleted file mode 100644
index d59b582..0000000
--- a/perflib/build.gradle
+++ /dev/null
@@ -1,22 +0,0 @@
-apply plugin: 'java'
-apply plugin: 'jacoco'
-
-group = 'com.android.tools.perflib'
-archivesBaseName = 'perflib'
-version = rootProject.ext.baseVersion
-
-dependencies {
- compile project(':base:ddmlib')
-
- compile 'net.sf.trove4j:trove4j:1.1'
-
- testCompile 'org.easymock:easymock:3.1'
- testCompile 'junit:junit:4.12'
- testCompile project(':base:testutils')
- testCompile 'org.mockito:mockito-all:1.9.5'
-}
-
-project.ext.pomName = 'Android Tools perflib'
-project.ext.pomDesc = 'Library to handle android performance data'
-
-apply from: "$rootDir/buildSrc/base/javadoc.gradle"
diff --git a/perflib/perflib.iml b/perflib/perflib.iml
index 79ab1df..36cf14d 100644
--- a/perflib/perflib.iml
+++ b/perflib/perflib.iml
@@ -14,5 +14,6 @@
<orderEntry type="library" name="Trove4j" level="project" />
<orderEntry type="module" module-name="testutils" scope="TEST" />
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
+ <orderEntry type="library" scope="TEST" name="truth" level="project" />
</component>
-</module>
+</module>
\ No newline at end of file
diff --git a/perflib/src/test/java/com/android/tools/perflib/heap/ClassObjTest.java b/perflib/src/test/java/com/android/tools/perflib/heap/ClassObjTest.java
index 883a9f6..f7fb759 100644
--- a/perflib/src/test/java/com/android/tools/perflib/heap/ClassObjTest.java
+++ b/perflib/src/test/java/com/android/tools/perflib/heap/ClassObjTest.java
@@ -15,6 +15,8 @@
*/
package com.android.tools.perflib.heap;
+import static com.google.common.truth.Truth.assertThat;
+
import com.android.testutils.TestResources;
import com.android.tools.perflib.captures.MemoryMappedFileBuffer;
import junit.framework.TestCase;
@@ -43,14 +45,14 @@
public void testGetAllFieldsCount() {
ClassObj application = mSnapshot.findClass("android.app.Application");
- assertNotNull(application);
- assertEquals(5, application.getAllFieldsCount());
+ assertThat(application).isNotNull();
+ assertThat(application.getAllFieldsCount()).isEqualTo(5);
- assertNull(application.getClassObj());
+ assertThat(application.getClassObj()).isNull();
ClassObj dialer = mSnapshot.findClass("com.android.dialer.DialerApplication");
- assertNotNull(dialer);
- assertEquals(5, dialer.getAllFieldsCount());
+ assertThat(dialer).isNotNull();
+ assertThat(dialer.getAllFieldsCount()).isEqualTo(5);
}
public void testComparison() {
@@ -59,10 +61,10 @@
ClassObj c = new ClassObj(2, null, "TestClassC", 0);
ClassObj aAlt = new ClassObj(3, null, "TestClassA", 0);
- assertEquals(0, a.compareTo(a));
- assertEquals(0, a.compareTo(b)); // This is a weird test case, since IDs are supposed to be unique.
- assertTrue(c.compareTo(a) > 0);
- assertTrue(aAlt.compareTo(a) > 0);
+ assertThat(a).isEquivalentAccordingToCompareTo(a);
+ assertThat(a).isEquivalentAccordingToCompareTo(b); // This is a weird test case, since IDs are supposed to be unique.
+ assertThat(c).isGreaterThan(a);
+ assertThat(aAlt).isGreaterThan(a);
}
public void testSubClassNameClash() {
@@ -72,8 +74,8 @@
superClass.addSubclass(subClass1);
superClass.addSubclass(subClass2);
- assertEquals(2, superClass.getSubclasses().size());
- assertTrue(superClass.getSubclasses().contains(subClass1));
- assertTrue(superClass.getSubclasses().contains(subClass2));
+ assertThat(superClass.getSubclasses().size()).isEqualTo(2);
+ assertThat(superClass.getSubclasses()).contains(subClass1);
+ assertThat(superClass.getSubclasses()).contains(subClass2);
}
}
diff --git a/pixelprobe/BUILD b/pixelprobe/BUILD
index 7b0883f..e15e9ae 100644
--- a/pixelprobe/BUILD
+++ b/pixelprobe/BUILD
@@ -2,17 +2,18 @@
iml_module(
name = "studio.pixelprobe",
+ # do not sort: must match IML order
srcs = [
"src/main/generated",
"src/main/java",
"src/test/tools",
],
- javacopts = ["-extra_checks:off"],
resources = ["src/main/resources"],
tags = ["managed"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/base/chunkio:studio.chunkio[module]",
"//tools/base/chunkio-processor:studio.chunkio-processor[module]",
diff --git a/profiler/BUILD b/profiler/BUILD
index 1ea5aa1..853d464 100644
--- a/profiler/BUILD
+++ b/profiler/BUILD
@@ -5,9 +5,9 @@
java_jarjar(
name = "studio-profiler-grpc-1.0-jarjar",
srcs = [
- "//tools/base/profiler/proto:libprofiler_java_proto.jar",
- "//prebuilts/tools/common/m2/repository/io/grpc/grpc-all/0.13.2:jar",
"//prebuilts/tools/common/m2/repository/com/google/protobuf/protobuf-java/3.0.0-beta-2:jar",
+ "//prebuilts/tools/common/m2/repository/io/grpc/grpc-all/0.13.2:jar",
+ "//tools/base/profiler/proto:libprofiler_java_proto.jar",
],
rules = "jarjar_rules.txt",
visibility = ["//visibility:public"],
diff --git a/profiler/grpc-java/build.gradle b/profiler/grpc-java/build.gradle
index 58d7a10..c6ea103 100644
--- a/profiler/grpc-java/build.gradle
+++ b/profiler/grpc-java/build.gradle
@@ -17,7 +17,17 @@
grpcVersion = '0.13.2'
}
+configurations {
+ packaging
+}
+
dependencies {
+ packaging("com.google.protobuf:protobuf-java:$protobufVersion") {
+ transitive false
+ }
+ packaging("io.grpc:grpc-all:$grpcVersion") {
+ transitive false
+ }
compile "com.google.protobuf:protobuf-java:$protobufVersion"
compile "io.grpc:grpc-all:$grpcVersion"
}
@@ -58,7 +68,7 @@
jarjar.repackage('jarjarLibs') {
destinationName = archivesBaseName + '-' + version + '-jarjar.jar'
- from configurations.compile
+ from configurations.packaging
from files(sourceSets.main.output.classesDir)
dependsOn sourceSets.main.output
classRename 'com.google.protobuf.**', 'com.google.protobuf3jarjar.@1'
diff --git a/profiler/native/perfa/BUILD b/profiler/native/perfa/BUILD
index a895635..927cfa9 100644
--- a/profiler/native/perfa/BUILD
+++ b/profiler/native/perfa/BUILD
@@ -1,25 +1,25 @@
cc_binary(
- name = "libperfa.so",
- linkshared = 1,
- srcs = [
- "agent_component.h",
- "perfa.cc",
- "perfa.h",
- "support/energy_passthrough.cc",
- "support/event_passthrough.cc",
- "support/http_tracker.cc",
- "support/jni_wrappers.h",
- "support/profiler_service.cc",
- "support/vm_stats_sampler.cc",
- ],
- deps = [
- "//prebuilts/studio/jdk:jni_headers",
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
- visibility = ["//visibility:public"],
+ name = "libperfa.so",
+ srcs = [
+ "agent_component.h",
+ "perfa.cc",
+ "perfa.h",
+ "support/energy_passthrough.cc",
+ "support/event_passthrough.cc",
+ "support/http_tracker.cc",
+ "support/jni_wrappers.h",
+ "support/profiler_service.cc",
+ "support/vm_stats_sampler.cc",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ linkshared = 1,
+ visibility = ["//visibility:public"],
+ deps = [
+ "//prebuilts/studio/jdk:jni_headers",
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
)
diff --git a/profiler/native/perfd/BUILD b/profiler/native/perfd/BUILD
index 2b9308b..0c69391 100644
--- a/profiler/native/perfd/BUILD
+++ b/profiler/native/perfd/BUILD
@@ -1,12 +1,12 @@
cc_library(
- name = "perfd_internal_headers",
- hdrs = [
- "daemon.h",
- "profiler_component.h",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
- visibility = ["//visibility:public"],
+ name = "perfd_internal_headers",
+ hdrs = [
+ "daemon.h",
+ "profiler_component.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ visibility = ["//visibility:public"],
)
diff --git a/profiler/native/perfd/cpu/BUILD b/profiler/native/perfd/cpu/BUILD
index de350c9..cac7090 100644
--- a/profiler/native/perfd/cpu/BUILD
+++ b/profiler/native/perfd/cpu/BUILD
@@ -1,30 +1,30 @@
cc_library(
- name = "profiler_cpu",
- srcs = [
- "cpu_cache.cc",
- "cpu_collector.cc",
- "cpu_service.cc",
- "cpu_usage_sampler.cc",
- "simpleperf_manager.cc",
- "thread_monitor.cc",
- ],
- hdrs = [
- "cpu_cache.h",
- "cpu_collector.h",
- "cpu_profiler_component.h",
- "cpu_service.h",
- "cpu_usage_sampler.h",
- "simpleperf_manager.h",
- "thread_monitor.h",
- ],
- deps = [
- "//tools/base/profiler/native/perfd:perfd_internal_headers",
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
- visibility = ["//visibility:public"]
-)
\ No newline at end of file
+ name = "profiler_cpu",
+ srcs = [
+ "cpu_cache.cc",
+ "cpu_collector.cc",
+ "cpu_service.cc",
+ "cpu_usage_sampler.cc",
+ "simpleperf_manager.cc",
+ "thread_monitor.cc",
+ ],
+ hdrs = [
+ "cpu_cache.h",
+ "cpu_collector.h",
+ "cpu_profiler_component.h",
+ "cpu_service.h",
+ "cpu_usage_sampler.h",
+ "simpleperf_manager.h",
+ "thread_monitor.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//tools/base/profiler/native/perfd:perfd_internal_headers",
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
+)
diff --git a/profiler/native/perfd/energy/BUILD b/profiler/native/perfd/energy/BUILD
index dbbd57d..ee2963b 100644
--- a/profiler/native/perfd/energy/BUILD
+++ b/profiler/native/perfd/energy/BUILD
@@ -1,42 +1,42 @@
cc_library(
- name = "profiler_energy",
- srcs = [
- "energy_cache.cc",
- "energy_collector.cc",
- "energy_service.cc",
- "energy_usage_sampler.cc",
- "internal_energy_service.cc",
- ],
- hdrs = [
- "energy_cache.h",
- "energy_collector.h",
- "energy_profiler_component.h",
- "energy_service.h",
- "energy_usage_sampler.h",
- "internal_energy_service.h",
- ],
- deps = [
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
+ name = "profiler_energy",
+ srcs = [
+ "energy_cache.cc",
+ "energy_collector.cc",
+ "energy_service.cc",
+ "energy_usage_sampler.cc",
+ "internal_energy_service.cc",
+ ],
+ hdrs = [
+ "energy_cache.h",
+ "energy_collector.h",
+ "energy_profiler_component.h",
+ "energy_service.h",
+ "energy_usage_sampler.h",
+ "internal_energy_service.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ deps = [
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
)
cc_test(
- name = "perfd_energy_tests",
- srcs = [
- "energy_cache_test.cc",
- "energy_usage_sampler_test.cc",
- ],
- deps = [
- ":profiler_energy",
- "//external:gmock_main"
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
-)
\ No newline at end of file
+ name = "perfd_energy_tests",
+ srcs = [
+ "energy_cache_test.cc",
+ "energy_usage_sampler_test.cc",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ deps = [
+ ":profiler_energy",
+ "//external:gmock_main",
+ ],
+)
diff --git a/profiler/native/perfd/event/BUILD b/profiler/native/perfd/event/BUILD
index 6732a9e..7bf4dd2 100644
--- a/profiler/native/perfd/event/BUILD
+++ b/profiler/native/perfd/event/BUILD
@@ -1,22 +1,22 @@
cc_library(
- name = "profiler_event",
- srcs = [
- "event_cache.cc",
- "event_service.cc",
- "internal_event_service.cc",
- ],
- hdrs = [
- "event_cache.h",
- "event_profiler_component.h",
- "event_service.h",
- "internal_event_service.h",
- ],
- deps = [
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
-)
\ No newline at end of file
+ name = "profiler_event",
+ srcs = [
+ "event_cache.cc",
+ "event_service.cc",
+ "internal_event_service.cc",
+ ],
+ hdrs = [
+ "event_cache.h",
+ "event_profiler_component.h",
+ "event_service.h",
+ "internal_event_service.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ deps = [
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
+)
diff --git a/profiler/native/perfd/memory/BUILD b/profiler/native/perfd/memory/BUILD
index 79fbca6..1e48bd0 100644
--- a/profiler/native/perfd/memory/BUILD
+++ b/profiler/native/perfd/memory/BUILD
@@ -1,47 +1,47 @@
package(default_visibility = ["//visibility:public"])
cc_library(
- name = "profiler_memory",
- srcs = [
- "internal_memory_service.cc",
- "memory_cache.cc",
- "memory_collector.cc",
- "memory_levels_sampler.cc",
- "memory_service.cc",
- ],
- hdrs = [
- "internal_memory_service.h",
- "memory_cache.h",
- "memory_collector.h",
- "memory_levels_sampler.h",
- "memory_profiler_component.h",
- "memory_service.h",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ],
- deps = [
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
+ name = "profiler_memory",
+ srcs = [
+ "internal_memory_service.cc",
+ "memory_cache.cc",
+ "memory_collector.cc",
+ "memory_levels_sampler.cc",
+ "memory_service.cc",
+ ],
+ hdrs = [
+ "internal_memory_service.h",
+ "memory_cache.h",
+ "memory_collector.h",
+ "memory_levels_sampler.h",
+ "memory_profiler_component.h",
+ "memory_service.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ deps = [
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
)
cc_test(
- name = "perfd_memory_tests",
- srcs = [
- "memory_levels_sampler_test.cc",
- ],
- data = [
- "//tools/base/profiler/native/testdata:perfd/memory",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler",
- ],
- deps = [
- ":profiler_memory",
- "//external:gmock_main",
- "//tools/base/profiler/native/test:testutils",
- ],
+ name = "perfd_memory_tests",
+ srcs = [
+ "memory_levels_sampler_test.cc",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ data = [
+ "//tools/base/profiler/native/testdata:perfd/memory",
+ ],
+ deps = [
+ ":profiler_memory",
+ "//external:gmock_main",
+ "//tools/base/profiler/native/test:testutils",
+ ],
)
diff --git a/profiler/native/perfd/network/BUILD b/profiler/native/perfd/network/BUILD
index 82b9215..a46a13a 100644
--- a/profiler/native/perfd/network/BUILD
+++ b/profiler/native/perfd/network/BUILD
@@ -1,56 +1,56 @@
package(default_visibility = ["//visibility:public"])
cc_library(
- name = "profiler_network",
- srcs = [
- "connection_sampler.cc",
- "connectivity_sampler.cc",
- "internal_network_service.cc",
- "network_cache.cc",
- "network_collector.cc",
- "network_service.cc",
- "traffic_sampler.cc",
- ],
- hdrs = [
- "connection_details.h",
- "connection_sampler.h",
- "connectivity_sampler.h",
- "internal_network_service.h",
- "network_cache.h",
- "network_collector.h",
- "network_constants.h",
- "network_profiler_component.h",
- "network_sampler.h",
- "network_service.h",
- "traffic_sampler.h",
- ],
- deps = [
- "//tools/base/profiler/native/utils:profiler_utils",
- "//tools/base/profiler/proto:profiler_cc_proto",
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler"
- ]
+ name = "profiler_network",
+ srcs = [
+ "connection_sampler.cc",
+ "connectivity_sampler.cc",
+ "internal_network_service.cc",
+ "network_cache.cc",
+ "network_collector.cc",
+ "network_service.cc",
+ "traffic_sampler.cc",
+ ],
+ hdrs = [
+ "connection_details.h",
+ "connection_sampler.h",
+ "connectivity_sampler.h",
+ "internal_network_service.h",
+ "network_cache.h",
+ "network_collector.h",
+ "network_constants.h",
+ "network_profiler_component.h",
+ "network_sampler.h",
+ "network_service.h",
+ "traffic_sampler.h",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ deps = [
+ "//tools/base/profiler/native/utils:profiler_utils",
+ "//tools/base/profiler/proto:profiler_cc_proto",
+ ],
)
cc_test(
- name = "perfd_network_tests",
- srcs = [
- "connection_sampler_test.cc",
- "connectivity_sampler_test.cc",
- "traffic_sampler_test.cc",
- ],
- data = [
- "//tools/base/profiler/native/testdata:perfd/network",
- ],
- deps = [
- ":profiler_network",
- "//external:gmock_main",
- "//tools/base/profiler/native/test:testutils"
- ],
- copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler",
- ]
-)
\ No newline at end of file
+ name = "perfd_network_tests",
+ srcs = [
+ "connection_sampler_test.cc",
+ "connectivity_sampler_test.cc",
+ "traffic_sampler_test.cc",
+ ],
+ copts = [
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
+ ],
+ data = [
+ "//tools/base/profiler/native/testdata:perfd/network",
+ ],
+ deps = [
+ ":profiler_network",
+ "//external:gmock_main",
+ "//tools/base/profiler/native/test:testutils",
+ ],
+)
diff --git a/profiler/native/perfd/network/traffic_sampler.cc b/profiler/native/perfd/network/traffic_sampler.cc
index 1f399d9..b6ecd89 100644
--- a/profiler/native/perfd/network/traffic_sampler.cc
+++ b/profiler/native/perfd/network/traffic_sampler.cc
@@ -33,8 +33,14 @@
Tokenizer t(line);
// Line, broken into tokens, with tokens we care about |highlighted|:
// idx iface acct_tag_hex |uid| cnt_set |rx_bytes| rx_packets |tx_bytes|
- std::string uid_str;
- if (t.EatTokens(3) && t.GetNextToken(&uid_str) && uid_str == uid_) {
+ // Currently, we are not only sampling the user's traffic but also the
+ // bytes sent between perfa <-> perfd, which to the user is noise. Here,
+ // we ignore the bytes sent on the loopback device to avoid counting such
+ // traffic. We agree as of right now that, users care about traffic from
+ // outside much more than inter-process traffic.
+ std::string str;
+ if (t.EatTokens(1) && t.GetNextToken(&str) && str != "lo" && t.EatTokens(1)
+ && t.GetNextToken(&str) && str == uid_) {
std::string rx_str;
std::string tx_str;
if (t.EatTokens(1) && t.GetNextToken(&rx_str) && t.EatTokens(1) &&
diff --git a/profiler/native/perfd/network/traffic_sampler_test.cc b/profiler/native/perfd/network/traffic_sampler_test.cc
index 1f6d53f..e3d0c70 100644
--- a/profiler/native/perfd/network/traffic_sampler_test.cc
+++ b/profiler/native/perfd/network/traffic_sampler_test.cc
@@ -54,3 +54,26 @@
EXPECT_EQ(0, data.traffic_data().bytes_received());
EXPECT_EQ(0, data.traffic_data().bytes_sent());
}
+
+TEST(GetTrafficData, OutputFiltersOutLoopbackTraffic) {
+ std::string file_name(
+ TestUtils::getNetworkTestData("traffic_filter_out_loopback_traffic.txt"));
+ TrafficSampler collector("12345", file_name);
+ profiler::proto::NetworkProfilerData data;
+ collector.GetData(&data);
+ EXPECT_TRUE(data.has_traffic_data());
+ EXPECT_EQ(0, data.traffic_data().bytes_received());
+ EXPECT_EQ(0, data.traffic_data().bytes_sent());
+}
+
+TEST(GetTrafficData, OutputFiltersOutLoopbackAndKeepNonLoopbackTraffic) {
+ std::string file_name(
+ TestUtils::getNetworkTestData(
+ "traffic_having_loopback_and_nonloopback_traffic.txt"));
+ TrafficSampler collector("12345", file_name);
+ profiler::proto::NetworkProfilerData data;
+ collector.GetData(&data);
+ EXPECT_TRUE(data.has_traffic_data());
+ EXPECT_EQ(2222, data.traffic_data().bytes_received());
+ EXPECT_EQ(3333, data.traffic_data().bytes_sent());
+}
diff --git a/profiler/native/test/BUILD b/profiler/native/test/BUILD
index c61c357..74352fc 100644
--- a/profiler/native/test/BUILD
+++ b/profiler/native/test/BUILD
@@ -1,12 +1,12 @@
cc_library(
name = "testutils",
srcs = glob([
- "**/*bazel.cc",
- "**/*.h",
+ "**/*bazel.cc",
+ "**/*.h",
]),
copts = [
- "-Itools/base/profiler/native",
- "-I$(GENDIR)/tools/base/profiler",
+ "-Itools/base/profiler/native",
+ "-I$(GENDIR)/tools/base/profiler",
],
visibility = ["//visibility:public"],
-)
\ No newline at end of file
+)
diff --git a/profiler/native/testdata/BUILD b/profiler/native/testdata/BUILD
index 37111b4..2723fae 100644
--- a/profiler/native/testdata/BUILD
+++ b/profiler/native/testdata/BUILD
@@ -13,4 +13,4 @@
filegroup(
name = "perfd/memory",
srcs = glob(["perfd/memory/**"]),
-)
\ No newline at end of file
+)
diff --git a/profiler/native/testdata/perfd/network/traffic_filter_out_loopback_traffic.txt b/profiler/native/testdata/perfd/network/traffic_filter_out_loopback_traffic.txt
new file mode 100644
index 0000000..9844e31
--- /dev/null
+++ b/profiler/native/testdata/perfd/network/traffic_filter_out_loopback_traffic.txt
@@ -0,0 +1,2 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 lo 0x0 12345 0 1111 5 2222 6 1100 3 11 2 0 0 2200 3 22 2 601948 8540
diff --git a/profiler/native/testdata/perfd/network/traffic_having_loopback_and_nonloopback_traffic.txt b/profiler/native/testdata/perfd/network/traffic_having_loopback_and_nonloopback_traffic.txt
new file mode 100644
index 0000000..2badab1
--- /dev/null
+++ b/profiler/native/testdata/perfd/network/traffic_having_loopback_and_nonloopback_traffic.txt
@@ -0,0 +1,3 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 lo 0x0 12345 0 1111 5 2222 6 1100 3 11 2 0 0 2200 3 22 2 601948 8540
+3 wlan0 0x0 12345 0 2222 5 3333 6 1100 3 11 2 0 0 2200 3 22 2 601948 8540
diff --git a/profiler/native/utils/BUILD b/profiler/native/utils/BUILD
index 953ab93..53807ab 100644
--- a/profiler/native/utils/BUILD
+++ b/profiler/native/utils/BUILD
@@ -95,4 +95,4 @@
"//external:gmock_main",
"//tools/base/profiler/native/test:testutils",
],
-)
\ No newline at end of file
+)
diff --git a/repository/BUILD b/repository/BUILD
index 19e6292..531b4df 100644
--- a/repository/BUILD
+++ b/repository/BUILD
@@ -3,11 +3,11 @@
iml_module(
name = "studio.repository",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools/base/annotations:studio.android-annotations[module]",
"//tools/idea/.idea/libraries:guava-tools",
@@ -15,6 +15,7 @@
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/idea/.idea/libraries:commons-compress",
"//tools/idea/.idea/libraries:jimfs",
+ "//tools/idea/.idea/libraries:truth[test]",
],
)
@@ -39,7 +40,6 @@
java_test(
name = "tools.tests",
srcs = glob(["src/test/java/**"]),
- javacopts = ["-extra_checks:off"],
jvm_flags = ["-Dtest.suite.jar=tools.tests.jar"],
resources = glob(["src/test/resources/**"]),
test_class = "com.android.testutils.JarTestSuite",
@@ -48,6 +48,7 @@
":tools.repository",
"//tools/base/annotations",
"//tools/base/third_party:com.google.guava_guava",
+ "//tools/base/third_party:com.google.truth_truth",
"//tools/base/third_party:junit_junit",
"//tools/base/third_party:org.apache.commons_commons-compress",
],
diff --git a/repository/build.gradle b/repository/build.gradle
index 07c51be..b5ef674 100644
--- a/repository/build.gradle
+++ b/repository/build.gradle
@@ -12,6 +12,7 @@
compile 'com.google.jimfs:jimfs:1.1'
testCompile 'junit:junit:4.12'
+ testCompile 'com.google.truth:truth:0.28'
}
test {
diff --git a/repository/repository.iml b/repository/repository.iml
index da0dcff..dd5a9a5 100644
--- a/repository/repository.iml
+++ b/repository/repository.iml
@@ -14,5 +14,6 @@
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="library" name="commons-compress" level="project" />
<orderEntry type="library" name="jimfs" level="project" />
+ <orderEntry type="library" scope="TEST" name="truth" level="project" />
</component>
-</module>
+</module>
\ No newline at end of file
diff --git a/repository/src/test/java/com/android/repository/RevisionTest.java b/repository/src/test/java/com/android/repository/RevisionTest.java
index 2e26d9b..3fb1ff2 100644
--- a/repository/src/test/java/com/android/repository/RevisionTest.java
+++ b/repository/src/test/java/com/android/repository/RevisionTest.java
@@ -16,159 +16,171 @@
package com.android.repository;
-import junit.framework.TestCase;
+import static com.google.common.truth.Truth.assertThat;
-import java.util.Arrays;
+import junit.framework.TestCase;
public class RevisionTest extends TestCase {
public final void testRevision() {
- assertEquals("5", Revision.parseRevision("5").toString());
- assertEquals("5.0", Revision.parseRevision("5.0").toString());
- assertEquals("5.0.0", Revision.parseRevision("5.0.0").toString());
- assertEquals("5.1.4", Revision.parseRevision("5.1.4").toString());
- assertEquals("5.0.0", Revision.parseRevision("5", Revision.Precision.MICRO).toString());
- assertEquals("5.1.0", Revision.parseRevision("5.1", Revision.Precision.MICRO).toString());
+ assertThat(Revision.parseRevision("5").toString()).isEqualTo("5");
+ assertThat(Revision.parseRevision("5.0").toString()).isEqualTo("5.0");
+ assertThat(Revision.parseRevision("5.0.0").toString()).isEqualTo("5.0.0");
+ assertThat(Revision.parseRevision("5.1.4").toString()).isEqualTo("5.1.4");
+ assertThat(Revision.parseRevision("5", Revision.Precision.MICRO).toString())
+ .isEqualTo("5.0.0");
+ assertThat(Revision.parseRevision("5.1", Revision.Precision.MICRO).toString())
+ .isEqualTo("5.1.0");
Revision p = new Revision(5);
- assertEquals(5, p.getMajor());
- assertEquals(Revision.IMPLICIT_MINOR_REV, p.getMinor());
- assertEquals(Revision.IMPLICIT_MICRO_REV, p.getMicro());
- assertEquals(Revision.NOT_A_PREVIEW, p.getPreview());
- assertFalse(p.isPreview());
- assertEquals("5", p.toShortString());
- assertEquals(p, Revision.parseRevision("5"));
- assertEquals("5", p.toString());
- assertEquals(p, Revision.parseRevision("5"));
- assertEquals("[5]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[5]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(5);
+ assertThat(p.getMinor()).isEqualTo(Revision.IMPLICIT_MINOR_REV);
+ assertThat(p.getMicro()).isEqualTo(Revision.IMPLICIT_MICRO_REV);
+ assertThat(p.getPreview()).isEqualTo(Revision.NOT_A_PREVIEW);
+ assertThat(p.isPreview()).isFalse();
+ assertThat(p.toShortString()).isEqualTo("5");
+ assertThat(Revision.parseRevision("5")).isEqualTo(p);
+ assertThat(p.toString()).isEqualTo("5");
+ assertThat(Revision.parseRevision("5")).isEqualTo(p);
+ assertThat(p.toIntArray(false /*includePreview*/)).asList().containsExactly(5);
+ assertThat(p.toIntArray(true /*includePreview*/)).asList().containsExactly(5);
p = new Revision(5, 0);
- assertEquals(5, p.getMajor());
- assertEquals(0, p.getMinor());
- assertEquals(Revision.IMPLICIT_MICRO_REV, p.getMicro());
- assertEquals(Revision.NOT_A_PREVIEW, p.getPreview());
- assertFalse(p.isPreview());
- assertEquals("5", p.toShortString());
- assertEquals(new Revision(5), Revision.parseRevision("5"));
- assertEquals("5.0", p.toString());
- assertEquals(p, Revision.parseRevision("5.0"));
- assertEquals("[5, 0]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[5, 0]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(5);
+ assertThat(p.getMinor()).isEqualTo(0);
+ assertThat(p.getMicro()).isEqualTo(Revision.IMPLICIT_MICRO_REV);
+ assertThat(p.getPreview()).isEqualTo(Revision.NOT_A_PREVIEW);
+ assertThat(p.isPreview()).isFalse();
+ assertThat(p.toShortString()).isEqualTo("5");
+ assertThat(Revision.parseRevision("5")).isEqualTo(new Revision(5));
+ assertThat(p.toString()).isEqualTo("5.0");
+ assertThat(Revision.parseRevision("5.0")).isEqualTo(p);
+ assertThat(p.toIntArray(false /*includePreview*/)).asList().containsExactly(5, 0).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList().containsExactly(5, 0).inOrder();
p = new Revision(5, 0, 0);
- assertEquals(5, p.getMajor());
- assertEquals(0, p.getMinor());
- assertEquals(0, p.getMicro());
- assertEquals(Revision.NOT_A_PREVIEW, p.getPreview());
- assertFalse(p.isPreview());
- assertEquals("5", p.toShortString());
- assertEquals(new Revision(5), Revision.parseRevision("5"));
- assertEquals("5.0.0", p.toString());
- assertEquals(p, Revision.parseRevision("5.0.0"));
- assertEquals("[5, 0, 0]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[5, 0, 0]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(5);
+ assertThat(p.getMinor()).isEqualTo(0);
+ assertThat(p.getMicro()).isEqualTo(0);
+ assertThat(p.getPreview()).isEqualTo(Revision.NOT_A_PREVIEW);
+ assertThat(p.isPreview()).isFalse();
+ assertThat(p.toShortString()).isEqualTo("5");
+ assertThat(Revision.parseRevision("5")).isEqualTo(new Revision(5));
+ assertThat(p.toString()).isEqualTo("5.0.0");
+ assertThat(Revision.parseRevision("5.0.0")).isEqualTo(p);
+ assertThat(p.toIntArray(false /*includePreview*/)).asList()
+ .containsExactly(5, 0, 0).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList()
+ .containsExactly(5, 0, 0).inOrder();
p = new Revision(5, 0, 0, 6);
- assertEquals(5, p.getMajor());
- assertEquals(Revision.IMPLICIT_MINOR_REV, p.getMinor());
- assertEquals(Revision.IMPLICIT_MICRO_REV, p.getMicro());
- assertEquals(6, p.getPreview());
- assertTrue(p.isPreview());
- assertEquals("5 rc6", p.toShortString());
- assertEquals("5.0.0 rc6", p.toString());
- assertEquals(p, Revision.parseRevision("5.0.0 rc6"));
- assertEquals("5.0.0-rc6", Revision.parseRevision("5.0.0-rc6").toString());
- assertEquals("[5, 0, 0]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[5, 0, 0, 6]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(5);
+ assertThat(p.getMinor()).isEqualTo(Revision.IMPLICIT_MINOR_REV);
+ assertThat(p.getMicro()).isEqualTo(Revision.IMPLICIT_MICRO_REV);
+ assertThat(p.getPreview()).isEqualTo(6);
+ assertThat(p.isPreview()).isTrue();
+ assertThat(p.toShortString()).isEqualTo("5 rc6");
+ assertThat(p.toString()).isEqualTo("5.0.0 rc6");
+ assertThat(Revision.parseRevision("5.0.0 rc6")).isEqualTo(p);
+ assertThat(Revision.parseRevision("5.0.0-rc6").toString()).isEqualTo("5.0.0-rc6");
+ assertThat(p.toIntArray(false /*includePreview*/)).asList()
+ .containsExactly(5, 0, 0).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList()
+ .containsExactly(5, 0, 0, 6).inOrder();
p = new Revision(6, 7, 0);
- assertEquals(6, p.getMajor());
- assertEquals(7, p.getMinor());
- assertEquals(0, p.getMicro());
- assertEquals(0, p.getPreview());
- assertFalse(p.isPreview());
- assertEquals("6.7", p.toShortString());
- assertFalse(p.equals(Revision.parseRevision("6.7")));
- assertEquals(new Revision(6, 7), Revision.parseRevision("6.7"));
- assertEquals("6.7.0", p.toString());
- assertEquals(p, Revision.parseRevision("6.7.0"));
- assertEquals("[6, 7, 0]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[6, 7, 0]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(6);
+ assertThat(p.getMinor()).isEqualTo(7);
+ assertThat(p.getMicro()).isEqualTo(0);
+ assertThat(p.getPreview()).isEqualTo(0);
+ assertThat(p.isPreview()).isFalse();
+ assertThat(p.toShortString()).isEqualTo("6.7");
+ assertThat(p).isNotEqualTo(Revision.parseRevision("6.7"));
+ assertThat(Revision.parseRevision("6.7")).isEqualTo(new Revision(6, 7));
+ assertThat(p.toString()).isEqualTo("6.7.0");
+ assertThat(Revision.parseRevision("6.7.0")).isEqualTo(p);
+ assertThat(p.toIntArray(false /*includePreview*/)).asList()
+ .containsExactly(6, 7, 0).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList()
+ .containsExactly(6, 7, 0).inOrder();
p = new Revision(10, 11, 12, Revision.NOT_A_PREVIEW);
- assertEquals(10, p.getMajor());
- assertEquals(11, p.getMinor());
- assertEquals(12, p.getMicro());
- assertEquals(0, p.getPreview());
- assertFalse(p.isPreview());
- assertEquals("10.11.12", p.toShortString());
- assertEquals("10.11.12", p.toString());
- assertEquals("[10, 11, 12]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[10, 11, 12, 0]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(10);
+ assertThat(p.getMinor()).isEqualTo(11);
+ assertThat(p.getMicro()).isEqualTo(12);
+ assertThat(p.getPreview()).isEqualTo(0);
+ assertThat(p.isPreview()).isFalse();
+ assertThat(p.toShortString()).isEqualTo("10.11.12");
+ assertThat(p.toString()).isEqualTo("10.11.12");
+ assertThat(p.toIntArray(false /*includePreview*/)).asList()
+ .containsExactly(10, 11, 12).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList()
+ .containsExactly(10, 11, 12, 0).inOrder();
p = new Revision(10, 11, 12, 13);
- assertEquals(10, p.getMajor());
- assertEquals(11, p.getMinor());
- assertEquals(12, p.getMicro());
- assertEquals(13, p.getPreview());
- assertTrue (p.isPreview());
- assertEquals("10.11.12 rc13", p.toShortString());
- assertEquals("10.11.12 rc13", p.toString());
- assertEquals(p, Revision.parseRevision("10.11.12 rc13"));
- assertEquals(p, Revision.parseRevision(" 10.11.12 rc13"));
- assertEquals(p, Revision.parseRevision("10.11.12 rc13 "));
- assertEquals(p, Revision.parseRevision(" 10.11.12 rc13 "));
- assertEquals("[10, 11, 12]", Arrays.toString(p.toIntArray(false /*includePreview*/)));
- assertEquals("[10, 11, 12, 13]", Arrays.toString(p.toIntArray(true /*includePreview*/)));
+ assertThat(p.getMajor()).isEqualTo(10);
+ assertThat(p.getMinor()).isEqualTo(11);
+ assertThat(p.getMicro()).isEqualTo(12);
+ assertThat(p.getPreview()).isEqualTo(13);
+ assertThat(p.isPreview()).isTrue();
+ assertThat(p.toShortString()).isEqualTo("10.11.12 rc13");
+ assertThat(p.toString()).isEqualTo("10.11.12 rc13");
+ assertThat(Revision.parseRevision("10.11.12 rc13")).isEqualTo(p);
+ assertThat(Revision.parseRevision(" 10.11.12 rc13")).isEqualTo(p);
+ assertThat(Revision.parseRevision("10.11.12 rc13 ")).isEqualTo(p);
+ assertThat(Revision.parseRevision(" 10.11.12 rc13 ")).isEqualTo(p);
+ assertThat(p.toIntArray(false /*includePreview*/)).asList()
+ .containsExactly(10, 11, 12).inOrder();
+ assertThat(p.toIntArray(true /*includePreview*/)).asList()
+ .containsExactly(10, 11, 12, 13).inOrder();
}
public final void testParse() {
Revision revision = Revision.parseRevision("1");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 0);
- assertEquals(revision.getMicro(), 0);
- assertFalse(revision.isPreview());
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(0);
+ assertThat(revision.getMicro()).isEqualTo(0);
+ assertThat(revision.isPreview()).isFalse();
revision = Revision.parseRevision("1.2");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 2);
- assertEquals(revision.getMicro(), 0);
- assertFalse(revision.isPreview());
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(2);
+ assertThat(revision.getMicro()).isEqualTo(0);
+ assertThat(revision.isPreview()).isFalse();
revision = Revision.parseRevision("1.2.3");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 2);
- assertEquals(revision.getMicro(), 3);
- assertFalse(revision.isPreview());
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(2);
+ assertThat(revision.getMicro()).isEqualTo(3);
+ assertThat(revision.isPreview()).isFalse();
revision = Revision.parseRevision("1.2.3-rc4");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 2);
- assertEquals(revision.getMicro(), 3);
- assertTrue(revision.isPreview());
- assertEquals(revision.getPreview(), 4);
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(2);
+ assertThat(revision.getMicro()).isEqualTo(3);
+ assertThat(revision.isPreview()).isTrue();
+ assertThat(revision.getPreview()).isEqualTo(4);
revision = Revision.parseRevision("1.2.3-alpha5");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 2);
- assertEquals(revision.getMicro(), 3);
- assertTrue(revision.isPreview());
- assertEquals(revision.getPreview(), 5);
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(2);
+ assertThat(revision.getMicro()).isEqualTo(3);
+ assertThat(revision.isPreview()).isTrue();
+ assertThat(revision.getPreview()).isEqualTo(5);
revision = Revision.parseRevision("1.2.3-beta6");
- assertNotNull(revision);
- assertEquals(revision.getMajor(), 1);
- assertEquals(revision.getMinor(), 2);
- assertEquals(revision.getMicro(), 3);
- assertTrue(revision.isPreview());
- assertEquals(revision.getPreview(), 6);
+ assertThat(revision).isNotNull();
+ assertThat(revision.getMajor()).isEqualTo(1);
+ assertThat(revision.getMinor()).isEqualTo(2);
+ assertThat(revision.getMicro()).isEqualTo(3);
+ assertThat(revision.isPreview()).isTrue();
+ assertThat(revision.getPreview()).isEqualTo(6);
try {
Revision.parseRevision("1.2.3-preview");
@@ -176,7 +188,7 @@
} catch (NumberFormatException ignored) {}
revision = Revision.safeParseRevision("1.2.3-preview");
- assertEquals(revision, Revision.NOT_SPECIFIED);
+ assertThat(Revision.NOT_SPECIFIED).isEqualTo(revision);
}
public final void testParseError() {
@@ -187,7 +199,7 @@
} catch (NumberFormatException e) {
errorMsg = e.getMessage();
}
- assertEquals("Invalid revision: not a number", errorMsg);
+ assertThat(errorMsg).isEqualTo("Invalid revision: not a number");
errorMsg = null;
try {
@@ -196,7 +208,7 @@
} catch (NumberFormatException e) {
errorMsg = e.getMessage();
}
- assertEquals("Invalid revision: 5 .6 .7", errorMsg);
+ assertThat(errorMsg).isEqualTo("Invalid revision: 5 .6 .7");
errorMsg = null;
try {
@@ -205,7 +217,7 @@
} catch (NumberFormatException e) {
errorMsg = e.getMessage();
}
- assertEquals("Invalid revision: 5.0.0 preview 1", errorMsg);
+ assertThat(errorMsg).isEqualTo("Invalid revision: 5.0.0 preview 1");
errorMsg = null;
try {
@@ -214,7 +226,7 @@
} catch (NumberFormatException e) {
errorMsg = e.getMessage();
}
- assertEquals("Invalid revision: 5.1.2 rc 42 ", errorMsg);
+ assertThat(errorMsg).isEqualTo("Invalid revision: 5.1.2 rc 42 ");
}
public final void testCompareTo() {
@@ -226,21 +238,21 @@
Revision o5 = new Revision(5, 0, 0, 7);
Revision p5 = new Revision(5, 1, 0, 0);
- assertEquals(s4, i4); // 4.0.0-0 == 4.0.0-0
- assertEquals(g5, c5); // 5.1.0-6 == 5.1.0-6
+ assertThat(i4).isEqualTo(s4); // 4.0.0-0 == 4.0.0-0
+ assertThat(c5).isEqualTo(g5); // 5.1.0-6 == 5.1.0-6
- assertFalse(y5.equals(p5)); // 5.0.0-0 != 5.1.0-0
- assertFalse(g5.equals(p5)); // 5.1.0-6 != 5.1.0-0
- assertTrue (s4.compareTo(i4) == 0); // 4.0.0-0 == 4.0.0-0
- assertTrue (s4.compareTo(y5) < 0); // 4.0.0-0 < 5.0.0-0
- assertTrue (y5.compareTo(y5) == 0); // 5.0.0-0 == 5.0.0-0
- assertTrue (y5.compareTo(p5) < 0); // 5.0.0-0 < 5.1.0-0
- assertTrue (o5.compareTo(y5) < 0); // 5.0.0-7 < 5.0.0-0
- assertTrue (p5.compareTo(p5) == 0); // 5.1.0-0 == 5.1.0-0
- assertTrue (c5.compareTo(p5) < 0); // 5.1.0-6 < 5.1.0-0
- assertTrue (p5.compareTo(c5) > 0); // 5.1.0-0 > 5.1.0-6
- assertTrue (p5.compareTo(o5) > 0); // 5.1.0-0 > 5.0.0-7
- assertTrue (c5.compareTo(o5) > 0); // 5.1.0-6 > 5.0.0-7
- assertTrue (o5.compareTo(o5) == 0); // 5.0.0-7 > 5.0.0-7
+ assertThat(y5).isNotEqualTo(p5); // 5.0.0-0 != 5.1.0-0
+ assertThat(g5).isNotEqualTo(p5); // 5.1.0-6 != 5.1.0-0
+ assertThat(s4).isEquivalentAccordingToCompareTo(i4); // 4.0.0-0 == 4.0.0-0
+ assertThat(s4).isLessThan(y5); // 4.0.0-0 < 5.0.0-0
+ assertThat(y5).isEquivalentAccordingToCompareTo(y5); // 5.0.0-0 == 5.0.0-0
+ assertThat(y5).isLessThan(p5); // 5.0.0-0 < 5.1.0-0
+ assertThat(o5).isLessThan(y5); // 5.0.0-7 < 5.0.0-0
+ assertThat(p5).isEquivalentAccordingToCompareTo(p5); // 5.1.0-0 == 5.1.0-0
+ assertThat(c5).isLessThan(p5); // 5.1.0-6 < 5.1.0-0
+ assertThat(p5).isGreaterThan(c5); // 5.1.0-0 > 5.1.0-6
+ assertThat(p5).isGreaterThan(o5); // 5.1.0-0 > 5.0.0-7
+ assertThat(c5).isGreaterThan(o5); // 5.1.0-6 > 5.0.0-7
+ assertThat(o5).isEquivalentAccordingToCompareTo(o5); // 5.0.0-7 > 5.0.0-7
}
}
\ No newline at end of file
diff --git a/rpclib/BUILD b/rpclib/BUILD
index a5ab029..f808b1d 100644
--- a/rpclib/BUILD
+++ b/rpclib/BUILD
@@ -3,9 +3,9 @@
iml_module(
name = "studio.rpclib",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
deps = [
"//tools:idea.annotations[module]",
"//tools:idea.util[module]",
diff --git a/rpclib/src/main/java/com/android/tools/rpclib/rpccore/ErrInvalidHeader.java b/rpclib/src/main/java/com/android/tools/rpclib/rpccore/ErrInvalidHeader.java
index 9fb92a8..59833ea 100644
--- a/rpclib/src/main/java/com/android/tools/rpclib/rpccore/ErrInvalidHeader.java
+++ b/rpclib/src/main/java/com/android/tools/rpclib/rpccore/ErrInvalidHeader.java
@@ -23,6 +23,7 @@
import com.android.tools.rpclib.schema.*;
import java.io.IOException;
+import java.util.Arrays;
public final class ErrInvalidHeader extends RpcException implements BinaryObject {
//<<<Start:Java.ClassBody:1>>>
@@ -58,7 +59,7 @@
@Override
public String getMessage() {
- return "Invalid RPC header: " + mHeader;
+ return "Invalid RPC header: " + Arrays.toString(mHeader);
}
public enum Klass implements BinaryClass {
diff --git a/sdk-common/BUILD b/sdk-common/BUILD
index 0720c98..2e39d45 100644
--- a/sdk-common/BUILD
+++ b/sdk-common/BUILD
@@ -3,27 +3,28 @@
iml_module(
name = "studio.sdk-common",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/base/layoutlib-api:studio.layoutlib-api",
+ "//tools/base/build-system/builder-model:studio.builder-model",
"//tools/base/common:studio.common",
"//tools/base/sdklib:studio.sdklib",
"//tools/idea/.idea/libraries:kxml2",
- "//tools/idea/.idea/libraries:builder-model",
"//tools/idea/.idea/libraries:gson",
],
+ # do not sort: must match IML order
deps = [
"//tools/base/layoutlib-api:studio.layoutlib-api[module]",
+ "//tools/base/build-system/builder-model:studio.builder-model[module]",
"//tools/base/common:studio.common[module]",
"//tools/base/sdklib:studio.sdklib[module]",
"//tools/idea/.idea/libraries:kxml2",
"//tools/idea/.idea/libraries:JUnit4[test]",
"//tools/base/testutils:studio.testutils[module, test]",
- "//tools/idea/.idea/libraries:builder-model",
"//tools/idea/.idea/libraries:mockito[test]",
"//tools/idea/.idea/libraries:gson",
"//tools/base/build-system:studio.builder-test-api[module]",
@@ -36,12 +37,11 @@
java_library(
name = "tools.sdk-common",
srcs = glob(["src/main/java/**"]),
- javacopts = ["-extra_checks:off"],
visibility = ["//visibility:public"],
deps = [
"//tools/base/annotations",
- "//tools/base/build-system/builder-model",
"//tools/base/build-system:tools.builder-test-api",
+ "//tools/base/build-system/builder-model",
"//tools/base/common:tools.common",
"//tools/base/layoutlib-api:tools.layoutlib-api",
"//tools/base/repository:tools.repository",
@@ -64,8 +64,8 @@
deps = [
":tools.sdk-common",
"//tools/base/annotations",
- "//tools/base/build-system/builder-model",
"//tools/base/build-system:tools.builder-test-api",
+ "//tools/base/build-system/builder-model",
"//tools/base/common:tools.common",
"//tools/base/layoutlib-api:tools.layoutlib-api",
"//tools/base/repository:tools.repository",
diff --git a/sdk-common/sdk-common.iml b/sdk-common/sdk-common.iml
index c1e8e94..288a0bf 100644
--- a/sdk-common/sdk-common.iml
+++ b/sdk-common/sdk-common.iml
@@ -12,12 +12,12 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" />
<orderEntry type="module" module-name="layoutlib-api" exported="" />
+ <orderEntry type="module" module-name="builder-model" exported="" />
<orderEntry type="module" module-name="common" exported="" />
<orderEntry type="module" module-name="sdklib" exported="" />
<orderEntry type="library" exported="" name="kxml2" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testutils" scope="TEST" />
- <orderEntry type="library" exported="" name="builder-model" level="project" />
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
<orderEntry type="library" exported="" name="gson" level="project" />
<orderEntry type="module" module-name="builder-test-api" />
diff --git a/sdk-common/src/main/java/com/android/ide/common/res2/DataSet.java b/sdk-common/src/main/java/com/android/ide/common/res2/DataSet.java
index 2ffa1b3..c455bd7 100644
--- a/sdk-common/src/main/java/com/android/ide/common/res2/DataSet.java
+++ b/sdk-common/src/main/java/com/android/ide/common/res2/DataSet.java
@@ -20,7 +20,7 @@
import com.android.annotations.Nullable;
import com.android.ide.common.blame.Message;
import com.android.utils.ILogger;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
@@ -571,7 +571,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(getClass())
+ return MoreObjects.toStringHelper(getClass())
.addValue(mConfigName)
.add("sources", Arrays.toString(mSourceFiles.toArray()))
.toString();
diff --git a/sdk-common/src/main/java/com/android/ide/common/res2/ResourceFile.java b/sdk-common/src/main/java/com/android/ide/common/res2/ResourceFile.java
index c655b36..06b6b51 100644
--- a/sdk-common/src/main/java/com/android/ide/common/res2/ResourceFile.java
+++ b/sdk-common/src/main/java/com/android/ide/common/res2/ResourceFile.java
@@ -20,7 +20,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.VisibleForTesting;
import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -142,7 +142,7 @@
@Override
public String toString() {
- return Objects.toStringHelper(getClass())
+ return MoreObjects.toStringHelper(getClass())
.add("mFile", mFile)
.add("mQualifiers", mQualifiers)
.toString();
diff --git a/sdk-common/src/main/java/com/android/ide/common/vectordrawable/VdPath.java b/sdk-common/src/main/java/com/android/ide/common/vectordrawable/VdPath.java
index d03ef92..39a32f4 100644
--- a/sdk-common/src/main/java/com/android/ide/common/vectordrawable/VdPath.java
+++ b/sdk-common/src/main/java/com/android/ide/common/vectordrawable/VdPath.java
@@ -590,7 +590,7 @@
//noinspection ImplicitArrayToString
return "Path:" +
" Name: " + mName +
- " Node: " + mNodeList.toString() +
+ " Node: " + Arrays.toString(mNodeList) +
" mFillColor: " + Integer.toHexString(mFillColor) +
" mFillAlpha:" + mFillAlpha +
" mFillType:" + mFillType +
diff --git a/sdk-common/src/test/java/com/android/ide/common/rendering/HardwareConfigHelperTest.java b/sdk-common/src/test/java/com/android/ide/common/rendering/HardwareConfigHelperTest.java
index 627f53d..40e749d 100644
--- a/sdk-common/src/test/java/com/android/ide/common/rendering/HardwareConfigHelperTest.java
+++ b/sdk-common/src/test/java/com/android/ide/common/rendering/HardwareConfigHelperTest.java
@@ -11,6 +11,7 @@
import static com.android.ide.common.rendering.HardwareConfigHelper.nexusRank;
import static com.android.ide.common.rendering.HardwareConfigHelper.sortNexusListByRank;
+import com.android.repository.testframework.MockFileOp;
import com.android.sdklib.devices.Device;
import com.android.sdklib.devices.DeviceManager;
import com.android.utils.StdLogger;
@@ -24,7 +25,8 @@
public class HardwareConfigHelperTest extends TestCase {
private static DeviceManager getDeviceManager() {
- return DeviceManager.createInstance(null, new StdLogger(StdLogger.Level.INFO));
+ return DeviceManager.createInstance(
+ null, null, new StdLogger(StdLogger.Level.INFO), new MockFileOp());
}
public void testNexus() {
diff --git a/sdk-common/src/test/java/com/android/ide/common/repository/SdkMavenRepositoryTest.java b/sdk-common/src/test/java/com/android/ide/common/repository/SdkMavenRepositoryTest.java
index 5a07b79..919c8b5 100644
--- a/sdk-common/src/test/java/com/android/ide/common/repository/SdkMavenRepositoryTest.java
+++ b/sdk-common/src/test/java/com/android/ide/common/repository/SdkMavenRepositoryTest.java
@@ -17,7 +17,6 @@
package com.android.ide.common.repository;
import com.android.annotations.NonNull;
-import com.android.repository.Revision;
import com.android.repository.api.LocalPackage;
import com.android.repository.api.ProgressIndicator;
import com.android.repository.api.RepoPackage;
@@ -29,11 +28,13 @@
import com.android.sdklib.repository.AndroidSdkHandler;
import com.android.sdklib.repository.meta.DetailsTypes;
import com.google.common.collect.ImmutableList;
+
+import junit.framework.TestCase;
+
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
public class SdkMavenRepositoryTest extends TestCase {
private static final File SDK_HOME = new File("/sdk");
@@ -46,8 +47,12 @@
protected void setUp() throws Exception {
super.setUp();
mFileOp = new MockFileOp();
- mSdkHandler = new AndroidSdkHandler(SDK_HOME, mFileOp,
- new FakeRepoManager(SDK_HOME, mRepositoryPackages));
+ mSdkHandler =
+ new AndroidSdkHandler(
+ SDK_HOME,
+ null,
+ mFileOp,
+ new FakeRepoManager(SDK_HOME, mRepositoryPackages));
}
private void registerRepo(@NonNull String vendor) {
@@ -203,4 +208,4 @@
pattern = new GradleCoordinate("group", "artifact", 2, 1, 3);
assertNull(SdkMavenRepository.findBestPackageMatching(pattern, packages));
}
-}
\ No newline at end of file
+}
diff --git a/sdklib/BUILD b/sdklib/BUILD
index 5c8c3aa..30eb103 100644
--- a/sdklib/BUILD
+++ b/sdklib/BUILD
@@ -3,11 +3,11 @@
iml_module(
name = "studio.sdklib",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_resources = ["src/test/resources"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
+ # do not sort: must match IML order
exports = [
"//tools/base/common:studio.common",
"//tools/base/device_validator:studio.dvlib",
@@ -17,6 +17,7 @@
"//tools/idea/.idea/libraries:gson",
"//tools/base/repository:studio.repository",
],
+ # do not sort: must match IML order
deps = [
"//tools/base/common:studio.common[module]",
"//tools/base/device_validator:studio.dvlib[module]",
@@ -35,7 +36,6 @@
name = "tools.sdklib",
# TODO: Why are the xml files not under resources?
srcs = glob(["src/main/java/**/*.java"]),
- javacopts = ["-extra_checks:off"],
resources = glob(
include = ["src/main/java/**"],
exclude = ["src/main/java/**/*.java"],
diff --git a/sdklib/build.gradle b/sdklib/build.gradle
index 97d19a6..088a903 100755
--- a/sdklib/build.gradle
+++ b/sdklib/build.gradle
@@ -112,6 +112,7 @@
'--channel=3',
'tools',
'platform-tools',
+ 'build-tools;25.0.0',
'build-tools;24.0.3',
'build-tools;24.0.2',
'build-tools;24.0.1',
@@ -127,6 +128,7 @@
'build-tools;21.0.0',
'build-tools;20.0.0',
'build-tools;19.1.0',
+ 'platforms;android-25',
'platforms;android-24',
'platforms;android-23',
'platforms;android-22',
@@ -143,8 +145,8 @@
'extras;android;m2repository',
'cmake;3.6.3155560',
'ndk-bundle',
- 'extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha9',
- 'extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha9',
+ 'extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta1',
+ 'extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta1',
"system-images;android-19;default;x86",
"system-images;android-23;default;x86",
"extras;android;gapid;3"]
@@ -152,8 +154,8 @@
}
}
-def offline_repo_files = ["extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-alpha9",
- "extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-alpha9"]
+def offline_repo_files = ["extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta1",
+ "extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.0-beta1"]
def offline_sdk_targets = [["macosx", "64", "darwin-x86_64"],
["macosx", "32", "darwin-x86"],
["windows", "64", "windows-x86_64"],
diff --git a/sdklib/src/main/java/com/android/sdklib/BuildToolInfo.java b/sdklib/src/main/java/com/android/sdklib/BuildToolInfo.java
old mode 100755
new mode 100644
index e966885..6c1608e
--- a/sdklib/src/main/java/com/android/sdklib/BuildToolInfo.java
+++ b/sdklib/src/main/java/com/android/sdklib/BuildToolInfo.java
@@ -70,7 +70,7 @@
import com.android.repository.Revision;
import com.android.repository.api.LocalPackage;
import com.android.utils.ILogger;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;
import com.google.common.collect.Range;
@@ -440,11 +440,6 @@
return true;
}
- /** If this build tools supports Jack. */
- public boolean supportsJack() {
- return getRevision().compareTo(JackVersion.V4.getMinRevision()) >= 0;
- }
-
/** Gets the supported Jack API version. This throws exception if no API is supported. */
@NonNull
public JackVersion getSupportedJackApi() {
@@ -477,7 +472,7 @@
*/
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("rev", mRevision)
.add("mPath", mPath)
.add("mPaths", getPathString())
diff --git a/sdklib/src/main/java/com/android/sdklib/SdkVersionInfo.java b/sdklib/src/main/java/com/android/sdklib/SdkVersionInfo.java
index 7cdbd7c..ca28c08 100644
--- a/sdklib/src/main/java/com/android/sdklib/SdkVersionInfo.java
+++ b/sdklib/src/main/java/com/android/sdklib/SdkVersionInfo.java
@@ -29,12 +29,12 @@
* release. This number is used as a baseline and any more recent platforms
* found can be used to increase the highest known number.
*/
- public static final int HIGHEST_KNOWN_API = 24;
+ public static final int HIGHEST_KNOWN_API = 25;
/**
* Like {@link #HIGHEST_KNOWN_API} but does not include preview platforms
*/
- public static final int HIGHEST_KNOWN_STABLE_API = 24;
+ public static final int HIGHEST_KNOWN_STABLE_API = 25;
/**
* The lowest active API level in the ecosystem. This number will change over time
@@ -123,6 +123,7 @@
case 22: return "5.1";
case 23: return "6.0";
case 24: return "7.0";
+ case 25: return "7.1.1";
// If you add more versions here, also update #getBuildCodes and
// #HIGHEST_KNOWN_API
@@ -170,6 +171,7 @@
case 23:
return "Marshmallow";
case 24:
+ case 25:
return "Nougat";
// If you add more versions here, also update #getBuildCodes and
@@ -216,6 +218,7 @@
case 22: return "LOLLIPOP_MR1"; //$NON-NLS-1$
case 23: return "M"; //$NON-NLS-1$
case 24: return "N"; //$NON-NLS-1$
+ case 25: return "N_MR1"; //$NON-NLS-1$
// If you add more versions here, also update #getAndroidName and
// #HIGHEST_KNOWN_API
}
diff --git a/sdklib/src/main/java/com/android/sdklib/devices/DeviceManager.java b/sdklib/src/main/java/com/android/sdklib/devices/DeviceManager.java
index ee5a4cd..fdad33d 100644
--- a/sdklib/src/main/java/com/android/sdklib/devices/DeviceManager.java
+++ b/sdklib/src/main/java/com/android/sdklib/devices/DeviceManager.java
@@ -20,14 +20,13 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.repository.io.FileOp;
import com.android.repository.io.FileOpUtils;
import com.android.resources.Keyboard;
import com.android.resources.KeyboardState;
import com.android.resources.Navigation;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.avd.HardwareProperties;
-import com.android.repository.io.FileOp;
import com.android.sdklib.repository.PkgProps;
import com.android.utils.ILogger;
import com.google.common.base.Charsets;
@@ -70,14 +69,18 @@
private static final String DEVICE_PROFILES_PROP = "DeviceProfiles";
private static final Pattern PATH_PROPERTY_PATTERN =
Pattern.compile('^' + PkgProps.EXTRA_PATH + '=' + DEVICE_PROFILES_PROP + '$');
+ @Nullable
+ private final File mAndroidFolder;
private ILogger mLog;
+ @NonNull
+ private final FileOp mFop;
private Table<String, String, Device> mVendorDevices;
private Table<String, String, Device> mSysImgDevices;
private Table<String, String, Device> mUserDevices;
private Table<String, String, Device> mDefaultDevices;
private final Object mLock = new Object();
private final List<DevicesChangedListener> sListeners = new ArrayList<DevicesChangedListener>();
- private final String mOsSdkPath;
+ private final File mOsSdkPath;
public enum DeviceFilter {
/** getDevices() flag to list default devices from the bundled devices.xml definitions. */
@@ -110,27 +113,57 @@
}
/**
+ * Creates a new instance of {@link DeviceManager}, using the user's android folder.
+ *
+ * @see #createInstance(File, File, ILogger, FileOp)
+ */
+ public static DeviceManager createInstance(@Nullable File sdkLocation, @NonNull ILogger log) {
+ File androidFolder;
+ try {
+ androidFolder = new File(AndroidLocation.getFolder());
+ } catch (AndroidLocation.AndroidLocationException e) {
+ androidFolder = null;
+ }
+
+ return createInstance(sdkLocation, androidFolder, log, FileOpUtils.create());
+ }
+
+ /**
* Creates a new instance of DeviceManager.
*
* @param sdkLocation Path to the current SDK. If null or invalid, vendor and system images
* devices are ignored.
+ * @param androidFolder Path to the users' Android folder. If null or invalid, user devices are ignored.
* @param log SDK logger instance. Should be non-null.
*/
- public static DeviceManager createInstance(@Nullable File sdkLocation, @NonNull ILogger log) {
+ public static DeviceManager createInstance(
+ @Nullable File sdkLocation,
+ @Nullable File androidFolder,
+ @NonNull ILogger log,
+ @NonNull FileOp fop) {
// TODO consider using a cache and reusing the same instance of the device manager
// for the same manager/log combo.
- return new DeviceManager(sdkLocation == null ? null : sdkLocation.getPath(), log);
+ return new DeviceManager(sdkLocation, androidFolder, log, fop);
}
/**
* Creates a new instance of DeviceManager.
*
* @param osSdkPath Path to the current SDK. If null or invalid, vendor devices are ignored.
+ * @param androidFolder Path to the user's android folder. If null or invalid, user devices
+ * are ignored.
* @param log SDK logger instance. Should be non-null.
+ * @param fop {@link FileOp} used for file I/O.
*/
- private DeviceManager(@Nullable String osSdkPath, @NonNull ILogger log) {
+ private DeviceManager(
+ @Nullable File osSdkPath,
+ @Nullable File androidFolder,
+ @NonNull ILogger log,
+ @NonNull FileOp fop) {
mOsSdkPath = osSdkPath;
+ mAndroidFolder = androidFolder;
mLog = log;
+ mFop = fop;
}
/**
@@ -362,26 +395,25 @@
// Load devices from tagged system-images
// Path pattern is /sdk/system-images/<platform-N>/<tag>/<abi>/devices.xml
- FileOp fop = FileOpUtils.create();
File sysImgFolder = new File(mOsSdkPath, SdkConstants.FD_SYSTEM_IMAGES);
- for (File platformFolder : fop.listFiles(sysImgFolder)) {
- if (!fop.isDirectory(platformFolder)) {
+ for (File platformFolder : mFop.listFiles(sysImgFolder)) {
+ if (!mFop.isDirectory(platformFolder)) {
continue;
}
- for (File tagFolder : fop.listFiles(platformFolder)) {
- if (!fop.isDirectory(tagFolder)) {
+ for (File tagFolder : mFop.listFiles(platformFolder)) {
+ if (!mFop.isDirectory(tagFolder)) {
continue;
}
- for (File abiFolder : fop.listFiles(tagFolder)) {
- if (!fop.isDirectory(abiFolder)) {
+ for (File abiFolder : mFop.listFiles(tagFolder)) {
+ if (!mFop.isDirectory(abiFolder)) {
continue;
}
File deviceXml = new File(abiFolder, SdkConstants.FN_DEVICES_XML);
- if (fop.isFile(deviceXml)) {
+ if (mFop.isFile(deviceXml)) {
mSysImgDevices.putAll(loadDevices(deviceXml));
}
}
@@ -406,21 +438,19 @@
File userDevicesFile = null;
try {
userDevicesFile = new File(
- AndroidLocation.getFolder(),
+ mAndroidFolder,
SdkConstants.FN_DEVICES_XML);
- if (userDevicesFile.exists()) {
+ if (mFop.exists(userDevicesFile)) {
mUserDevices.putAll(DeviceParser.parse(userDevicesFile));
return true;
}
- } catch (AndroidLocationException e) {
- mLog.warning("Couldn't load user devices: %1$s", e.getMessage());
} catch (SAXException e) {
// Probably an old config file which we don't want to overwrite.
if (userDevicesFile != null) {
String base = userDevicesFile.getAbsoluteFile() + ".old";
File renamedConfig = new File(base);
int i = 0;
- while (renamedConfig.exists()) {
+ while (mFop.exists(renamedConfig)) {
renamedConfig = new File(base + '.' + (i++));
}
mLog.error(e, "Error parsing %1$s, backing up to %2$s",
@@ -482,23 +512,18 @@
}
/**
- * Saves out the user devices to {@link SdkConstants#FN_DEVICES_XML} in
- * {@link AndroidLocation#getFolder()}.
+ * Saves out the user devices to {@link SdkConstants#FN_DEVICES_XML} in the Android folder.
*/
public void saveUserDevices() {
if (mUserDevices == null) {
return;
}
-
- File userDevicesFile = null;
- try {
- userDevicesFile = new File(AndroidLocation.getFolder(),
- SdkConstants.FN_DEVICES_XML);
- } catch (AndroidLocationException e) {
- mLog.warning("Couldn't find user directory: %1$s", e.getMessage());
+ if (mAndroidFolder == null) {
return;
}
+ File userDevicesFile = new File(mAndroidFolder, SdkConstants.FN_DEVICES_XML);
+
if (mUserDevices.isEmpty()) {
userDevicesFile.delete();
return;
diff --git a/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml b/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml
index 37bda80..3cd241d 100644
--- a/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml
+++ b/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml
@@ -1411,4 +1411,178 @@
<d:nav-state>nonav</d:nav-state>
</d:state>
</d:device>
+
+ <d:device>
+ <d:name>Pixel</d:name>
+ <d:id>pixel</d:id>
+ <d:manufacturer>Google</d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>5.0</d:diagonal-length>
+ <d:pixel-density>xxhdpi</d:pixel-density>
+ <d:screen-ratio>notlong</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>1080</d:x-dimension>
+ <d:y-dimension>1920</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>440.58</d:xdpi>
+ <d:ydpi>440.58</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Wifi
+ Bluetooth
+ NFC</d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Compass
+ GPS
+ Gyroscope
+ LightSensor
+ ProximitySensor
+ <!--Fingerprint-->
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>false</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">4</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">32</d:internal-storage>
+ <d:removable-storage unit="MiB">0</d:removable-storage>
+ <d:cpu>Quad Core 2x 2.15GHz / 2x 1.6GHz (Qualcomm Snapdragon 821)</d:cpu>
+ <d:gpu>Adreno 530</d:gpu>
+ <d:abi>
+ arm64-v8a
+ armeabi-v7a
+ armeabi
+ </d:abi>
+ <d:dock> </d:dock>
+ <d:power-type>battery</d:power-type>
+ <d:skin>pixel</d:skin>
+ </d:hardware>
+ <d:software>
+ <d:api-level>25</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles> </d:bluetooth-profiles>
+ <d:gl-version>3.2</d:gl-version>
+ <d:gl-extensions>GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_half_float GL_OES_framebuffer_object GL_OES_rgb8_rgba8 GL_OES_compressed_ETC1_RGB8_texture GL_AMD_compressed_ATC_texture GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_OES_texture_compression_astc GL_OES_texture_npot GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_OES_texture_3D GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_QCOM_alpha_test GL_OES_depth24 GL_OES_packed_depth_stencil GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_EXT_sRGB GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_sRGB_decode GL_OES_element_index_uint GL_EXT_copy_image GL_EXT_geometry_shader GL_EXT_tessellation_shader GL_OES_texture_stencil8 GL_EXT_shader_io_blocks GL_OES_shader_image_atomic GL_OES_sample_variables GL_EXT_texture_border_clamp GL_EXT_multisampled_render_to_texture GL_OES_shader_multisample_interpolation GL_EXT_texture_cube_map_array GL_EXT_draw_buffers_indexed GL_EXT_gpu_shader5 GL_EXT_robustness GL_EXT_texture_buffer GL_EXT_shader_framebuffer_fetch GL_ARM_shader_framebuffer_fetch_depth_stencil GL_OES_texture_storage_multisample_2d_array GL_OES_sample_shading GL_OES_get_program_binary GL_EXT_debug_label GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_QCOM_tiled_rendering GL_ANDROID_extension_pack_es31a GL_EXT_primitive_bounding_box GL_OES_standard_derivatives GL_OES_vertex_array_object GL_EXT_disjoint_timer_query GL_KHR_debug GL_EXT_YUV_target GL_EXT_sRGB_write_control GL_EXT_texture_norm16 GL_EXT_discard_framebuffer GL_OES_surfaceless_context GL_OVR_multiview GL_OVR_multiview2 GL_EXT_texture_sRGB_R8 GL_KHR_no_error GL_EXT_debug_marker GL_OES_EGL_image_external_essl3 GL_OVR_multiview_multisampled_render_to_texture GL_EXT_buffer_storage GL_EXT_blit_framebuffer_params GL_EXT_clip_cull_distance GL_EXT_protected_textures </d:gl-extensions>
+ <d:status-bar>true</d:status-bar>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>port</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>land</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+
+ <d:device>
+ <d:name>Pixel XL</d:name>
+ <d:id>pixel_xl</d:id>
+ <d:manufacturer>Google</d:manufacturer>
+ <d:hardware>
+ <d:screen>
+ <d:screen-size>normal</d:screen-size>
+ <d:diagonal-length>5.5</d:diagonal-length>
+ <d:pixel-density>560dpi</d:pixel-density>
+ <d:screen-ratio>notlong</d:screen-ratio>
+ <d:dimensions>
+ <d:x-dimension>1440</d:x-dimension>
+ <d:y-dimension>2560</d:y-dimension>
+ </d:dimensions>
+ <d:xdpi>534.04</d:xdpi>
+ <d:ydpi>534.04</d:ydpi>
+ <d:touch>
+ <d:multitouch>jazz-hands</d:multitouch>
+ <d:mechanism>finger</d:mechanism>
+ <d:screen-type>capacitive</d:screen-type>
+ </d:touch>
+ </d:screen>
+ <d:networking>
+ Wifi
+ Bluetooth
+ NFC
+ </d:networking>
+ <d:sensors>
+ Accelerometer
+ Barometer
+ Compass
+ GPS
+ Gyroscope
+ LightSensor
+ ProximitySensor
+ <!--Fingerprint-->
+ </d:sensors>
+ <d:mic>true</d:mic>
+ <d:camera>
+ <d:location>back</d:location>
+ <d:autofocus>true</d:autofocus>
+ <d:flash>true</d:flash>
+ </d:camera>
+ <d:camera>
+ <d:location>front</d:location>
+ <d:autofocus>false</d:autofocus>
+ <d:flash>false</d:flash>
+ </d:camera>
+ <d:keyboard>nokeys</d:keyboard>
+ <d:nav>nonav</d:nav>
+ <d:ram unit="GiB">4</d:ram>
+ <d:buttons>soft</d:buttons>
+ <d:internal-storage unit="GiB">32</d:internal-storage>
+ <d:removable-storage unit="MiB">0</d:removable-storage>
+ <d:cpu>Quad Core 2x 2.15GHz / 2x 1.6GHz (Qualcomm Snapdragon 821)</d:cpu>
+ <d:gpu>Adreno 530</d:gpu>
+ <d:abi>
+ arm64-v8a
+ armeabi-v7a
+ armeabi
+ </d:abi>
+ <d:dock> </d:dock>
+ <d:power-type>battery</d:power-type>
+ <d:skin>pixel_xl</d:skin>
+ </d:hardware>
+ <d:software>
+ <d:api-level>25</d:api-level>
+ <d:live-wallpaper-support>true</d:live-wallpaper-support>
+ <d:bluetooth-profiles> </d:bluetooth-profiles>
+ <d:gl-version>3.2</d:gl-version>
+ <d:gl-extensions>GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_half_float GL_OES_framebuffer_object GL_OES_rgb8_rgba8 GL_OES_compressed_ETC1_RGB8_texture GL_AMD_compressed_ATC_texture GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_OES_texture_compression_astc GL_OES_texture_npot GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_OES_texture_3D GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_QCOM_alpha_test GL_OES_depth24 GL_OES_packed_depth_stencil GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_EXT_sRGB GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_sRGB_decode GL_OES_element_index_uint GL_EXT_copy_image GL_EXT_geometry_shader GL_EXT_tessellation_shader GL_OES_texture_stencil8 GL_EXT_shader_io_blocks GL_OES_shader_image_atomic GL_OES_sample_variables GL_EXT_texture_border_clamp GL_EXT_multisampled_render_to_texture GL_OES_shader_multisample_interpolation GL_EXT_texture_cube_map_array GL_EXT_draw_buffers_indexed GL_EXT_gpu_shader5 GL_EXT_robustness GL_EXT_texture_buffer GL_EXT_shader_framebuffer_fetch GL_ARM_shader_framebuffer_fetch_depth_stencil GL_OES_texture_storage_multisample_2d_array GL_OES_sample_shading GL_OES_get_program_binary GL_EXT_debug_label GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_QCOM_tiled_rendering GL_ANDROID_extension_pack_es31a GL_EXT_primitive_bounding_box GL_OES_standard_derivatives GL_OES_vertex_array_object GL_EXT_disjoint_timer_query GL_KHR_debug GL_EXT_YUV_target GL_EXT_sRGB_write_control GL_EXT_texture_norm16 GL_EXT_discard_framebuffer GL_OES_surfaceless_context GL_OVR_multiview GL_OVR_multiview2 GL_EXT_texture_sRGB_R8 GL_KHR_no_error GL_EXT_debug_marker GL_OES_EGL_image_external_essl3 GL_OVR_multiview_multisampled_render_to_texture GL_EXT_buffer_storage GL_EXT_blit_framebuffer_params GL_EXT_clip_cull_distance GL_EXT_protected_textures </d:gl-extensions>
+ <d:status-bar>true</d:status-bar>
+ </d:software>
+ <d:state name="Portrait" default="true">
+ <d:description>The phone in portrait view</d:description>
+ <d:screen-orientation>port</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ <d:state name="Landscape">
+ <d:description>The phone in landscape view</d:description>
+ <d:screen-orientation>land</d:screen-orientation>
+ <d:keyboard-state>keyssoft</d:keyboard-state>
+ <d:nav-state>nonav</d:nav-state>
+ </d:state>
+ </d:device>
+
</d:devices>
diff --git a/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdInfo.java b/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdInfo.java
index 4ea0208..970f241 100644
--- a/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdInfo.java
+++ b/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdInfo.java
@@ -257,7 +257,7 @@
public static File getDefaultAvdFolder(@NonNull AvdManager manager, @NonNull String avdName,
@NonNull FileOp fileOp, boolean unique)
throws AndroidLocationException {
- String base = manager.getBaseAvdFolder();
+ File base = manager.getBaseAvdFolder();
File result = new File(base, avdName + AvdManager.AVD_FOLDER_EXTENSION);
if (unique) {
int suffix = 0;
@@ -281,7 +281,7 @@
@NonNull
public static File getDefaultIniFile(@NonNull AvdManager manager, @NonNull String avdName)
throws AndroidLocationException {
- String avdRoot = manager.getBaseAvdFolder();
+ File avdRoot = manager.getBaseAvdFolder();
return new File(avdRoot, avdName + AvdManager.INI_EXTENSION);
}
diff --git a/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdManager.java b/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdManager.java
index 93b9262..58146a1 100644
--- a/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdManager.java
+++ b/sdklib/src/main/java/com/android/sdklib/internal/avd/AvdManager.java
@@ -76,6 +76,8 @@
*/
public class AvdManager {
+ private File mBaseAvdFolder;
+
/**
* Exception thrown when something is wrong with a target path.
*/
@@ -339,11 +341,15 @@
new HashMap<>();
private final FileOp mFop;
- protected AvdManager(@NonNull AndroidSdkHandler sdkHandler, @NonNull ILogger log,
- @NonNull FileOp fop)
- throws AndroidLocationException {
+ protected AvdManager(
+ @NonNull AndroidSdkHandler sdkHandler,
+ @NonNull File baseAvdFolder,
+ @NonNull ILogger log,
+ @NonNull FileOp fop)
+ throws AndroidLocationException {
mSdkHandler = sdkHandler;
mFop = fop;
+ mBaseAvdFolder = baseAvdFolder;
buildAvdList(mAllAvdList, log);
}
@@ -364,12 +370,19 @@
public static AvdManager getInstance(@NonNull AndroidSdkHandler sdkHandler,
@NonNull ILogger log)
throws AndroidLocationException {
- return getInstance(sdkHandler, log, FileOpUtils.create());
+ return getInstance(
+ sdkHandler,
+ new File(AndroidLocation.getAvdFolder()),
+ log,
+ FileOpUtils.create());
}
@Nullable
- public static AvdManager getInstance(@NonNull AndroidSdkHandler sdkHandler,
- @NonNull ILogger log, @NonNull FileOp fop)
+ public static AvdManager getInstance(
+ @NonNull AndroidSdkHandler sdkHandler,
+ @NonNull File baseAvdFolder,
+ @NonNull ILogger log,
+ @NonNull FileOp fop)
throws AndroidLocationException {
if (sdkHandler.getLocation() == null) {
throw new AndroidLocationException("Local SDK path not set!");
@@ -382,7 +395,7 @@
return manager;
}
try {
- manager = new AvdManager(sdkHandler, log, fop);
+ manager = new AvdManager(sdkHandler, baseAvdFolder, log, fop);
}
catch (AndroidLocationException e){
throw e;
@@ -403,8 +416,8 @@
* @throws AndroidLocationException
*/
@NonNull
- public static String getBaseAvdFolder() throws AndroidLocationException {
- return AndroidLocation.getAvdFolder();
+ public File getBaseAvdFolder() throws AndroidLocationException {
+ return mBaseAvdFolder;
}
/**
@@ -1121,7 +1134,12 @@
String absPath = avdFolder.getAbsolutePath();
String relPath = null;
- String androidPath = AndroidLocation.getFolder();
+ File androidFolder = mSdkHandler.getAndroidFolder();
+ if (androidFolder == null) {
+ throw new AndroidLocation.AndroidLocationException(
+ "Can't locate ANDROID_HOME for the AVD .ini file.");
+ }
+ String androidPath = androidFolder.getAbsolutePath() + File.separator;
if (absPath.startsWith(androidPath)) {
// Compute the AVD path relative to the android path.
assert androidPath.endsWith(File.separator);
@@ -1320,19 +1338,17 @@
* @throws AndroidLocationException if there's a problem getting android root directory.
*/
private File[] buildAvdFilesList() throws AndroidLocationException {
- File folder = new File(getBaseAvdFolder());
-
// ensure folder validity.
- if (mFop.isFile(folder)) {
+ if (mFop.isFile(mBaseAvdFolder)) {
throw new AndroidLocationException(
- String.format("%1$s is not a valid folder.", folder.getAbsolutePath()));
- } else if (mFop.exists(folder) == false) {
+ String.format("%1$s is not a valid folder.", mBaseAvdFolder.getAbsolutePath()));
+ } else if (mFop.exists(mBaseAvdFolder) == false) {
// folder is not there, we create it and return
- mFop.mkdirs(folder);
+ mFop.mkdirs(mBaseAvdFolder);
return null;
}
- File[] avds = mFop.listFiles(folder, (parent, name) -> {
+ File[] avds = mFop.listFiles(mBaseAvdFolder, (parent, name) -> {
if (INI_NAME_PATTERN.matcher(name).matches()) {
// check it's a file and not a folder
return mFop.isFile(new File(parent, name));
@@ -1367,7 +1383,12 @@
private DeviceManager getDeviceManager(ILogger logger) {
DeviceManager manager = mDeviceManagers.get(logger);
if (manager == null) {
- manager = DeviceManager.createInstance(mSdkHandler.getLocation(), logger);
+ manager =
+ DeviceManager.createInstance(
+ mSdkHandler.getLocation(),
+ mSdkHandler.getAndroidFolder(),
+ logger,
+ mFop);
manager.registerListener(mDeviceManagers::clear);
mDeviceManagers.put(logger, manager);
}
@@ -1393,13 +1414,11 @@
// Try to fallback on the relative path, if present.
String relPath = map.get(AVD_INFO_REL_PATH);
if (relPath != null) {
- try {
- String androidPath = AndroidLocation.getFolder();
- File f = new File(androidPath, relPath);
- if (mFop.isDirectory(f)) {
- avdPath = f.getAbsolutePath();
- }
- } catch (AndroidLocationException ignore) {}
+ File androidFolder = mSdkHandler.getAndroidFolder();
+ File f = new File(androidFolder, relPath);
+ if (mFop.isDirectory(f)) {
+ avdPath = f.getAbsolutePath();
+ }
}
}
@@ -1768,7 +1787,6 @@
* @param avd the AVD to update.
* @param log the log object to receive action logs. Cannot be null.
* @return The new AVD on success.
- * @throws IOException
*/
public AvdInfo updateDeviceChanged(AvdInfo avd, ILogger log) throws IOException {
diff --git a/sdklib/src/main/java/com/android/sdklib/repository/AndroidSdkHandler.java b/sdklib/src/main/java/com/android/sdklib/repository/AndroidSdkHandler.java
index 4393c2c..349f73e 100755
--- a/sdklib/src/main/java/com/android/sdklib/repository/AndroidSdkHandler.java
+++ b/sdklib/src/main/java/com/android/sdklib/repository/AndroidSdkHandler.java
@@ -15,6 +15,8 @@
*/
package com.android.sdklib.repository;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
@@ -193,6 +195,12 @@
private final File mLocation;
/**
+ * @see AndroidLocation#getFolder()
+ */
+ @Nullable
+ private final File mAndroidFolder;
+
+ /**
* Provider for user-specified {@link RepositorySource}s.
*/
private LocalSourceProvider mUserSourceProvider;
@@ -213,12 +221,20 @@
public static AndroidSdkHandler getInstance(@Nullable File localPath) {
File key = localPath == null ? new File("") : localPath;
synchronized (sInstances) {
- AndroidSdkHandler instance = sInstances.get(key);
- if (instance == null) {
- instance = new AndroidSdkHandler(localPath, FileOpUtils.create());
- sInstances.put(key, instance);
- }
- return instance;
+ return sInstances.computeIfAbsent(
+ key,
+ k -> {
+ File androidFolder;
+ try {
+ androidFolder = new File(AndroidLocation.getFolder());
+ } catch (AndroidLocation.AndroidLocationException e) {
+ androidFolder = null;
+ }
+ return new AndroidSdkHandler(
+ localPath,
+ androidFolder,
+ FileOpUtils.create());
+ });
}
}
@@ -233,25 +249,31 @@
sInstances.remove(localPath);
}
}
+
/**
* Don't use this, use {@link #getInstance(File)}, unless you're in a unit test and need to
- * specify a custom {@link FileOp}.
+ * specify a custom {@link FileOp} and/or {@code androidFolder}.
*/
@VisibleForTesting
- public AndroidSdkHandler(@Nullable File localPath, @NonNull FileOp fop) {
- mFop = fop;
+ public AndroidSdkHandler(
+ @Nullable File localPath, @Nullable File androidFolder, @NonNull FileOp fop) {
mLocation = localPath;
+ mAndroidFolder = androidFolder;
+ mFop = checkNotNull(fop);
}
/**
* Don't use this either, unless you're in a unit test and need to specify a custom
* {@link RepoManager}.
- * @see #AndroidSdkHandler(File, FileOp)
+ * @see #AndroidSdkHandler(File, File, FileOp)
*/
@VisibleForTesting
- public AndroidSdkHandler(@Nullable File localPath, @NonNull FileOp fop,
+ public AndroidSdkHandler(
+ @Nullable File localPath,
+ @Nullable File androidFolder,
+ @NonNull FileOp fop,
@NonNull RepoManager repoManager) {
- this(localPath, fop);
+ this(localPath, androidFolder, fop);
mRepoManager = repoManager;
}
@@ -274,13 +296,10 @@
mFop);
// Invalidate system images, targets, the latest build tool, and the legacy local
// package manager when local packages change
- result.registerLocalChangeListener(new RepoManager.RepoLoadedCallback() {
- @Override
- public void doRun(@NonNull RepositoryPackages packages) {
- mSystemImageManager = null;
- mAndroidTargetManager = null;
- mLatestBuildTool = null;
- }
+ result.registerLocalChangeListener(packages -> {
+ mSystemImageManager = null;
+ mAndroidTargetManager = null;
+ mLatestBuildTool = null;
});
mRepoManager = result;
}
@@ -322,6 +341,11 @@
return mLocation;
}
+ @Nullable
+ public File getAndroidFolder() {
+ return mAndroidFolder;
+ }
+
/**
* Convenience to get a package from the local repo.
*/
@@ -515,8 +539,8 @@
*/
@Nullable
public LocalSourceProvider getUserSourceProvider(@NonNull ProgressIndicator progress) {
- if (mUserSourceProvider == null) {
- mUserSourceProvider = RepoConfig.createUserSourceProvider(progress, mFop);
+ if (mUserSourceProvider == null && mAndroidFolder != null) {
+ mUserSourceProvider = RepoConfig.createUserSourceProvider(mFop, mAndroidFolder);
synchronized (MANAGER_LOCK) {
if (mRepoManager != null) {
// If the repo already exists cause it to be reloaded, so the userSourceProvider
@@ -604,21 +628,15 @@
}
/**
- * Creates a customizable {@link RepositorySourceProvider}. Can be null if there's a problem
- * with the user's environment.
+ * Creates a customizable {@link RepositorySourceProvider}.
*/
- @Nullable
+ @NonNull
public static LocalSourceProvider createUserSourceProvider(
- @NonNull ProgressIndicator progress,
- @NonNull FileOp fileOp) {
- try {
- return new LocalSourceProvider(
- new File(AndroidLocation.getFolder(), LOCAL_ADDONS_FILENAME),
- ImmutableList.of(SYS_IMG_MODULE, ADDON_MODULE), fileOp);
- } catch (AndroidLocation.AndroidLocationException e) {
- progress.logWarning("Couldn't find android folder", e);
- }
- return null;
+ @NonNull FileOp fileOp, @NonNull File androidFolder) {
+ return new LocalSourceProvider(
+ new File(androidFolder, LOCAL_ADDONS_FILENAME),
+ ImmutableList.of(SYS_IMG_MODULE, ADDON_MODULE),
+ fileOp);
}
@NonNull
diff --git a/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyDownloader.java b/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyDownloader.java
index d85c8b8..0ded548 100644
--- a/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyDownloader.java
+++ b/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyDownloader.java
@@ -46,7 +46,8 @@
private SettingsController mSettingsController;
public LegacyDownloader(@NonNull FileOp fop, @NonNull SettingsController settings) {
- mDownloadCache = new DownloadCache(fop, DownloadCache.Strategy.FRESH_CACHE, settings);
+ mDownloadCache =
+ DownloadCache.inUserHome(fop, DownloadCache.Strategy.FRESH_CACHE, settings);
mFileOp = fop;
mSettingsController = settings;
}
diff --git a/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyRemoteRepoLoader.java b/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyRemoteRepoLoader.java
index 5f19468..56d05fa 100644
--- a/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyRemoteRepoLoader.java
+++ b/sdklib/src/main/java/com/android/sdklib/repository/legacy/LegacyRemoteRepoLoader.java
@@ -18,6 +18,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
+import com.android.prefs.AndroidLocation;
import com.android.repository.Revision;
import com.android.repository.api.Channel;
import com.android.repository.api.ConsoleProgressIndicator;
@@ -83,11 +84,13 @@
/**
* Gets or creates a {@link DownloadCache} using the settings from our {@link
- * SettingsController}.
+ * SettingsController} and {@link AndroidLocation}.
*/
private DownloadCache getDownloadCache(@NonNull SettingsController settings) {
if (mDownloadCache == null) {
- mDownloadCache = new DownloadCache(DownloadCache.Strategy.FRESH_CACHE, settings);
+ mDownloadCache =
+ DownloadCache.inUserHome(
+ FileOpUtils.create(), DownloadCache.Strategy.FRESH_CACHE, settings);
}
return mDownloadCache;
}
diff --git a/sdklib/src/main/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCache.java b/sdklib/src/main/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCache.java
index a21fc10..e9f1c67 100644
--- a/sdklib/src/main/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCache.java
+++ b/sdklib/src/main/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCache.java
@@ -175,17 +175,28 @@
DIRECT
}
- /** Creates a default instance of the URL cache */
- public DownloadCache(@NonNull Strategy strategy, @NonNull SettingsController settings) {
- this(FileOpUtils.create(), strategy, settings);
+ public static DownloadCache inUserHome(
+ @NonNull FileOp fileOp,
+ @NonNull Strategy strategy,
+ @NonNull SettingsController settings) {
+ File androidFolder;
+ try {
+ androidFolder = new File(AndroidLocation.getFolder());
+ } catch (AndroidLocationException e) {
+ androidFolder = null;
+ }
+ return new DownloadCache(androidFolder, fileOp, strategy, settings);
}
/** Creates a default instance of the URL cache */
- public DownloadCache(@NonNull FileOp fileOp, @NonNull Strategy strategy,
+ public DownloadCache(
+ @Nullable File androidFolder,
+ @NonNull FileOp fileOp,
+ @NonNull Strategy strategy,
@NonNull SettingsController settings) {
mFileOp = fileOp;
mSettings = settings;
- mCacheRoot = initCacheRoot();
+ mCacheRoot = initCacheRoot(androidFolder);
// If this is defined in the environment, never use the cache. Useful for testing.
if (System.getenv("SDKMAN_DISABLE_CACHE") != null) { //$NON-NLS-1$
@@ -203,30 +214,26 @@
/**
* Returns the directory to be used as a cache.
* Creates it if necessary.
- * Makes it possible to disable or override the cache location in unit tests.
*
* @return An existing directory to use as a cache root dir,
* or null in case of error in which case the cache will be disabled.
+ * @param androidFolder
*/
- @VisibleForTesting(visibility=Visibility.PRIVATE)
@Nullable
- protected File initCacheRoot() {
- try {
- File root = new File(AndroidLocation.getFolder());
- root = new File(root, SdkConstants.FD_CACHE);
- if (!mFileOp.exists(root)) {
- mFileOp.mkdirs(root);
- }
- return root;
- } catch (AndroidLocationException e) {
- // No root? Disable the cache.
+ private File initCacheRoot(@Nullable File androidFolder) {
+ if (androidFolder == null) {
return null;
}
+
+ File cacheRoot = new File(androidFolder, SdkConstants.FD_CACHE);
+ if (!mFileOp.exists(cacheRoot)) {
+ mFileOp.mkdirs(cacheRoot);
+ }
+ return cacheRoot;
}
/**
- * Calls {@link HttpConfigurable#openHttpConnection(String)}
- * to actually perform a download.
+ * Calls {@link URL#openConnection()} to actually perform a download.
* <p>
* Isolated so that it can be overridden by unit tests.
*/
diff --git a/sdklib/src/main/java/com/android/sdklib/tool/AvdManagerCli.java b/sdklib/src/main/java/com/android/sdklib/tool/AvdManagerCli.java
index 493f68f..76676a4 100644
--- a/sdklib/src/main/java/com/android/sdklib/tool/AvdManagerCli.java
+++ b/sdklib/src/main/java/com/android/sdklib/tool/AvdManagerCli.java
@@ -518,11 +518,8 @@
* Displays the list of available devices.
*/
private void displayDeviceList() {
-
- DeviceManager devman = DeviceManager.createInstance(
- new File(mOsSdkFolder), mSdkLog);
-
- List<Device> devices = new ArrayList<>(devman.getDevices(DeviceManager.ALL_DEVICES));
+ List<Device> devices =
+ new ArrayList<>(createDeviceManager().getDevices(DeviceManager.ALL_DEVICES));
Collections.sort(devices, Device.getDisplayComparator());
// Compact output, suitable for scripts.
@@ -555,6 +552,22 @@
}
}
+ @NonNull
+ private DeviceManager createDeviceManager() {
+ File androidFolder;
+ try {
+ androidFolder = new File(AndroidLocation.getFolder());
+ } catch (AndroidLocation.AndroidLocationException e) {
+ mSdkLog.warning(e.getMessage());
+ androidFolder = null;
+ }
+ return DeviceManager.createInstance(
+ new File(mOsSdkFolder),
+ androidFolder,
+ mSdkLog,
+ mSdkHandler.getFileOp());
+ }
+
/**
* Creates a new AVD. This is a text based creation with command line prompt.
*/
@@ -686,11 +699,8 @@
Device device = null;
String deviceParam = getParamDevice();
if (deviceParam != null) {
- DeviceManager deviceManager = DeviceManager.createInstance(
- new File(mOsSdkFolder), mSdkLog);
-
List<Device> devices = new ArrayList<>(
- deviceManager.getDevices(DeviceManager.ALL_DEVICES));
+ createDeviceManager().getDevices(DeviceManager.ALL_DEVICES));
Collections.sort(devices, Device.getDisplayComparator());
int index = -1;
diff --git a/sdklib/src/main/java/com/android/sdklib/tool/SdkManagerCli.java b/sdklib/src/main/java/com/android/sdklib/tool/SdkManagerCli.java
index 0f24f9e..fe39abe 100644
--- a/sdklib/src/main/java/com/android/sdklib/tool/SdkManagerCli.java
+++ b/sdklib/src/main/java/com/android/sdklib/tool/SdkManagerCli.java
@@ -42,7 +42,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -101,8 +100,7 @@
System.exit(1);
}
}
-
- AndroidSdkHandler handler = new AndroidSdkHandler(localPath.toFile(), fop);
+ AndroidSdkHandler handler = AndroidSdkHandler.getInstance(localPath.toFile());
new SdkManagerCli(settings, System.out, System.in, new LegacyDownloader(fop, settings),
handler).run();
System.out.println("done");
@@ -302,7 +300,8 @@
private boolean askYesNo() {
try {
String result = mIn.readLine();
- return result.equalsIgnoreCase("y") || result.equalsIgnoreCase("yes");
+ return result != null
+ && (result.equalsIgnoreCase("y") || result.equalsIgnoreCase("yes"));
} catch (IOException e) {
return false;
}
diff --git a/sdklib/src/test/java/com/android/sdklib/BuildToolInfoTest.java b/sdklib/src/test/java/com/android/sdklib/BuildToolInfoTest.java
index 593e421..c46e1f6 100644
--- a/sdklib/src/test/java/com/android/sdklib/BuildToolInfoTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/BuildToolInfoTest.java
@@ -30,7 +30,8 @@
public void testGetCurrentJvmVersion() {
MockFileOp fop = new MockFileOp();
recordBuildTool23(fop);
- AndroidSdkHandler sdkHandler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler sdkHandler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
BuildToolInfo bt = sdkHandler.getBuildToolInfo(new Revision(23, 0, 2), progress);
progress.assertNoErrorsOrWarnings();
diff --git a/sdklib/src/test/java/com/android/sdklib/SdkVersionInfoTest.java b/sdklib/src/test/java/com/android/sdklib/SdkVersionInfoTest.java
index 19cd61e..9a24087 100644
--- a/sdklib/src/test/java/com/android/sdklib/SdkVersionInfoTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/SdkVersionInfoTest.java
@@ -31,6 +31,7 @@
public void testGetAndroidName() {
assertEquals("API 16: Android 4.1 (Jelly Bean)", SdkVersionInfo.getAndroidName(16));
assertEquals("API 20: Android 4.4W (KitKat Wear)", SdkVersionInfo.getAndroidName(20));
+ assertEquals("API 25: Android 7.1.1 (Nougat)", SdkVersionInfo.getAndroidName(25));
// Future: if we don't have a name, don't include "null" as a name
assertEquals("API 500", SdkVersionInfo.getAndroidName(500));
}
diff --git a/sdklib/src/test/java/com/android/sdklib/TempAndroidLocation.java b/sdklib/src/test/java/com/android/sdklib/TempAndroidLocation.java
deleted file mode 100644
index b5e6843..0000000
--- a/sdklib/src/test/java/com/android/sdklib/TempAndroidLocation.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * 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.android.sdklib;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.EnvVar;
-import com.android.sdklib.internal.avd.AvdManager;
-
-import com.android.utils.FileUtils;
-import org.junit.rules.ExternalResource;
-
-import java.io.File;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * {@link org.junit.rules.TestRule} that overrides the {@link AndroidLocation} to point to temp one.
- * <p>
- * This one doesn't create a temp fake SDK (see {@link TempSdkManager}.)
- * Instead this is about setting up a temporary folder for android data as AVDs and other stored config files.
- */
-public class TempAndroidLocation extends ExternalResource {
-
- private final String mAndroidConfigHomeName;
- private String mOldAndroidConfigHomeProp;
- private String mOldAvdHomeProp;
- private File mAndroidConfigHome;
- private File mAvdHome;
-
- public TempAndroidLocation(String androidConfigHomeName) {
- mAndroidConfigHomeName = androidConfigHomeName;
- }
-
- /**
- * Sets up a fake config folder in a temporary directory,
- * and an AVD Manager pointing to an initially-empty AVD directory.
- */
- @Override
- protected void before() throws Throwable {
- makeFakeAndroidConfigHome();
- }
-
- /**
- * Removes the temporary directories for AVDs and other config data.
- */
- @Override
- protected void after() {
- tearDownAndroidConfigHome();
- }
-
- private void makeFakeAndroidConfigHome() throws Exception {
- // First we create a temp file to "reserve" the temp directory name we want to use.
- mAndroidConfigHome = File.createTempFile(mAndroidConfigHomeName, null);
- mAvdHome = File.createTempFile("avd_" + mAndroidConfigHomeName, null);
- // Then erase the file and make the directory
- mAndroidConfigHome.delete();
- mAndroidConfigHome.mkdirs();
- mAvdHome.delete();
- mAvdHome.mkdirs();
-
- // Set the system property that will force AndroidLocation to use this
- mOldAndroidConfigHomeProp = System.getProperty(EnvVar.ANDROID_SDK_HOME.getName());
- mOldAvdHomeProp = System.getProperty(EnvVar.ANDROID_AVD_HOME.getName());
- System.setProperty(EnvVar.ANDROID_SDK_HOME.getName(), mAndroidConfigHome.getAbsolutePath());
- System.setProperty(EnvVar.ANDROID_AVD_HOME.getName(), mAvdHome.getAbsolutePath());
- AndroidLocation.resetFolder();
-
- // Assert that we are using the ANDROID_AVD_HOME in AndroidLocation and AvdManager:
- assertEquals(FileUtils.toSystemIndependentPath(mAvdHome.getPath() + File.separator),
- FileUtils.toSystemDependentPath(AndroidLocation.getAvdFolder()));
- assertEquals(FileUtils.toSystemIndependentPath(mAvdHome.getPath() + File.separator),
- FileUtils.toSystemDependentPath(AvdManager.getBaseAvdFolder()));
- }
-
- private void tearDownAndroidConfigHome() {
- if (mOldAndroidConfigHomeProp == null) {
- System.clearProperty(EnvVar.ANDROID_SDK_HOME.getName());
- } else {
- System.setProperty(EnvVar.ANDROID_SDK_HOME.getName(), mOldAndroidConfigHomeProp);
- }
- AndroidLocation.resetFolder();
- deleteDir(mAndroidConfigHome);
- }
-
- /** Clear the .android home folder and reconstruct it empty. */
- private void clearAndroidHome() {
- deleteDir(mAndroidConfigHome);
- mAndroidConfigHome.mkdirs();
- AndroidLocation.resetFolder();
- }
-
- /**
- * Recursive delete directory. Mostly for fake SDKs.
- *
- * @param root directory to delete
- */
- private static void deleteDir(File root) {
- if (root.exists()) {
- for (File file : root.listFiles()) {
- if (file.isDirectory()) {
- deleteDir(file);
- } else {
- file.delete();
- }
- }
- root.delete();
- }
- }
-}
diff --git a/sdklib/src/test/java/com/android/sdklib/TempSdkManager.java b/sdklib/src/test/java/com/android/sdklib/TempSdkManager.java
index b53e533..408e773 100644
--- a/sdklib/src/test/java/com/android/sdklib/TempSdkManager.java
+++ b/sdklib/src/test/java/com/android/sdklib/TempSdkManager.java
@@ -23,7 +23,6 @@
import com.android.annotations.Nullable;
import com.android.repository.Revision;
import com.android.repository.io.FileOpUtils;
-import com.android.repository.testframework.MockFileOp;
import com.android.resources.Density;
import com.android.resources.Keyboard;
import com.android.resources.KeyboardState;
@@ -46,11 +45,11 @@
import com.android.sdklib.devices.State;
import com.android.sdklib.devices.Storage;
import com.android.sdklib.devices.Storage.Unit;
-import com.android.testutils.MockLog;
import com.android.sdklib.repository.AndroidSdkHandler;
import com.android.sdklib.repository.PkgProps;
import com.android.sdklib.repository.legacy.local.LocalPlatformPkgInfo;
import com.android.sdklib.repository.legacy.local.LocalSysImgPkgInfo;
+import com.android.testutils.MockLog;
import org.junit.rules.ExternalResource;
@@ -69,16 +68,17 @@
private static final String TARGET_DIR_NAME_0 = "v0_0";
- private final String mSdkFileName;
+ private final String mTestName;
private File mFakeSdk;
+ private File mFakeAndroidFolder;
private MockLog mLog;
private AndroidSdkHandler mSdkHandler;
- public TempSdkManager(String sdkFileName) {
- mSdkFileName = sdkFileName;
+ public TempSdkManager(String testName) {
+ mTestName = testName;
}
/**
@@ -100,6 +100,7 @@
protected void before() throws Throwable {
mLog = new MockLog();
makeFakeSdk();
+ makeFakeAndroidFolder();
createSdkAvdManagers();
}
@@ -109,7 +110,7 @@
* will be reparsed.
*/
private void createSdkAvdManagers() {
- mSdkHandler = new AndroidSdkHandler(mFakeSdk, new MockFileOp());
+ mSdkHandler = new AndroidSdkHandler(mFakeSdk, mFakeAndroidFolder, FileOpUtils.create());
}
/**
@@ -127,7 +128,7 @@
*/
private void makeFakeSdk() throws IOException {
// First we create a temp file to "reserve" the temp directory name we want to use.
- mFakeSdk = File.createTempFile(mSdkFileName, null);
+ mFakeSdk = File.createTempFile(mTestName, "sdk");
// Then erase the file and make the directory
mFakeSdk.delete();
mFakeSdk.mkdirs();
@@ -158,6 +159,12 @@
makeFakeSourceInternal(mFakeSdk);
}
+ private void makeFakeAndroidFolder() throws IOException {
+ mFakeAndroidFolder = File.createTempFile(mTestName, "android-home");
+ mFakeAndroidFolder.delete();
+ mFakeAndroidFolder.mkdirs();
+ }
+
private void tearDownSdk() {
deleteDir(mFakeSdk);
}
diff --git a/sdklib/src/test/java/com/android/sdklib/devices/DeviceManagerTest.java b/sdklib/src/test/java/com/android/sdklib/devices/DeviceManagerTest.java
index a5d517d..1b84da8 100644
--- a/sdklib/src/test/java/com/android/sdklib/devices/DeviceManagerTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/devices/DeviceManagerTest.java
@@ -16,21 +16,23 @@
package com.android.sdklib.devices;
-import com.android.repository.Revision;
+import static com.google.common.truth.Truth.assertThat;
+
import com.android.repository.impl.meta.TypeDetails;
+import com.android.repository.io.FileOpUtils;
import com.android.repository.testframework.FakePackage;
import com.android.resources.Keyboard;
import com.android.resources.Navigation;
-import com.android.sdklib.TempAndroidLocation;
import com.android.sdklib.TempSdkManager;
import com.android.sdklib.devices.Device.Builder;
import com.android.sdklib.devices.DeviceManager.DeviceFilter;
import com.android.sdklib.devices.DeviceManager.DeviceStatus;
-import com.android.testutils.MockLog;
import com.android.sdklib.repository.AndroidSdkHandler;
import com.android.sdklib.repository.IdDisplay;
import com.android.sdklib.repository.meta.DetailsTypes;
import com.android.sdklib.repository.targets.SystemImage;
+import com.android.testutils.MockLog;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -43,13 +45,9 @@
import java.util.List;
import java.util.stream.Collectors;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(JUnit4.class)
public class DeviceManagerTest {
- @Rule public final TempAndroidLocation androidLocation =
- new TempAndroidLocation("androidhome_" + getClass().getSimpleName());
@Rule public final TempSdkManager sdkManager =
new TempSdkManager("sdk_" + getClass().getSimpleName());
@@ -64,8 +62,12 @@
private DeviceManager createDeviceManager() {
log = sdkManager.getLog();
- File sdkLocation = sdkManager.getSdkHandler().getLocation();
- return DeviceManager.createInstance(sdkLocation, log);
+ AndroidSdkHandler sdkHandler = sdkManager.getSdkHandler();
+ return DeviceManager.createInstance(
+ sdkHandler.getLocation(),
+ sdkHandler.getAndroidFolder(),
+ log,
+ FileOpUtils.create());
}
/**
@@ -103,7 +105,8 @@
"Android TV (1080p)", "Android TV (720p)", "Android Wear Round",
"Android Wear Round Chin", "Android Wear Square", "Galaxy Nexus", "Nexus 10",
"Nexus 4", "Nexus 5", "Nexus 5X", "Nexus 6", "Nexus 6P", "Nexus 7",
- "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C");
+ "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C",
+ "Pixel", "Pixel XL");
assertThat(log.getMessages()).isEmpty();
assertThat(dm.getDevice("Nexus One", "Google").getDisplayName()).isEqualTo("Nexus One");
@@ -116,7 +119,8 @@
"7\" WSVGA (Tablet)", "Android TV (1080p)", "Android TV (720p)",
"Android Wear Round", "Android Wear Round Chin", "Android Wear Square",
"Galaxy Nexus", "Nexus 10", "Nexus 4", "Nexus 5", "Nexus 5X", "Nexus 6", "Nexus 6P",
- "Nexus 7", "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C");
+ "Nexus 7", "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C",
+ "Pixel", "Pixel XL");
assertThat(log.getMessages()).isEmpty();
}
@@ -185,7 +189,8 @@
"Android TV (1080p)", "Android TV (720p)", "Android Wear Round",
"Android Wear Round Chin", "Android Wear Square", "Galaxy Nexus", "Nexus 10",
"Nexus 4", "Nexus 5", "Nexus 5X", "Nexus 6", "Nexus 6P", "Nexus 7",
- "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C");
+ "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C",
+ "Pixel", "Pixel XL");
assertThat(log.getMessages()).isEmpty();
assertThat(listDisplayNames(dm2.getDevices(DeviceManager.ALL_DEVICES))).containsExactly(
@@ -197,7 +202,8 @@
"Android Wear Round", "Android Wear Round Chin", "Android Wear Square",
"Galaxy Nexus", "My Custom Tablet", "Nexus 10", "Nexus 4", "Nexus 5", "Nexus 5X",
"Nexus 6", "Nexus 6P", "Nexus 7", "Nexus 7 (2012)", "Nexus 9", "Nexus One",
- "Nexus S", "Pixel C");
+ "Nexus S", "Pixel C", "Pixel", "Pixel XL");
+
assertThat(log.getMessages()).isEmpty();
}
@@ -235,7 +241,8 @@
"Android TV (1080p)", "Android TV (720p)", "Android Wear Round",
"Android Wear Round Chin", "Android Wear Square", "Galaxy Nexus", "Nexus 10",
"Nexus 4", "Nexus 5", "Nexus 5X", "Nexus 6", "Nexus 6P", "Nexus 7",
- "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C");
+ "Nexus 7 (2012)", "Nexus 9", "Nexus One", "Nexus S", "Pixel C",
+ "Pixel", "Pixel XL");
assertThat(log.getMessages()).isEmpty();
assertThat(listDisplayNames(dm.getDevices(DeviceManager.ALL_DEVICES))).containsExactly(
@@ -247,7 +254,7 @@
"Android Wear Round", "Android Wear Round Chin", "Android Wear Square",
"Galaxy Nexus", "Mock Tag 1 Device Name", "Nexus 10", "Nexus 4", "Nexus 5",
"Nexus 5X", "Nexus 6", "Nexus 6P", "Nexus 7", "Nexus 7 (2012)", "Nexus 9",
- "Nexus One", "Nexus S", "Pixel C");
+ "Nexus One", "Nexus S", "Pixel C", "Pixel", "Pixel XL");
assertThat(log.getMessages()).isEmpty();
}
@@ -330,13 +337,13 @@
IdDisplay.create("android-wear", "android-wear"),
IdDisplay.create("Google", "Google1"),
"x86", new File[]{}, p);
- DeviceManager manager = DeviceManager.createInstance(location, log);
+ DeviceManager manager = createDeviceManager();
int count = manager.getDevices(EnumSet.allOf(DeviceFilter.class)).size();
Device d = manager.getDevice("wear_round", "Google");
assertThat(d.getDisplayName()).isEqualTo("Android Wear Round");
sdkManager.makeSystemImageFolder(imageWithDevice, "wear_round");
- manager = DeviceManager.createInstance(location, log);
+ manager = createDeviceManager();
d = manager.getDevice("wear_round", "Google");
assertThat(d.getDisplayName()).isEqualTo("Mock Android wear Device Name");
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/AddonListSourceProviderTest.java b/sdklib/src/test/java/com/android/sdklib/repository/AddonListSourceProviderTest.java
index 741a7f6..34d3902 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/AddonListSourceProviderTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/AddonListSourceProviderTest.java
@@ -16,12 +16,11 @@
package com.android.sdklib.repository;
import com.android.prefs.AndroidLocation;
-import com.android.repository.testframework.FakeDownloader;
-import com.android.repository.testframework.FakeProgressIndicator;
import com.android.repository.api.RepositorySource;
import com.android.repository.api.RepositorySourceProvider;
+import com.android.repository.testframework.FakeDownloader;
+import com.android.repository.testframework.FakeProgressIndicator;
import com.android.repository.testframework.MockFileOp;
-import com.android.sdklib.repository.AndroidSdkHandler;
import com.android.testutils.TestResources;
import com.android.utils.FileUtils;
import com.google.common.collect.ImmutableSet;
@@ -37,10 +36,12 @@
*/
public class AddonListSourceProviderTest extends TestCase {
+ public static final File ANDROID_FOLDER = new File("/android-home");
+
public void testRemoteSource() throws Exception {
MockFileOp fop = new MockFileOp();
FakeDownloader downloader = new FakeDownloader(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(null, fop);
+ AndroidSdkHandler handler = new AndroidSdkHandler(null, ANDROID_FOLDER, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
RepositorySourceProvider provider = handler.getRemoteListSourceProvider(progress);
@@ -85,12 +86,12 @@
public void testLocalSource() throws Exception {
AndroidLocation.resetFolder();
MockFileOp fop = new MockFileOp();
+ fop.mkdirs(ANDROID_FOLDER);
File testFile = TestResources.getFile(getClass(), "/repositories.xml");
fop.recordExistingFile(
- new File(AndroidLocation.getFolder(), AndroidSdkHandler.LOCAL_ADDONS_FILENAME)
- .getAbsolutePath(),
+ new File(ANDROID_FOLDER, AndroidSdkHandler.LOCAL_ADDONS_FILENAME).getAbsolutePath(),
FileUtils.loadFileWithUnixLineSeparators(testFile));
- AndroidSdkHandler handler = new AndroidSdkHandler(null, fop);
+ AndroidSdkHandler handler = new AndroidSdkHandler(null, ANDROID_FOLDER, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
handler.getSdkManager(progress);
RepositorySourceProvider provider = handler.getUserSourceProvider(progress);
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/UnmarshalTest.java b/sdklib/src/test/java/com/android/sdklib/repository/UnmarshalTest.java
index f9f1bba..ef67cf9 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/UnmarshalTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/UnmarshalTest.java
@@ -15,6 +15,7 @@
*/
package com.android.sdklib.repository;
+import com.android.annotations.NonNull;
import com.android.repository.Revision;
import com.android.repository.api.License;
import com.android.repository.api.LocalPackage;
@@ -27,7 +28,6 @@
import com.android.repository.impl.meta.SchemaModuleUtil;
import com.android.repository.testframework.FakeProgressIndicator;
import com.android.repository.testframework.MockFileOp;
-import com.android.sdklib.repository.AndroidSdkHandler;
import com.android.sdklib.repository.meta.DetailsTypes;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
@@ -50,7 +50,7 @@
InputStream xmlStream = getClass().getResourceAsStream(filename);
assertNotNull("Missing test file: " + filename, xmlStream);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File(filename), new MockFileOp());
+ AndroidSdkHandler handler = getAndroidSdkHandler();
SchemaModule repoEx = AndroidSdkHandler.getRepositoryModule();
SchemaModule addonEx = AndroidSdkHandler.getAddonModule();
FakeProgressIndicator progress = new FakeProgressIndicator();
@@ -124,7 +124,7 @@
+ "</repo:repository>";
public void testLeniency() throws Exception {
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), new MockFileOp());
+ AndroidSdkHandler handler = getAndroidSdkHandler();
FakeProgressIndicator progress = new FakeProgressIndicator();
RepoManager mgr = handler.getSdkManager(progress);
Repository repo = (Repository) SchemaModuleUtil
@@ -163,7 +163,7 @@
+ "</repo:repository>";
public void testNamespaceFallback() throws Exception {
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), new MockFileOp());
+ AndroidSdkHandler handler = getAndroidSdkHandler();
FakeProgressIndicator progress = new FakeProgressIndicator();
RepoManager mgr = handler.getSdkManager(progress);
Repository repo = (Repository) SchemaModuleUtil
@@ -187,4 +187,9 @@
}
}
+ @NonNull
+ private static AndroidSdkHandler getAndroidSdkHandler() {
+ MockFileOp fileOp = new MockFileOp();
+ return new AndroidSdkHandler(new File("/sdk"), null, fileOp);
+ }
}
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/installer/MavenInstallListenerTest.java b/sdklib/src/test/java/com/android/sdklib/repository/installer/MavenInstallListenerTest.java
index f62d5d8..6bee157 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/installer/MavenInstallListenerTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/installer/MavenInstallListenerTest.java
@@ -74,13 +74,14 @@
+ " <name>test package 1 version 1.2.3</name>\n"
+ "</project>";
+ private static final File ROOT = new File("/repo");
+
public void testInstallFirst() throws Exception {
- File root = new File("/repo");
MockFileOp fop = new MockFileOp();
RepoManager mgr = new RepoManagerImpl(fop);
mgr.registerSchemaModule(AndroidSdkHandler.getCommonModule());
mgr.registerSchemaModule(AndroidSdkHandler.getAddonModule());
- mgr.setLocalPath(root);
+ mgr.setLocalPath(ROOT);
FakeDownloader downloader = new FakeDownloader(fop);
URL repoUrl = new URL("http://example.com/dummy.xml");
@@ -120,14 +121,16 @@
.get("m2repository;com;android;group1;artifact1;1.2.3");
// Install
BasicInstallerFactory factory = new BasicInstallerFactory();
- factory.setListenerFactory(new FakeInstallListenerFactory(
- new MavenInstallListener(new AndroidSdkHandler(root, fop))));
+ factory.setListenerFactory(
+ new FakeInstallListenerFactory(
+ new MavenInstallListener(
+ new AndroidSdkHandler(ROOT, null, fop))));
Installer installer = factory.createInstaller(p, mgr, downloader, fop);
installer.prepare(runner.getProgressIndicator());
installer.complete(runner.getProgressIndicator());
runner.getProgressIndicator().assertNoErrorsOrWarnings();
- File artifactRoot = new File(root, "m2repository/com/android/group1/artifact1");
+ File artifactRoot = new File(ROOT, "m2repository/com/android/group1/artifact1");
File mavenMetadata = new File(artifactRoot, "maven-metadata.xml");
MavenInstallListener.MavenMetadata metadata = MavenInstallListener.unmarshal(mavenMetadata,
MavenInstallListener.MavenMetadata.class, runner.getProgressIndicator(), fop);
@@ -138,13 +141,13 @@
assertEquals(ImmutableList.of("1.2.3"), metadata.versioning.versions.version);
File[] contents = fop
- .listFiles(new File(root, "m2repository/com/android/group1/artifact1/1.2.3"));
+ .listFiles(new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3"));
// Ensure it was installed on the filesystem
assertArrayEquals(new File[]{
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/a"),
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/artifact1-1.2.3.pom"),
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/package.xml")},
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/a"),
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/artifact1-1.2.3.pom"),
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/package.xml")},
contents);
// Reload
@@ -180,11 +183,10 @@
fop.recordExistingFile(
"/repo/m2repository/com/android/group1/artifact1/1.0.0/artifact1-1.0.0.pom",
POM_1_0_0_CONTENTS);
- File root = new File("/repo");
RepoManager mgr = new RepoManagerImpl(fop);
mgr.registerSchemaModule(AndroidSdkHandler.getCommonModule());
mgr.registerSchemaModule(AndroidSdkHandler.getAddonModule());
- mgr.setLocalPath(root);
+ mgr.setLocalPath(ROOT);
FakeDownloader downloader = new FakeDownloader(fop);
URL repoUrl = new URL("http://example.com/dummy.xml");
@@ -226,14 +228,16 @@
// Install
InstallerFactory factory = new BasicInstallerFactory();
- factory.setListenerFactory(new FakeInstallListenerFactory(
- new MavenInstallListener(new AndroidSdkHandler(root, fop))));
+ factory.setListenerFactory(
+ new FakeInstallListenerFactory(
+ new MavenInstallListener(
+ new AndroidSdkHandler(ROOT, null, fop))));
Installer installer = factory.createInstaller(remotePackage, mgr, downloader, fop);
installer.prepare(runner.getProgressIndicator());
installer.complete(runner.getProgressIndicator());
runner.getProgressIndicator().assertNoErrorsOrWarnings();
- File artifactRoot = new File(root, "m2repository/com/android/group1/artifact1");
+ File artifactRoot = new File(ROOT, "m2repository/com/android/group1/artifact1");
File mavenMetadata = new File(artifactRoot, "maven-metadata.xml");
MavenInstallListener.MavenMetadata metadata = MavenInstallListener
.unmarshal(mavenMetadata, MavenInstallListener.MavenMetadata.class,
@@ -245,13 +249,13 @@
assertEquals(ImmutableList.of("1.0.0", "1.2.3"), metadata.versioning.versions.version);
File[] contents = fop
- .listFiles(new File(root, "m2repository/com/android/group1/artifact1/1.2.3"));
+ .listFiles(new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3"));
// Ensure it was installed on the filesystem
assertArrayEquals(new File[]{
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/a"),
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/artifact1-1.2.3.pom"),
- new File(root, "m2repository/com/android/group1/artifact1/1.2.3/package.xml")},
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/a"),
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/artifact1-1.2.3.pom"),
+ new File(ROOT, "m2repository/com/android/group1/artifact1/1.2.3/package.xml")},
contents);
// Reload
mgr.load(0, ImmutableList.<RepoLoadedCallback>of(), ImmutableList.<RepoLoadedCallback>of(),
@@ -334,9 +338,8 @@
+ " </versioning>\n"
+ "</metadata>\n");
- File root = new File("/repo");
RepoManager mgr = new RepoManagerImpl(fop);
- mgr.setLocalPath(root);
+ mgr.setLocalPath(ROOT);
mgr.registerSchemaModule(AndroidSdkHandler.getCommonModule());
mgr.registerSchemaModule(AndroidSdkHandler.getAddonModule());
@@ -353,8 +356,10 @@
LocalPackage p = locals.get("m2repository;com;android;group1;artifact1;1.2.3");
assertNotNull(p);
InstallerFactory factory = new BasicInstallerFactory();
- factory.setListenerFactory(new FakeInstallListenerFactory(
- new MavenInstallListener(new AndroidSdkHandler(root, fop))));
+ factory.setListenerFactory(
+ new FakeInstallListenerFactory(
+ new MavenInstallListener(
+ new AndroidSdkHandler(ROOT, null, fop))));
Uninstaller uninstaller = factory.createUninstaller(p, mgr, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
uninstaller.prepare(progress);
@@ -412,9 +417,8 @@
+ " </versioning>\n"
+ "</metadata>\n");
- File root = new File("/repo");
RepoManager mgr = new RepoManagerImpl(fop);
- mgr.setLocalPath(root);
+ mgr.setLocalPath(ROOT);
mgr.registerSchemaModule(AndroidSdkHandler.getCommonModule());
mgr.registerSchemaModule(AndroidSdkHandler.getAddonModule());
@@ -431,8 +435,10 @@
LocalPackage p = locals.get("m2repository;com;android;group1;artifact1;1.2.3");
assertNotNull(p);
InstallerFactory factory = new BasicInstallerFactory();
- factory.setListenerFactory(new FakeInstallListenerFactory(
- new MavenInstallListener(new AndroidSdkHandler(root, fop))));
+ factory.setListenerFactory(
+ new FakeInstallListenerFactory(
+ new MavenInstallListener(
+ new AndroidSdkHandler(ROOT, null, fop))));
Uninstaller uninstaller = factory.createUninstaller(p, mgr, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
uninstaller.prepare(progress);
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyLocalRepoTest.java b/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyLocalRepoTest.java
index f33e0e1..1e181fd 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyLocalRepoTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyLocalRepoTest.java
@@ -30,7 +30,6 @@
import com.android.repository.testframework.MockFileOp;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.sdklib.repository.legacy.LegacyLocalRepoLoader;
import com.android.sdklib.repository.meta.DetailsTypes;
import com.android.sdklib.repository.meta.SdkCommonFactory;
import com.google.common.collect.ImmutableList;
@@ -66,7 +65,8 @@
File root = new File("/sdk");
FakeProgressIndicator progress = new FakeProgressIndicator();
- RepoManager mgr = AndroidSdkHandler.getInstance(root).getSdkManager(progress);
+ RepoManager mgr =
+ new AndroidSdkHandler(root, null, mockFop).getSdkManager(progress);
progress.assertNoErrorsOrWarnings();
LocalRepoLoader sdk = new LocalRepoLoaderImpl(root, mgr,
@@ -94,7 +94,8 @@
FakeProgressIndicator progress = new FakeProgressIndicator();
File root = new File("/sdk");
- RepoManager mgr = new AndroidSdkHandler(root, mockFop).getSdkManager(progress);
+ RepoManager mgr =
+ new AndroidSdkHandler(root, null, mockFop).getSdkManager(progress);
progress.assertNoErrorsOrWarnings();
@@ -123,7 +124,7 @@
FakeProgressIndicator progress = new FakeProgressIndicator();
File root = new File("/sdk");
- AndroidSdkHandler sdkHandler = new AndroidSdkHandler(root, mockFop);
+ AndroidSdkHandler sdkHandler = new AndroidSdkHandler(root, null, mockFop);
SdkCommonFactory factory = AndroidSdkHandler.getCommonModule().createLatestFactory();
RepoManager mgr = sdkHandler.getSdkManager(progress);
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyRemoteTest.java b/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyRemoteTest.java
index ed3907e..b69d6bb 100755
--- a/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyRemoteTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/legacy/LegacyRemoteTest.java
@@ -15,7 +15,6 @@
*/
package com.android.sdklib.repository.legacy;
-import com.android.prefs.AndroidLocation;
import com.android.repository.Revision;
import com.android.repository.api.Channel;
import com.android.repository.api.ConstantSourceProvider;
@@ -38,6 +37,7 @@
import junit.framework.Assert;
import junit.framework.TestCase;
+import java.io.File;
import java.net.URL;
import java.util.Map;
@@ -46,9 +46,12 @@
*/
public class LegacyRemoteTest extends TestCase {
+ public static final File ANDROID_FOLDER = new File("/android-home");
+
public void testLegacyRemoteSdk() throws Exception {
MockFileOp fop = new MockFileOp();
- final AndroidSdkHandler handler = new AndroidSdkHandler(null, fop);
+ final AndroidSdkHandler handler =
+ new AndroidSdkHandler(null, ANDROID_FOLDER, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
RepoManager mgr = handler.getSdkManager(progress);
progress.assertNoErrorsOrWarnings();
@@ -67,12 +70,14 @@
FakeSettingsController settings = new FakeSettingsController(false);
LegacyRemoteRepoLoader sdk = new LegacyRemoteRepoLoader();
- sdk.setDownloadCache(new DownloadCache(fop, DownloadCache.Strategy.ONLY_CACHE, settings));
+ sdk.setDownloadCache(
+ new DownloadCache(
+ ANDROID_FOLDER, fop, DownloadCache.Strategy.ONLY_CACHE, settings));
mgr.setFallbackRemoteRepoLoader(sdk);
FakeDownloader downloader = new FakeDownloader(fop);
// TODO: find a better way to get it into the cache/have the fallback load it
fop.recordExistingFile(fop.getAgnosticAbsPath(
- AndroidLocation.getFolder() + "cache/sdkbin-1_951b49ff-test_epo"), ByteStreams
+ ANDROID_FOLDER + "/cache/sdkbin-1_951b49ff-test_epo"), ByteStreams
.toByteArray(getClass().getResourceAsStream("/repository_sample_10.xml")));
downloader.registerUrl(new URL("http://www.example.com/testRepo2"),
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCacheTest.java b/sdklib/src/test/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCacheTest.java
index 82cb888..5fce155 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCacheTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/legacy/remote/internal/DownloadCacheTest.java
@@ -16,18 +16,20 @@
package com.android.sdklib.repository.legacy.remote.internal;
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.repository.io.FileOp;
import com.android.repository.io.FileOpUtils;
import com.android.repository.testframework.FakeSettingsController;
import com.android.repository.testframework.MockFileOp;
-import com.android.sdklib.TempAndroidLocation;
import com.android.utils.Pair;
import com.google.common.base.Charsets;
+
import org.apache.http.Header;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -48,15 +50,9 @@
import java.util.Map;
import java.util.Set;
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
@RunWith(JUnit4.class)
public class DownloadCacheTest {
-
- @Rule public final TempAndroidLocation mTempAndroidLocation =
- new TempAndroidLocation("androidhome_" + getClass().getSimpleName());
-
+ private static final File ANDROID_FOLDER = new File("/android-home");
private OutputStreamMockFileOp mFileOp;
private MockMonitor mMonitor;
@@ -108,7 +104,7 @@
new HashMap<>();
public NoDownloadCache(@NonNull FileOp fileOp, @NonNull Strategy strategy) {
- super(fileOp, strategy, new FakeSettingsController(false));
+ super(ANDROID_FOLDER, fileOp, strategy, new FakeSettingsController(false));
}
@Override
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/targets/AndroidTargetManagerTest.java b/sdklib/src/test/java/com/android/sdklib/repository/targets/AndroidTargetManagerTest.java
index e96643f..df27936 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/targets/AndroidTargetManagerTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/targets/AndroidTargetManagerTest.java
@@ -17,11 +17,9 @@
import com.android.SdkConstants;
import com.android.annotations.NonNull;
-import com.android.repository.Revision;
import com.android.repository.api.LocalPackage;
import com.android.repository.api.RepoManager;
import com.android.repository.api.RepoPackage;
-import com.android.repository.impl.manager.RepoManagerImpl;
import com.android.repository.impl.meta.RepositoryPackages;
import com.android.repository.impl.meta.TypeDetails;
import com.android.repository.testframework.FakePackage;
@@ -35,7 +33,6 @@
import com.android.sdklib.repository.meta.RepoFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -65,7 +62,8 @@
recordSysImg13(fop);
recordGoogleApisSysImg23(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
AndroidTargetManager mgr = handler.getAndroidTargetManager(progress);
@@ -91,7 +89,8 @@
recordBuildTool23(fop);
recordGoogleApisSysImg23(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
AndroidTargetManager mgr = handler.getAndroidTargetManager(progress);
Collection<IAndroidTarget> targets = mgr.getTargets(progress);
@@ -112,7 +111,8 @@
recordBuildTool23(fop);
recordGoogleApisSysImg23(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
AndroidTargetManager mgr = handler.getAndroidTargetManager(progress);
Collection<IAndroidTarget> targets = mgr.getTargets(progress);
@@ -130,7 +130,8 @@
MockFileOp fop = new MockFileOp();
recordPlatform23(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
AndroidTargetManager mgr = handler.getAndroidTargetManager(progress);
IAndroidTarget target = mgr.getTargets(progress).iterator().next();
@@ -689,7 +690,8 @@
recordBuildTool23(fop);
recordBuildTool24Preview1(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
assertEquals("23.0.2", handler.getLatestBuildTool(progress, false).getRevision().toString());
@@ -706,7 +708,8 @@
// This test like testBuildTools but also adds in a final version of 24
recordBuildTool24(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
assertEquals("24.0.0", handler.getLatestBuildTool(progress, false).getRevision().toString());
@@ -733,7 +736,8 @@
Maps.uniqueIndex(locals, RepoPackage::getPath),
new HashMap<>());
RepoManager mgr = new FakeRepoManager(packages);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop, mgr);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop, mgr);
FakeProgressIndicator progress = new FakeProgressIndicator();
AndroidTargetManager targetMgr =
handler.getAndroidTargetManager(progress);
diff --git a/sdklib/src/test/java/com/android/sdklib/repository/targets/SystemImageManagerTest.java b/sdklib/src/test/java/com/android/sdklib/repository/targets/SystemImageManagerTest.java
index c27f8db..2abafaf 100644
--- a/sdklib/src/test/java/com/android/sdklib/repository/targets/SystemImageManagerTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/repository/targets/SystemImageManagerTest.java
@@ -42,7 +42,8 @@
recordSysImg23(fop);
recordGoogleApis13(fop);
- AndroidSdkHandler handler = new AndroidSdkHandler(new File("/sdk"), fop);
+ AndroidSdkHandler handler =
+ new AndroidSdkHandler(new File("/sdk"), null, fop);
FakeProgressIndicator progress = new FakeProgressIndicator();
SystemImageManager mgr = new SystemImageManager(handler.getSdkManager(progress),
diff --git a/sdklib/src/test/java/com/android/sdklib/tool/AvdManagerTest.java b/sdklib/src/test/java/com/android/sdklib/tool/AvdManagerTest.java
index e967fd5..5baa95b 100644
--- a/sdklib/src/test/java/com/android/sdklib/tool/AvdManagerTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/tool/AvdManagerTest.java
@@ -16,6 +16,7 @@
package com.android.sdklib.tool;
+import com.android.prefs.AndroidLocation;
import com.android.repository.testframework.FakeProgressIndicator;
import com.android.repository.testframework.MockFileOp;
import com.android.sdklib.internal.avd.AvdInfo;
@@ -35,6 +36,8 @@
public class AvdManagerTest extends TestCase {
+ private static final File ANDROID_HOME = new File("/android-home");
+
private AndroidSdkHandler mAndroidSdkHandler;
private AvdManager mAvdManager;
private File mAvdFolder;
@@ -48,10 +51,16 @@
mFileOp.recordExistingFile("/sdk/tools/lib/emulator/snapshots.img");
recordGoogleApisSysImg23(mFileOp);
recordSysImg23(mFileOp);
- mAndroidSdkHandler = new AndroidSdkHandler(new File("/sdk"), mFileOp);
- mAvdManager = AvdManager.getInstance(mAndroidSdkHandler, new NullLogger(), mFileOp);
- mAvdFolder = AvdInfo
- .getDefaultAvdFolder(mAvdManager, getName(), mFileOp, false);
+ mAndroidSdkHandler =
+ new AndroidSdkHandler(new File("/sdk"), ANDROID_HOME, mFileOp);
+ mAvdManager =
+ AvdManager.getInstance(
+ mAndroidSdkHandler,
+ new File(ANDROID_HOME, AndroidLocation.FOLDER_AVD),
+ new NullLogger(),
+ mFileOp);
+ mAvdFolder =
+ AvdInfo.getDefaultAvdFolder(mAvdManager, getName(), mFileOp, false);
mSystemImage = mAndroidSdkHandler.getSystemImageManager(
new FakeProgressIndicator()).getImages().iterator().next();
diff --git a/sdklib/src/test/java/com/android/sdklib/tool/SdkManagerCliTest.java b/sdklib/src/test/java/com/android/sdklib/tool/SdkManagerCliTest.java
index 10fbc96..3ef2cbf 100644
--- a/sdklib/src/test/java/com/android/sdklib/tool/SdkManagerCliTest.java
+++ b/sdklib/src/test/java/com/android/sdklib/tool/SdkManagerCliTest.java
@@ -84,7 +84,12 @@
createLocalRepo(repoManager);
- mSdkHandler = new AndroidSdkHandler(new File(SDK_LOCATION), mFileOp, repoManager);
+ mSdkHandler =
+ new AndroidSdkHandler(
+ new File(SDK_LOCATION),
+ null,
+ mFileOp,
+ repoManager);
// Doesn't actually need to provide anything, since the remote loader gets them directly.
repoManager.registerSourceProvider(new FakeRepositorySourceProvider(null));
diff --git a/testutils/BUILD b/testutils/BUILD
index 5444080..320f028 100644
--- a/testutils/BUILD
+++ b/testutils/BUILD
@@ -3,11 +3,11 @@
iml_module(
name = "studio.testutils",
srcs = ["src/main/java"],
- javacopts = ["-extra_checks:off"],
tags = ["managed"],
test_srcs = ["src/test/java"],
visibility = ["//visibility:public"],
exports = ["//tools/base/common:studio.common"],
+ # do not sort: must match IML order
deps = [
"//tools/base/common:studio.common[module]",
"//tools/idea/.idea/libraries:JUnit4",
@@ -24,18 +24,20 @@
deps = [
"//tools/base/annotations",
"//tools/base/common:tools.common",
+ "//tools/base/third_party:com.google.truth_truth",
"//tools/base/third_party:junit_junit",
"//tools/base/third_party:org.easymock_easymock",
"//tools/base/third_party:org.mockito_mockito-all",
- "//tools/base/third_party:com.google.truth_truth",
],
)
java_test(
name = "tools.tests",
srcs = glob(["src/test/java/**"]),
- javacopts = ["-extra_checks:off"],
jvm_flags = ["-Dtest.suite.jar=tools.tests.jar"],
test_class = "com.android.testutils.JarTestSuite",
- deps = [":tools.testutils"],
+ deps = [
+ ":tools.testutils",
+ "//tools/base/third_party:com.google.truth_truth",
+ ],
)
diff --git a/testutils/src/main/java/com/android/testutils/TestUtils.java b/testutils/src/main/java/com/android/testutils/TestUtils.java
index aef4a29..a4a945c 100644
--- a/testutils/src/main/java/com/android/testutils/TestUtils.java
+++ b/testutils/src/main/java/com/android/testutils/TestUtils.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertTrue;
+import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.utils.FileUtils;
import com.google.common.io.Files;
@@ -208,24 +209,6 @@
}
/**
- * Given a path to a file relative to the SDK's root, return the file.
- *
- * @throws IllegalStateException if the current OS is not supported.
- * @throws IllegalArgumentException if the path results in a file not found.
- */
- @NonNull
- public static File getSdkFile(String path) {
- OsType osType = OsType.getHostOs();
- if (osType == OsType.UNKNOWN) {
- throw new IllegalStateException(
- "SDK test not supported on unknown platform: " + OsType.getOsName());
- }
-
- String hostDir = osType.getFolderName();
- return getWorkspaceFile("prebuilts/studio/sdk/" + hostDir + (path.isEmpty() ? path : "/" + path));
- }
-
- /**
* Returns a file at {@code path} relative to the root for {@link #getLatestAndroidPlatform}.
*
* @throws IllegalStateException if the current OS is not supported.
@@ -233,7 +216,8 @@
*/
@NonNull
public static File getPlatformFile(String path) {
- return getSdkFile("platforms/" + getLatestAndroidPlatform() + "/" + path);
+ return FileUtils.join(
+ getSdk(), SdkConstants.FD_PLATFORMS, getLatestAndroidPlatform(), path);
}
/**
@@ -246,12 +230,19 @@
*/
@NonNull
public static File getSdk() {
- return getSdkFile("");
+ OsType osType = OsType.getHostOs();
+ if (osType == OsType.UNKNOWN) {
+ throw new IllegalStateException(
+ "SDK test not supported on unknown platform: " + OsType.getOsName());
+ }
+
+ String hostDir = osType.getFolderName();
+ return getWorkspaceFile("prebuilts/studio/sdk/" + hostDir);
}
@NonNull
public static String getLatestAndroidPlatform() {
- return "android-24";
+ return "android-25";
}
/**
diff --git a/testutils/src/main/java/com/android/testutils/truth/FileSubject.java b/testutils/src/main/java/com/android/testutils/truth/FileSubject.java
index 70b8009..8df9836 100644
--- a/testutils/src/main/java/com/android/testutils/truth/FileSubject.java
+++ b/testutils/src/main/java/com/android/testutils/truth/FileSubject.java
@@ -22,7 +22,6 @@
import com.google.common.truth.FailureStrategy;
import com.google.common.truth.Subject;
import com.google.common.truth.SubjectFactory;
-
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@@ -127,10 +126,6 @@
isNewerThan(other.lastModified());
}
- public void isSameAgeAs(File other) {
- wasModifiedAt(other.lastModified());
- }
-
public void contentWithUnixLineSeparatorsIsExactly(String expected) throws IOException {
if (!FileUtils.loadFileWithUnixLineSeparators(getSubject()).equals(expected)) {
fail("content is exactly", expected);
diff --git a/testutils/src/test/java/com/android/testutils/VirtualTimeSchedulerTest.java b/testutils/src/test/java/com/android/testutils/VirtualTimeSchedulerTest.java
index cab11d4..b4527b4 100644
--- a/testutils/src/test/java/com/android/testutils/VirtualTimeSchedulerTest.java
+++ b/testutils/src/test/java/com/android/testutils/VirtualTimeSchedulerTest.java
@@ -16,6 +16,8 @@
package com.android.testutils;
+import static com.google.common.truth.Truth.assertThat;
+
import junit.framework.TestCase;
import org.junit.Assert;
@@ -681,8 +683,8 @@
VirtualTimeFuture<Integer> vtf1 = (VirtualTimeFuture<Integer>) future1;
Assert.assertTrue(future2 instanceof VirtualTimeFuture);
VirtualTimeFuture<Integer> vtf2 = (VirtualTimeFuture<Integer>) future2;
- Assert.assertEquals(0, vtf1.compareTo(vtf1));
- Assert.assertEquals(-1, vtf1.compareTo(vtf2));
+ assertThat(vtf1).isEquivalentAccordingToCompareTo(vtf1);
+ assertThat(vtf1).isLessThan(vtf2);
// Ensure the jobs result is as expected.
Assert.assertEquals(3, (int) future1.get(1, TimeUnit.MINUTES));