aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@google.com>2013-11-14 23:40:00 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-11-14 23:40:00 +0000
commit442c4711c9e2856bfb98e2f805e7d3a249f593ee (patch)
tree55bbba664328e96d42948744930c42a54c26a32c
parent984c1a5a52b0b962f903e73106e0c32cf18fd38f (diff)
parent4204c184b20dbbe7b81f06ca8f21605aa0cbc9e6 (diff)
downloadbuild-442c4711c9e2856bfb98e2f805e7d3a249f593ee.tar.gz
Merge "Support for jni lib in library project."
-rw-r--r--.gitignore1
-rw-r--r--builder-model/src/main/java/com/android/builder/NdkConfig.java51
-rw-r--r--builder-model/src/main/java/com/android/builder/model/BuildType.java4
-rw-r--r--builder-model/src/main/java/com/android/builder/model/ProductFlavor.java4
-rw-r--r--builder/src/main/java/com/android/builder/DefaultBuildType.java6
-rw-r--r--builder/src/main/java/com/android/builder/DefaultProductFlavor.java7
-rw-r--r--builder/src/main/java/com/android/builder/VariantConfiguration.java54
-rw-r--r--builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java93
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy35
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy59
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy36
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy12
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java35
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy8
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java7
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java43
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy48
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy17
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy11
-rw-r--r--tests/ndkJniLib/app/build.gradle28
-rw-r--r--tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java29
-rw-r--r--tests/ndkJniLib/app/src/main/AndroidManifest.xml11
-rw-r--r--tests/ndkJniLib/app/src/main/res/values/strings.xml4
-rw-r--r--tests/ndkJniLib/build.gradle8
-rw-r--r--tests/ndkJniLib/lib/build.gradle12
-rw-r--r--tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java29
-rw-r--r--tests/ndkJniLib/lib/src/main/AndroidManifest.xml15
-rw-r--r--tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java54
-rw-r--r--tests/ndkJniLib/lib/src/main/jni/hello-jni.c72
-rw-r--r--tests/ndkJniLib/lib/src/main/res/values/strings.xml4
-rw-r--r--tests/ndkJniLib/settings.gradle1
-rw-r--r--tests/rsSupportMode/build.gradle2
32 files changed, 651 insertions, 149 deletions
diff --git a/.gitignore b/.gitignore
index ffc527f..87388fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ tests/libProguardLibDep/*/build
tests/libsTest/*/build
tests/multiproject/*/build
tests/localJars/*/build
+tests/ndkJniLib/*/build
tests/proguardLib/*/build
tests/renderscriptInLib/*/build
tests/repo/*/build
diff --git a/builder-model/src/main/java/com/android/builder/NdkConfig.java b/builder-model/src/main/java/com/android/builder/NdkConfig.java
new file mode 100644
index 0000000..b3bebef
--- /dev/null
+++ b/builder-model/src/main/java/com/android/builder/NdkConfig.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 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;
+
+import com.android.annotations.Nullable;
+
+import java.util.Set;
+
+/**
+ * Base class for NDK config file.
+ */
+public interface NdkConfig {
+
+ /**
+ * The module name
+ */
+ @Nullable
+ public String getModuleName();
+
+ /**
+ * The C Flags
+ */
+ @Nullable
+ public String getcFlags();
+
+ /**
+ * The LD Libs
+ */
+ @Nullable
+ public String getLdLibs();
+
+ /**
+ * The ABI Filters
+ */
+ @Nullable
+ public Set<String> getAbiFilters();
+}
diff --git a/builder-model/src/main/java/com/android/builder/model/BuildType.java b/builder-model/src/main/java/com/android/builder/model/BuildType.java
index 33d9ada..d846a90 100644
--- a/builder-model/src/main/java/com/android/builder/model/BuildType.java
+++ b/builder-model/src/main/java/com/android/builder/model/BuildType.java
@@ -18,6 +18,7 @@ package com.android.builder.model;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.builder.NdkConfig;
/**
* a Build Type. This is only the configuration of the build type.
@@ -97,4 +98,7 @@ public interface BuildType extends BaseConfig {
* @return true if zipalign is enabled.
*/
boolean isZipAlign();
+
+ @Nullable
+ NdkConfig getNdkConfig();
}
diff --git a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java
index f281f8e..9563136 100644
--- a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java
+++ b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java
@@ -18,6 +18,7 @@ package com.android.builder.model;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.builder.NdkConfig;
/**
* a Product Flavor. This is only the configuration of the flavor.
@@ -125,4 +126,7 @@ public interface ProductFlavor extends BaseConfig {
*/
@Nullable
Boolean getTestFunctionalTest();
+
+ @Nullable
+ NdkConfig getNdkConfig();
}
diff --git a/builder/src/main/java/com/android/builder/DefaultBuildType.java b/builder/src/main/java/com/android/builder/DefaultBuildType.java
index 5ebbd0b..f9ed1be 100644
--- a/builder/src/main/java/com/android/builder/DefaultBuildType.java
+++ b/builder/src/main/java/com/android/builder/DefaultBuildType.java
@@ -162,6 +162,12 @@ public class DefaultBuildType extends BaseConfigImpl implements BuildType {
}
@Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return null;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
diff --git a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java
index f739a3f..e4f6e18 100644
--- a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java
+++ b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java
@@ -217,6 +217,12 @@ public class DefaultProductFlavor extends BaseConfigImpl implements ProductFlavo
return this;
}
+ @Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return null;
+ }
+
/**
* Merges the flavor on top of a base platform and returns a new object with the result.
* @param base the flavor to merge on top of
@@ -359,5 +365,4 @@ public class DefaultProductFlavor extends BaseConfigImpl implements ProductFlavo
release signing info (keystore, key alias, passwords,...).
native abi filter
*/
-
}
diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java
index a5978d4..72fbf9a 100644
--- a/builder/src/main/java/com/android/builder/VariantConfiguration.java
+++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java
@@ -22,6 +22,7 @@ import com.android.annotations.VisibleForTesting;
import com.android.builder.dependency.DependencyContainer;
import com.android.builder.dependency.JarDependency;
import com.android.builder.dependency.LibraryDependency;
+import com.android.builder.internal.NdkConfigImpl;
import com.android.builder.model.SigningConfig;
import com.android.builder.model.SourceProvider;
import com.android.builder.testing.TestData;
@@ -64,6 +65,7 @@ public class VariantConfiguration implements TestData {
private LibraryDependency mOutput;
private DefaultProductFlavor mMergedFlavor;
+ private final NdkConfigImpl mMergedNdkConfig = new NdkConfigImpl();
private final Set<JarDependency> mJars = Sets.newHashSet();
@@ -104,7 +106,7 @@ public class VariantConfiguration implements TestData {
@NonNull DefaultProductFlavor defaultConfig,
@NonNull SourceProvider defaultSourceProvider,
@NonNull DefaultBuildType buildType,
- @NonNull SourceProvider buildTypeSourceProvider,
+ @Nullable SourceProvider buildTypeSourceProvider,
@Nullable String debugName) {
this(defaultConfig, defaultSourceProvider,
buildType, buildTypeSourceProvider,
@@ -164,6 +166,7 @@ public class VariantConfiguration implements TestData {
checkState(mType != Type.TEST || mTestedConfig != null);
mMergedFlavor = mDefaultConfig;
+ computeNdkConfig();
if (testedConfig != null &&
testedConfig.mType == Type.LIBRARY &&
@@ -181,7 +184,9 @@ public class VariantConfiguration implements TestData {
* comes to resolving Android resources overlays (ie earlier added flavors supersedes
* latter added ones).
*
- * @param sourceProvider the configured product flavor
+ * @param productFlavor the configured product flavor
+ * @param sourceProvider
+ *
* @return the config object
*/
@NonNull
@@ -189,11 +194,32 @@ public class VariantConfiguration implements TestData {
@NonNull SourceProvider sourceProvider) {
mFlavorConfigs.add(productFlavor);
mFlavorSourceProviders.add(sourceProvider);
+
mMergedFlavor = productFlavor.mergeOver(mMergedFlavor);
+ computeNdkConfig();
return this;
}
+ private void computeNdkConfig() {
+ mMergedNdkConfig.reset();
+
+ if (mDefaultConfig.getNdkConfig() != null) {
+ mMergedNdkConfig.append(mDefaultConfig.getNdkConfig());
+ }
+
+ for (int i = mFlavorConfigs.size() - 1 ; i >= 0 ; i--) {
+ NdkConfig ndkConfig = mFlavorConfigs.get(i).getNdkConfig();
+ if (ndkConfig != null) {
+ mMergedNdkConfig.append(ndkConfig);
+ }
+ }
+
+ if (mBuildType.getNdkConfig() != null && mType != Type.TEST) {
+ mMergedNdkConfig.append(mBuildType.getNdkConfig());
+ }
+ }
+
/**
* Sets the dependencies
*
@@ -721,6 +747,21 @@ public class VariantConfiguration implements TestData {
return assetSets;
}
+ @NonNull
+ public List<File> getLibraryJniFolders() {
+ List<File> list = Lists.newArrayListWithExpectedSize(mFlatLibraries.size());
+
+ for (int n = mFlatLibraries.size() - 1 ; n >= 0 ; n--) {
+ LibraryDependency dependency = mFlatLibraries.get(n);
+ File jniFolder = dependency.getJniFolder();
+ if (jniFolder.isDirectory()) {
+ list.add(jniFolder);
+ }
+ }
+
+ return list;
+ }
+
/**
* Returns all the renderscript import folder that are outside of the current project.
*/
@@ -944,11 +985,18 @@ public class VariantConfiguration implements TestData {
}
}
+ @NonNull
+ public NdkConfig getNdkConfig() {
+ return mMergedNdkConfig;
+ }
@Nullable
@Override
public Set<String> getSupportedAbis() {
- // TODO no ndk support yet, so return null
+ if (mMergedNdkConfig != null) {
+ return mMergedNdkConfig.getAbiFilters();
+ }
+
return null;
}
}
diff --git a/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java
new file mode 100644
index 0000000..d4e8b4e
--- /dev/null
+++ b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 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;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.builder.NdkConfig;
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ */
+public class NdkConfigImpl implements NdkConfig {
+
+ private String moduleName;
+ private String cFlags;
+ private String ldLibs;
+ private Set<String> abiFilters;
+
+ public void reset() {
+ moduleName = null;
+ cFlags = null;
+ ldLibs = null;
+ abiFilters = null;
+ }
+
+ @Override
+ @Nullable
+ public String getModuleName() {
+ return moduleName;
+ }
+
+ @Override
+ @Nullable
+ public String getcFlags() {
+ return cFlags;
+ }
+
+ @Override
+ @Nullable
+ public String getLdLibs() {
+ return ldLibs;
+ }
+
+ @Override
+ @Nullable
+ public Set<String> getAbiFilters() {
+ return abiFilters;
+ }
+
+ public void append(@NonNull NdkConfig ndkConfig) {
+ // override
+ if (ndkConfig.getModuleName() != null) {
+ moduleName = ndkConfig.getModuleName();
+ }
+ if (ndkConfig.getAbiFilters() != null) {
+ if (abiFilters == null) {
+ abiFilters = Sets.newHashSetWithExpectedSize(ndkConfig.getAbiFilters().size());
+ } else {
+ abiFilters.clear();
+ }
+ abiFilters.addAll(ndkConfig.getAbiFilters());
+ }
+
+ // append
+ if (cFlags == null) {
+ cFlags = ndkConfig.getcFlags();
+ } else if (ndkConfig.getcFlags() != null) {
+ cFlags = cFlags + " " + ndkConfig.getcFlags();
+ }
+
+ if (ldLibs == null) {
+ ldLibs = ndkConfig.getLdLibs();
+ } else if (ndkConfig.getLdLibs() != null) {
+ ldLibs = ldLibs + " " + ndkConfig.getLdLibs();
+ }
+ }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
index 7367c00..77e9807 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
@@ -15,7 +15,6 @@
*/
package com.android.build.gradle
-
import com.android.annotations.NonNull
import com.android.annotations.Nullable
import com.android.build.gradle.api.BaseVariant
@@ -57,7 +56,6 @@ import static com.android.builder.BuilderConstants.INSTRUMENT_TEST
import static com.android.builder.BuilderConstants.LINT
import static com.android.builder.BuilderConstants.RELEASE
import static com.android.builder.BuilderConstants.UI_TEST
-
/**
* Gradle plugin class for 'application' projects.
*/
@@ -295,8 +293,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr
for (BuildTypeData buildTypeData : buildTypes.values()) {
def variantConfig = new VariantConfiguration(
- defaultConfigData.productFlavor, defaultConfigData.sourceSet,
- buildTypeData.buildType, buildTypeData.sourceSet, project.name)
+ defaultConfigData.productFlavor,
+ defaultConfigData.sourceSet,
+ buildTypeData.buildType,
+ buildTypeData.sourceSet, project.name)
// create the variant and get its internal storage object.
ApplicationVariantData appVariantData = new ApplicationVariantData(variantConfig)
@@ -315,8 +315,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr
// handle the test variant
def testVariantConfig = new VariantConfiguration(
- defaultConfigData.productFlavor, defaultConfigData.testSourceSet,
- testData.buildType, null,
+ defaultConfigData.productFlavor,
+ defaultConfigData.testSourceSet,
+ testData.buildType,
+ null,
VariantConfiguration.Type.TEST, testedVariantData.variantConfiguration,
project.name)
@@ -429,11 +431,16 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr
variantProviders.add(buildTypeData)
VariantConfiguration variantConfig = new VariantConfiguration(
- extension.defaultConfig, getDefaultConfigData().sourceSet,
- buildTypeData.buildType, buildTypeData.sourceSet, project.name)
+ extension.defaultConfig,
+ getDefaultConfigData().sourceSet,
+ buildTypeData.buildType,
+ buildTypeData.sourceSet,
+ project.name)
for (ProductFlavorData data : flavorDataList) {
- variantConfig.addProductFlavor(data.productFlavor, data.sourceSet)
+ variantConfig.addProductFlavor(
+ data.productFlavor,
+ data.sourceSet)
variantProviders.add(data.mainProvider)
}
@@ -458,8 +465,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr
// handle test variant
VariantConfiguration testVariantConfig = new VariantConfiguration(
- extension.defaultConfig, getDefaultConfigData().testSourceSet,
- testData.buildType, null,
+ extension.defaultConfig,
+ getDefaultConfigData().testSourceSet,
+ testData.buildType,
+ null,
VariantConfiguration.Type.TEST,
testedVariantData.variantConfiguration, project.name)
@@ -469,7 +478,9 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr
List<ConfigurationProvider> testVariantProviders = []
for (ProductFlavorData data : flavorDataList) {
- testVariantConfig.addProductFlavor(data.productFlavor, data.testSourceSet)
+ testVariantConfig.addProductFlavor(
+ data.productFlavor,
+ data.testSourceSet)
testVariantProviders.add(data.testProvider)
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
index bf799a6..b8a6c1d 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
@@ -15,7 +15,6 @@
*/
package com.android.build.gradle
-
import com.android.annotations.NonNull
import com.android.annotations.Nullable
import com.android.build.gradle.api.AndroidSourceSet
@@ -29,7 +28,6 @@ import com.android.build.gradle.internal.dependency.LibraryDependencyImpl
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl
import com.android.build.gradle.internal.dependency.SymbolFileProviderImpl
import com.android.build.gradle.internal.dependency.VariantDependencies
-import com.android.build.gradle.internal.dsl.NdkConfigDsl
import com.android.build.gradle.internal.dsl.SigningConfigDsl
import com.android.build.gradle.internal.model.ModelBuilder
import com.android.build.gradle.internal.tasks.AndroidReportTask
@@ -123,7 +121,6 @@ import static com.android.builder.BuilderConstants.FD_INSTRUMENT_TESTS
import static com.android.builder.BuilderConstants.FD_REPORTS
import static com.android.builder.BuilderConstants.INSTRUMENT_TEST
import static java.io.File.separator
-
/**
* Base class for all Android plugins
*/
@@ -464,24 +461,7 @@ public abstract class BasePlugin {
renderscriptTask.conventionMapping.libOutputDir = {
project.file("$project.buildDir/rs/$variantData.dirName/lib")
}
- renderscriptTask.conventionMapping.ndkConfig = {
-
- //noinspection GroovyAssignabilityCheck
- NdkConfigDsl mergedConfig = new NdkConfigDsl(config.defaultConfig.ndkConfig)
- if (config.hasFlavors()) {
- for (DefaultProductFlavor flavorConfig : config.flavorConfigs) {
- //noinspection GroovyAssignabilityCheck
- mergedConfig.append(flavorConfig.ndkConfig)
- }
- }
- if (config.getType() != VariantConfiguration.Type.TEST) {
- //noinspection GroovyAssignabilityCheck
- mergedConfig.append(config.buildType.ndkConfig)
- }
-
- return mergedConfig
- }
-
+ renderscriptTask.conventionMapping.ndkConfig = { config.ndkConfig }
}
protected void createMergeResourcesTask(@NonNull BaseVariantData variantData,
@@ -750,6 +730,14 @@ public abstract class BasePlugin {
}
protected void createNdkTasks(@NonNull BaseVariantData variantData) {
+ createNdkTasks(
+ variantData,
+ { project.file("$project.buildDir/ndk/$variantData.dirName/lib") }
+ )
+ }
+
+ protected void createNdkTasks(@NonNull BaseVariantData variantData,
+ @NonNull Closure<File> soFolderClosure) {
NdkCompile ndkCompile = project.tasks.create(
"compile${variantData.name}Ndk", NdkCompile)
@@ -781,23 +769,7 @@ public abstract class BasePlugin {
project.file("$project.buildDir/ndk/$variantData.dirName/Android.mk")
}
- ndkCompile.conventionMapping.ndkConfig = {
-
- //noinspection GroovyAssignabilityCheck
- NdkConfigDsl mergedConfig = new NdkConfigDsl(variantConfig.defaultConfig.ndkConfig)
- if (variantConfig.hasFlavors()) {
- for (DefaultProductFlavor flavorConfig : variantConfig.flavorConfigs) {
- //noinspection GroovyAssignabilityCheck
- mergedConfig.append(flavorConfig.ndkConfig)
- }
- }
- if (variantConfig.getType() != VariantConfiguration.Type.TEST) {
- //noinspection GroovyAssignabilityCheck
- mergedConfig.append(variantConfig.buildType.ndkConfig)
- }
-
- return mergedConfig
- }
+ ndkCompile.conventionMapping.ndkConfig = { variantConfig.ndkConfig }
ndkCompile.conventionMapping.debuggable = {
variantConfig.buildType.jniDebugBuild
@@ -806,10 +778,7 @@ public abstract class BasePlugin {
ndkCompile.conventionMapping.objFolder = {
project.file("$project.buildDir/ndk/$variantData.dirName/obj")
}
-
- ndkCompile.conventionMapping.soFolder = {
- project.file("$project.buildDir/ndk/$variantData.dirName/lib")
- }
+ ndkCompile.conventionMapping.soFolder = soFolderClosure
}
/**
@@ -1278,10 +1247,10 @@ public abstract class BasePlugin {
}
packageApp.conventionMapping.jniFolders = {
// for now only the project's compilation output.
- // TODO add dependencies
Set<File> set = Sets.newHashSet()
set.addAll(variantData.ndkCompileTask.soFolder)
set.addAll(variantData.renderscriptCompileTask.libOutputDir)
+ set.addAll(variantConfig.libraryJniFolders)
if (variantConfig.mergedFlavor.renderscriptSupportMode) {
File rsLibs = getAndroidBuilder(variantData).getSupportNativeLibFolder()
@@ -1292,9 +1261,7 @@ public abstract class BasePlugin {
return set
}
- packageApp.conventionMapping.abiFilters = {
- variantData.ndkCompileTask.getNdkConfig().abiFilters
- }
+ packageApp.conventionMapping.abiFilters = { variantConfig.supportedAbis }
packageApp.conventionMapping.jniDebugBuild = { variantConfig.buildType.jniDebugBuild }
SigningConfigDsl sc = (SigningConfigDsl) variantConfig.signingConfig
diff --git a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
index c45a827..69c7c2f 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package com.android.build.gradle
-
import com.android.SdkConstants
import com.android.annotations.NonNull
import com.android.annotations.Nullable
@@ -55,7 +54,6 @@ import org.gradle.tooling.BuildException
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import javax.inject.Inject
-
/**
* Gradle plugin class for 'library' projects.
*/
@@ -137,10 +135,13 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
createLibraryVariant(releaseVariantData, true)
VariantConfiguration testVariantConfig = new VariantConfiguration(
- defaultConfigData.productFlavor, defaultConfigData.testSourceSet,
- debugBuildTypeData.buildType, null,
+ defaultConfigData.productFlavor,
+ defaultConfigData.testSourceSet,
+ debugBuildTypeData.buildType,
+ null,
VariantConfiguration.Type.TEST,
- debugVariantData.variantConfiguration, project.name)
+ debugVariantData.variantConfiguration,
+ project.name)
TestVariantData testVariantData = new TestVariantData(testVariantConfig, debugVariantData)
// link the testVariant to the tested variant in the other direction
@@ -168,9 +169,12 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
protected LibraryVariantData createLibVariant(@NonNull ProductFlavorData configData,
@NonNull BuildTypeData buildTypeData) {
VariantConfiguration variantConfig = new VariantConfiguration(
- configData.productFlavor, configData.sourceSet,
- buildTypeData.buildType, buildTypeData.sourceSet,
- VariantConfiguration.Type.LIBRARY, project.name)
+ configData.productFlavor,
+ configData.sourceSet,
+ buildTypeData.buildType,
+ buildTypeData.sourceSet,
+ VariantConfiguration.Type.LIBRARY,
+ project.name)
LibraryVariantData variantData = new LibraryVariantData(variantConfig)
@@ -233,7 +237,9 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
createCompileTask(variantData, null/*testedVariant*/)
// Add NDK tasks
- createNdkTasks(variantData)
+ createNdkTasks(
+ variantData,
+ { project.file("$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/jni") });
// package the aidl files into the bundle folder
Sync packageAidl = project.tasks.create("package${variantData.name}Aidl", Sync)
@@ -251,11 +257,11 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
"$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.FD_RENDERSCRIPT"))
// merge consumer proguard files from different build types and flavors
- MergeFileTask mergeFileTask = project.tasks.create("merge${variantData.name}ProguardFiles",
+ MergeFileTask mergeProGuardFileTask = project.tasks.create("merge${variantData.name}ProguardFiles",
MergeFileTask)
- mergeFileTask.conventionMapping.inputFiles = {
+ mergeProGuardFileTask.conventionMapping.inputFiles = {
project.files(variantConfig.getConsumerProguardFiles()).files }
- mergeFileTask.conventionMapping.outputFile = {
+ mergeProGuardFileTask.conventionMapping.outputFile = {
project.file(
"$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$LibraryBundle.FN_PROGUARD_TXT")
}
@@ -273,9 +279,9 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
createProguardTasks(variantData, variantConfig)
// hack since bundle can't depend on variantData.proguardTask
- mergeFileTask.dependsOn variantData.proguardTask
+ mergeProGuardFileTask.dependsOn variantData.proguardTask
- bundle.dependsOn packageRes, packageAidl, packageRenderscript, mergeFileTask, lintCopy
+ bundle.dependsOn packageRes, packageAidl, packageRenderscript, mergeProGuardFileTask, lintCopy, variantData.ndkCompileTask
} else {
Sync packageLocalJar = project.tasks.create("package${variantData.name}LocalJar", Sync)
packageLocalJar.from(getLocalJarFileList(variantData.variantDependency))
@@ -304,7 +310,7 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
jar.exclude(packageName + "/BuildConfig.class")
bundle.dependsOn packageRes, jar, packageAidl, packageRenderscript, packageLocalJar,
- mergeFileTask, lintCopy
+ mergeProGuardFileTask, lintCopy, variantData.ndkCompileTask
}
bundle.setDescription("Assembles a bundle containing the library in ${variantData.name}.");
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
index 8a3cf68..ed4f651 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
@@ -16,8 +16,10 @@
package com.android.build.gradle.internal.dsl
import com.android.annotations.NonNull
+import com.android.annotations.Nullable
import com.android.builder.BuilderConstants
import com.android.builder.DefaultBuildType
+import com.android.builder.NdkConfig
import com.android.builder.model.SigningConfig
import org.gradle.api.Action
import org.gradle.api.internal.file.FileResolver
@@ -42,6 +44,12 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable {
ndkConfig = instantiator.newInstance(NdkConfigDsl.class)
}
+ @Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return ndkConfig;
+ }
+
public void init(SigningConfig debugSigningConfig) {
if (BuilderConstants.DEBUG.equals(getName())) {
setDebuggable(true)
@@ -63,10 +71,6 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable {
return true
}
- public NdkConfigDsl getNdkConfig() {
- return ndkConfig
- }
-
// -- DSL Methods. TODO remove once the instantiator does what I expect it to do.
public void buildConfig(String... lines) {
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java
index 8765f3b..84476bd 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java
@@ -17,6 +17,7 @@
package com.android.build.gradle.internal.dsl;
import com.android.annotations.NonNull;
+import com.android.builder.NdkConfig;
import com.google.common.collect.Sets;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
@@ -27,7 +28,7 @@ import java.util.Set;
/**
*/
-public class NdkConfigDsl implements Serializable {
+public class NdkConfigDsl implements NdkConfig, Serializable {
private static final long serialVersionUID = 1L;
private String moduleName;
@@ -45,6 +46,7 @@ public class NdkConfigDsl implements Serializable {
setSrcDirs(ndkConfig.abiFilters);
}
+ @Override
@Input @Optional
public String getModuleName() {
return moduleName;
@@ -54,6 +56,7 @@ public class NdkConfigDsl implements Serializable {
this.moduleName = moduleName;
}
+ @Override
@Input @Optional
public String getcFlags() {
return cFlags;
@@ -63,6 +66,7 @@ public class NdkConfigDsl implements Serializable {
this.cFlags = cFlags;
}
+ @Override
@Input @Optional
public String getLdLibs() {
return ldLibs;
@@ -72,6 +76,7 @@ public class NdkConfigDsl implements Serializable {
this.ldLibs = ldLibs;
}
+ @Override
@Input @Optional
public Set<String> getAbiFilters() {
return abiFilters;
@@ -111,32 +116,4 @@ public class NdkConfigDsl implements Serializable {
}
return this;
}
-
- public void append(@NonNull NdkConfigDsl ndkConfig) {
- // override
- if (ndkConfig.moduleName != null) {
- moduleName = ndkConfig.moduleName;
- }
- if (ndkConfig.abiFilters != null) {
- if (abiFilters == null) {
- abiFilters = Sets.newHashSetWithExpectedSize(ndkConfig.abiFilters.size());
- } else {
- abiFilters.clear();
- }
- abiFilters.addAll(ndkConfig.abiFilters);
- }
-
- // append
- if (cFlags == null) {
- cFlags = ndkConfig.cFlags;
- } else if (ndkConfig.cFlags != null) {
- cFlags = cFlags + " " + ndkConfig.cFlags;
- }
-
- if (ldLibs == null) {
- ldLibs = ndkConfig.ldLibs;
- } else if (ndkConfig.ldLibs != null) {
- ldLibs = ldLibs + " " + ndkConfig.ldLibs;
- }
- }
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
index daeb0ff..6b78c86 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
@@ -16,7 +16,9 @@
package com.android.build.gradle.internal.dsl
import com.android.annotations.NonNull
+import com.android.annotations.Nullable
import com.android.builder.DefaultProductFlavor
+import com.android.builder.NdkConfig
import org.gradle.api.Action
import org.gradle.api.internal.file.FileResolver
import org.gradle.internal.reflect.Instantiator
@@ -40,8 +42,10 @@ class ProductFlavorDsl extends DefaultProductFlavor {
ndkConfig = instantiator.newInstance(NdkConfigDsl.class)
}
- public NdkConfigDsl getNdkConfig() {
- return ndkConfig
+ @Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return ndkConfig;
}
// -- DSL Methods. TODO remove once the instantiator does what I expect it to do.
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
index 11b387d..03daa6f 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
@@ -18,6 +18,7 @@ package com.android.build.gradle.internal.model;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.builder.NdkConfig;
import com.android.builder.model.BuildType;
import java.io.File;
@@ -126,4 +127,10 @@ class BuildTypeImpl implements BuildType, Serializable {
public List<File> getConsumerProguardFiles() {
return Collections.emptyList();
}
+
+ @Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return null;
+ }
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
index 8dabb11..d03ae14 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
@@ -18,6 +18,7 @@ package com.android.build.gradle.internal.model;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.builder.NdkConfig;
import com.android.builder.model.ProductFlavor;
import java.io.File;
@@ -138,23 +139,6 @@ class ProductFlavorImpl implements ProductFlavor, Serializable {
return mTestFunctionalTest;
}
- @Override
- public String toString() {
- return "ProductFlavorImpl{" +
- "name='" + name + '\'' +
- ", mMinSdkVersion=" + mMinSdkVersion +
- ", mTargetSdkVersion=" + mTargetSdkVersion +
- ", mRenderscriptTargetApi=" + mRenderscriptTargetApi +
- ", mRenderscriptSupportMode=" + mRenderscriptSupportMode +
- ", mVersionCode=" + mVersionCode +
- ", mVersionName='" + mVersionName + '\'' +
- ", mPackageName='" + mPackageName + '\'' +
- ", mTestPackageName='" + mTestPackageName + '\'' +
- ", mTestInstrumentationRunner='" + mTestInstrumentationRunner + '\'' +
- ", mTestHandleProfiling='" + mTestHandleProfiling + '\'' +
- ", mTestFunctionalTest='" + mTestFunctionalTest + '\'' +
- '}';
- }
@NonNull
@Override
@@ -173,4 +157,29 @@ class ProductFlavorImpl implements ProductFlavor, Serializable {
public List<File> getConsumerProguardFiles() {
return Collections.emptyList();
}
+
+ @Override
+ @Nullable
+ public NdkConfig getNdkConfig() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "ProductFlavorImpl{" +
+ "name='" + name + '\'' +
+ ", mMinSdkVersion=" + mMinSdkVersion +
+ ", mTargetSdkVersion=" + mTargetSdkVersion +
+ ", mRenderscriptTargetApi=" + mRenderscriptTargetApi +
+ ", mRenderscriptSupportMode=" + mRenderscriptSupportMode +
+ ", mVersionCode=" + mVersionCode +
+ ", mVersionName='" + mVersionName + '\'' +
+ ", mPackageName='" + mPackageName + '\'' +
+ ", mTestPackageName='" + mTestPackageName + '\'' +
+ ", mTestInstrumentationRunner='" + mTestInstrumentationRunner + '\'' +
+ ", mTestHandleProfiling='" + mTestHandleProfiling + '\'' +
+ ", mTestFunctionalTest='" + mTestFunctionalTest + '\'' +
+ '}';
+ }
+
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy
new file mode 100644
index 0000000..a051aed
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 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.builder.NdkConfig
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Optional
+
+/**
+ * Base task for tasks that require an NdkConfig
+ */
+class NdkTask extends BaseTask {
+
+ NdkConfig ndkConfig
+
+ @Input @Optional
+ String getModuleName() {
+ return getNdkConfig()?.moduleName;
+ }
+
+ @Input @Optional
+ String getcFlags() {
+ return getNdkConfig()?.cFlags;
+ }
+
+ @Input @Optional
+ String getLdLibs() {
+ return getNdkConfig()?.ldLibs;
+ }
+
+ @Input @Optional
+ Set<String> getAbiFilters() {
+ return getNdkConfig()?.abiFilters;
+ }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy
index ab38543..0a8e9b8 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy
@@ -17,8 +17,8 @@
package com.android.build.gradle.tasks
import com.android.annotations.NonNull
-import com.android.build.gradle.internal.dsl.NdkConfigDsl
-import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.tasks.NdkTask
+import com.android.builder.NdkConfig
import com.android.sdklib.IAndroidTarget
import com.google.common.base.Charsets
import com.google.common.base.Joiner
@@ -28,25 +28,20 @@ import org.gradle.api.GradleException
import org.gradle.api.file.FileTree
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.gradle.api.tasks.util.PatternSet
-
/**
*/
-class NdkCompile extends BaseTask {
+class NdkCompile extends NdkTask {
Set<File> sourceFolders
@OutputFile
File generatedMakefile
- @Nested
- NdkConfigDsl ndkConfig
-
@Input
boolean debuggable
@@ -57,7 +52,7 @@ class NdkCompile extends BaseTask {
File objFolder
@InputFiles
- public FileTree getSource() {
+ FileTree getSource() {
FileTree src = null
Set<File> sources = getSourceFolders()
if (!sources.isEmpty()) {
@@ -117,7 +112,7 @@ class NdkCompile extends BaseTask {
}
private void writeMakefile(@NonNull Set<File> sourceFiles, @NonNull File makefile) {
- NdkConfigDsl ndk = getNdkConfig()
+ NdkConfig ndk = getNdkConfig()
StringBuilder sb = new StringBuilder()
@@ -148,7 +143,7 @@ class NdkCompile extends BaseTask {
}
private void runNdkBuild(@NonNull File ndkLocation, @NonNull File makefile) {
- NdkConfigDsl ndk = getNdkConfig()
+ NdkConfig ndk = getNdkConfig()
List<String> commands = Lists.newArrayList()
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
index c7a748e..17985fc 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
@@ -16,17 +16,15 @@
package com.android.build.gradle.tasks
-import com.android.build.gradle.internal.dsl.NdkConfigDsl
-import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.tasks.NdkTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
/**
* Task to compile Renderscript files. Supports incremental update.
*/
-public class RenderscriptCompile extends BaseTask {
+public class RenderscriptCompile extends NdkTask {
// ----- PUBLIC TASK API -----
@@ -63,9 +61,6 @@ public class RenderscriptCompile extends BaseTask {
@Input
boolean debugBuild
- @Nested
- NdkConfigDsl ndkConfig
-
@TaskAction
void taskAction() {
// this is full run (always), clean the previous outputs
@@ -97,6 +92,6 @@ public class RenderscriptCompile extends BaseTask {
getDebugBuild(),
getOptimLevel(),
getSupportMode(),
- getNdkConfig().abiFilters)
+ getNdkConfig()?.abiFilters)
}
}
diff --git a/tests/ndkJniLib/app/build.gradle b/tests/ndkJniLib/app/build.gradle
new file mode 100644
index 0000000..0c26b2a
--- /dev/null
+++ b/tests/ndkJniLib/app/build.gradle
@@ -0,0 +1,28 @@
+apply plugin: 'android'
+
+dependencies {
+ compile project(':lib')
+}
+
+android {
+ compileSdkVersion 15
+ buildToolsVersion "18.0.1"
+
+ productFlavors {
+ x86 {
+ ndk {
+ abiFilter "x86"
+ }
+ }
+ arm {
+ ndk {
+ abiFilter "armeabi-v7a"
+ }
+ }
+ mips {
+ ndk {
+ abiFilter "mips"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java b/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java
new file mode 100644
index 0000000..feadc72
--- /dev/null
+++ b/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java
@@ -0,0 +1,29 @@
+package com.example.hellojni.lib;
+
+import android.test.ActivityInstrumentationTestCase;
+
+/**
+ * This is a simple framework for a test of an Application. See
+ * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
+ * how to write and extend Application tests.
+ * <p/>
+ * To run this test, you can type:
+ * adb shell am instrument -w \
+ * -e class com.example.hellojni.HelloJniTest \
+ * com.example.hellojni.tests/android.test.InstrumentationTestRunner
+ */
+public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> {
+
+ public HelloJniTest() {
+ super("com.example.hellojni", HelloJni.class);
+ }
+
+
+ public void testJniName() {
+ final HelloJni a = getActivity();
+ // ensure a valid handle to the activity has been returned
+ assertNotNull(a);
+
+ assertFalse("unknown".equals(a.jniNameFromJNI()));
+ }
+}
diff --git a/tests/ndkJniLib/app/src/main/AndroidManifest.xml b/tests/ndkJniLib/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..aae7f79
--- /dev/null
+++ b/tests/ndkJniLib/app/src/main/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.hellojni.app"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="3" />
+
+ <application android:label="@string/app_name">
+ </application>
+</manifest>
diff --git a/tests/ndkJniLib/app/src/main/res/values/strings.xml b/tests/ndkJniLib/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c526073
--- /dev/null
+++ b/tests/ndkJniLib/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">HelloJni</string>
+</resources>
diff --git a/tests/ndkJniLib/build.gradle b/tests/ndkJniLib/build.gradle
new file mode 100644
index 0000000..b899f9a
--- /dev/null
+++ b/tests/ndkJniLib/build.gradle
@@ -0,0 +1,8 @@
+buildscript {
+ repositories {
+ maven { url '../../../../out/host/gradle/repo' }
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.7.0-SNAPSHOT'
+ }
+}
diff --git a/tests/ndkJniLib/lib/build.gradle b/tests/ndkJniLib/lib/build.gradle
new file mode 100644
index 0000000..5d18344
--- /dev/null
+++ b/tests/ndkJniLib/lib/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'android-library'
+
+android {
+ compileSdkVersion 15
+ buildToolsVersion "18.0.1"
+
+ defaultConfig {
+ ndk {
+ moduleName "hello-jni"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java b/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java
new file mode 100644
index 0000000..feadc72
--- /dev/null
+++ b/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java
@@ -0,0 +1,29 @@
+package com.example.hellojni.lib;
+
+import android.test.ActivityInstrumentationTestCase;
+
+/**
+ * This is a simple framework for a test of an Application. See
+ * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
+ * how to write and extend Application tests.
+ * <p/>
+ * To run this test, you can type:
+ * adb shell am instrument -w \
+ * -e class com.example.hellojni.HelloJniTest \
+ * com.example.hellojni.tests/android.test.InstrumentationTestRunner
+ */
+public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> {
+
+ public HelloJniTest() {
+ super("com.example.hellojni", HelloJni.class);
+ }
+
+
+ public void testJniName() {
+ final HelloJni a = getActivity();
+ // ensure a valid handle to the activity has been returned
+ assertNotNull(a);
+
+ assertFalse("unknown".equals(a.jniNameFromJNI()));
+ }
+}
diff --git a/tests/ndkJniLib/lib/src/main/AndroidManifest.xml b/tests/ndkJniLib/lib/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ff4f566
--- /dev/null
+++ b/tests/ndkJniLib/lib/src/main/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.hellojni.lib">
+
+ <uses-sdk android:minSdkVersion="3" />
+ <application>
+ <activity android:name=".HelloJni"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java b/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java
new file mode 100644
index 0000000..c97a0eb
--- /dev/null
+++ b/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 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.example.hellojni.lib;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+
+public class HelloJni extends Activity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ /* Create a TextView and set its content.
+ * the text is retrieved by calling a native
+ * function.
+ */
+ TextView tv = new TextView(this);
+ tv.setText( stringFromJNI() );
+ setContentView(tv);
+ }
+
+ /* A native method that is implemented by the
+ * 'hello-jni' native library, which is packaged
+ * with this application.
+ */
+ public native String stringFromJNI();
+
+ public native String jniNameFromJNI();
+
+ /* this is used to load the 'hello-jni' library on application
+ * startup. The library has already been unpacked into
+ * /data/data/com.example.hellojni/lib/libhello-jni.so at
+ * installation time by the package manager.
+ */
+ static {
+ System.loadLibrary("hello-jni");
+ }
+}
diff --git a/tests/ndkJniLib/lib/src/main/jni/hello-jni.c b/tests/ndkJniLib/lib/src/main/jni/hello-jni.c
new file mode 100644
index 0000000..4ee252f
--- /dev/null
+++ b/tests/ndkJniLib/lib/src/main/jni/hello-jni.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 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.
+ *
+ */
+#include <string.h>
+#include <jni.h>
+
+/* This is a trivial JNI example where we use a native method
+ * to return a new VM String. See the corresponding Java source
+ * file located at:
+ *
+ * apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
+ */
+jstring
+Java_com_example_hellojni_lib_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz)
+{
+#if defined(__arm__)
+ #if defined(__ARM_ARCH_7A__)
+ #if defined(__ARM_NEON__)
+ #define ABI "armeabi-v7a with NEON"
+ #else
+ #define ABI "armeabi-v7a"
+ #endif
+ #else
+ #define ABI "armeabi"
+ #endif
+#elif defined(__i386__)
+ #define ABI "x86"
+#elif defined(__mips__)
+ #define ABI "mips"
+#else
+ #define ABI "unknown"
+#endif
+
+ return (*env)->NewStringUTF(env, "Hello from JNI ! My ABI is " ABI ".");
+}
+
+jstring
+Java_com_example_hellojni_lib_HelloJni_jniNameFromJNI(JNIEnv* env, jobject thiz)
+{
+#if defined(__arm__)
+ #if defined(__ARM_ARCH_7A__)
+ #if defined(__ARM_NEON__)
+ #define ABI "armeabi-v7a with NEON"
+ #else
+ #define ABI "armeabi-v7a"
+ #endif
+ #else
+ #define ABI "armeabi"
+ #endif
+#elif defined(__i386__)
+ #define ABI "x86"
+#elif defined(__mips__)
+ #define ABI "mips"
+#else
+ #define ABI "unknown"
+#endif
+
+ return (*env)->NewStringUTF(env, ABI);
+}
diff --git a/tests/ndkJniLib/lib/src/main/res/values/strings.xml b/tests/ndkJniLib/lib/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c526073
--- /dev/null
+++ b/tests/ndkJniLib/lib/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">HelloJni</string>
+</resources>
diff --git a/tests/ndkJniLib/settings.gradle b/tests/ndkJniLib/settings.gradle
new file mode 100644
index 0000000..7f37a58
--- /dev/null
+++ b/tests/ndkJniLib/settings.gradle
@@ -0,0 +1 @@
+include 'app', 'lib' \ No newline at end of file
diff --git a/tests/rsSupportMode/build.gradle b/tests/rsSupportMode/build.gradle
index 86d1f22..96f40e4 100644
--- a/tests/rsSupportMode/build.gradle
+++ b/tests/rsSupportMode/build.gradle
@@ -13,7 +13,7 @@ android {
buildToolsVersion "18.1"
defaultConfig {
- minSdkVersion 16
+ minSdkVersion 8
targetSdkVersion 16
renderscriptTargetApi 18
renderscriptSupportMode true