Move jniDebuggable to NdkOptions

Experimental plugin use the flag to determine if native library is
debuggable.

debug build is now jni debuggable by default.

Change-Id: I11e9a1b2b3f0504ef2bcdf79de59fb5836e2b09e
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/internal/NdkOptionsHelper.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/internal/NdkOptionsHelper.java
index de7d52e..3e1ad72 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/internal/NdkOptionsHelper.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/internal/NdkOptionsHelper.java
@@ -17,6 +17,7 @@
 package com.android.build.gradle.internal;
 
 import com.android.annotations.NonNull;
+import com.android.build.gradle.managed.NdkBuildType;
 import com.android.build.gradle.managed.NdkConfig;
 import com.android.build.gradle.managed.NdkOptions;
 import com.google.common.collect.Lists;
@@ -48,7 +49,7 @@
     /**
      * Merge one NdkOptions to another.
      * @param base NdkOptions to merge to.  base is mutated to contain the merged result.
-     * @param other NdkOptions to merge.  Options in other priority over base if both are set.
+     * @param other NdkOptions to merge.  Options in other has priority over base if both are set.
      */
     public static void merge(NdkOptions base, NdkOptions other) {
         if (other.getModuleName() != null) {
@@ -68,4 +69,16 @@
             base.setRenderscriptNdkMode(other.getRenderscriptNdkMode());
         }
     }
+
+    /**
+     * Merge one NdkBuildType to another
+     * @param base NdkBuildType to merge to.  base is mutated to contain the merged result.
+     * @param other NdkBuildType to merge.  Options in other has priority over base if both are set.
+     */
+    public static void merge(NdkBuildType base, NdkBuildType other) {
+        merge(base, (NdkOptions) other);
+        if (other.getIsDebuggable() != null) {
+            base.setIsDebuggable(other.getIsDebuggable());
+        }
+    }
 }
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/BuildType.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/BuildType.java
index cdefb1f..5178d58 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/BuildType.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/BuildType.java
@@ -141,14 +141,6 @@
     void setIsPseudoLocalesEnabled(Boolean isPseudoLocalesEnabled);
 
     /**
-     * Returns whether the build type is configured to generate an apk with debuggable native code.
-     *
-     * @return true if the apk is debuggable
-     */
-    Boolean getIsJniDebuggable();
-    void setIsJniDebuggable(Boolean isJniDebuggable);
-
-    /**
      * Returns whether the build type is configured to generate an apk with debuggable
      * renderscript code.
      *
@@ -216,5 +208,5 @@
     Boolean getShrinkResources();
     void setShrinkResources(Boolean shrinkResources);
 
-    NdkOptions getNdk();
+    NdkBuildType getNdk();
 }
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkBuildType.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkBuildType.java
new file mode 100644
index 0000000..848853c
--- /dev/null
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkBuildType.java
@@ -0,0 +1,31 @@
+/*
+ * 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.build.gradle.managed;
+
+import org.gradle.model.Managed;
+
+/**
+ * NdkOptions with additional options specific to build types.
+ */
+@Managed
+public interface NdkBuildType extends NdkOptions {
+    /**
+     * Returns whether the resulting shared object is debuggable.
+     */
+    Boolean getIsDebuggable();
+    void setIsDebuggable(Boolean isDebuggable);
+}
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkConfig.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkConfig.java
index 1788083..5240e3e 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkConfig.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/NdkConfig.java
@@ -12,7 +12,7 @@
  * Root configuration model for android-ndk plugin.
  */
 @Managed
-public interface NdkConfig extends NdkOptions {
+public interface NdkConfig extends NdkBuildType {
 
     /**
      * The toolchain version.
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/adaptor/BuildTypeAdaptor.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/adaptor/BuildTypeAdaptor.java
index 249f208..1ecdcc5 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/adaptor/BuildTypeAdaptor.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/managed/adaptor/BuildTypeAdaptor.java
@@ -140,7 +140,7 @@
 
     @Override
     public boolean isJniDebuggable() {
-        return buildType.getIsJniDebuggable();
+        return Objects.firstNonNull(buildType.getNdk().getIsDebuggable(), false);
     }
 
     @Override
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.java
index 9a2190a..2d3d581 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.java
@@ -311,7 +311,6 @@
         private static void initBuildType(@NonNull BuildType buildType) {
             buildType.setIsDebuggable(false);
             buildType.setIsTestCoverageEnabled(false);
-            buildType.setIsJniDebuggable(false);
             buildType.setIsPseudoLocalesEnabled(false);
             buildType.setIsRenderscriptDebuggable(false);
             buildType.setRenderscriptOptimLevel(3);
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkComponentModelPlugin.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkComponentModelPlugin.java
index 90c03e0..073eb17 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkComponentModelPlugin.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkComponentModelPlugin.java
@@ -31,6 +31,7 @@
 import com.android.build.gradle.ndk.internal.NdkExtensionConvention;
 import com.android.build.gradle.ndk.internal.NdkNamingScheme;
 import com.android.build.gradle.ndk.internal.ToolchainConfiguration;
+import com.android.builder.core.BuilderConstants;
 import com.android.builder.core.VariantConfiguration;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
@@ -57,6 +58,7 @@
 import org.gradle.model.Validate;
 import org.gradle.nativeplatform.BuildTypeContainer;
 import org.gradle.nativeplatform.FlavorContainer;
+import org.gradle.nativeplatform.NativeBinarySpec;
 import org.gradle.nativeplatform.NativeLibraryBinarySpec;
 import org.gradle.nativeplatform.NativeLibrarySpec;
 import org.gradle.nativeplatform.SharedLibraryBinarySpec;
@@ -160,6 +162,17 @@
                     NdkOptionsHelper.init(buildType.getNdk());
                 }
             });
+
+            buildTypes.named(
+                    BuilderConstants.DEBUG,
+                    new Action<BuildType>() {
+                        @Override
+                        public void execute(BuildType buildType) {
+                            if (buildType.getNdk().getIsDebuggable() == null) {
+                                buildType.getNdk().setIsDebuggable(true);
+                            }
+                        }
+                    });
         }
 
         @Defaults
@@ -241,7 +254,6 @@
                                         nativeLib,
                                         sources,
                                         buildDir,
-                                        ndkConfig,
                                         ndkHandler);
                             }
                         });
@@ -266,18 +278,20 @@
             final DefaultAndroidComponentSpec androidSpec =
                     (DefaultAndroidComponentSpec) specs.get(COMPONENT_NAME);
             if (androidSpec.getNativeLibrary() != null) {
-                binaries.withType(SharedLibraryBinarySpec.class,
-                        new Action<SharedLibraryBinarySpec>() {
-                            @Override
-                            public void execute(SharedLibraryBinarySpec binary) {
-                                if (binary.getComponent().equals(androidSpec.getNativeLibrary())) {
-                                    NdkConfiguration.createTasks(
-                                            tasks, binary, buildDir, ndkConfig, ndkHandler);
-                                }
-                            }
-                        });
+                binaries.withType(DefaultAndroidBinary.class, new Action<DefaultAndroidBinary>() {
+                    @Override
+                    public void execute(DefaultAndroidBinary binary) {
+                        for (NativeBinarySpec nativeBinary : binary.getNativeBinaries()) {
+                            NdkConfiguration.createTasks(
+                                    tasks,
+                                    (SharedLibraryBinarySpec)nativeBinary,
+                                    buildDir,
+                                    binary.getMergedNdkConfig(),
+                                    ndkHandler);
+                        }
+                    }
+                });
             }
-
         }
 
         @Mutate
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkConfigImpl.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkConfigImpl.java
index 7c26a80..22a3095 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkConfigImpl.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/NdkConfigImpl.java
@@ -48,6 +48,8 @@
 
     String stl;
 
+    Boolean isDebuggable;
+
     Boolean renderscriptNdkMode;
 
     @Override
@@ -141,6 +143,16 @@
     }
 
     @Override
+    public Boolean getIsDebuggable() {
+        return isDebuggable;
+    }
+
+    @Override
+    public void setIsDebuggable(Boolean isDebuggable) {
+        this.isDebuggable = isDebuggable;
+    }
+
+    @Override
     public Boolean getRenderscriptNdkMode() {
         return renderscriptNdkMode;
     }
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
index a028989..a757a37 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/ClangNativeToolSpecification.java
@@ -188,10 +188,10 @@
 
     public ClangNativeToolSpecification(
             NdkHandler ndkHandler,
-            BuildType buildType,
-            NativePlatform platform) {
+            NativePlatform platform,
+            boolean isDebugBuild) {
         this.ndkHandler = ndkHandler;
-        this.isDebugBuild = (buildType.getName().equals(BuilderConstants.DEBUG));
+        this.isDebugBuild = isDebugBuild;
         this.platform = platform;
     }
 
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
index 8034c3a..d1b7bf6 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/GccNativeToolSpecification.java
@@ -17,19 +17,13 @@
 package com.android.build.gradle.ndk.internal;
 
 import com.android.SdkConstants;
-import com.android.builder.core.BuilderConstants;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.ListMultimap;
 
-import org.gradle.nativeplatform.BuildType;
 import org.gradle.nativeplatform.platform.NativePlatform;
 
-import java.util.List;
-import java.util.Map;
-
 /**
  * Flag configuration for GCC toolchain.
  */
@@ -189,8 +183,8 @@
     private boolean isDebugBuild;
 
 
-    public GccNativeToolSpecification(BuildType buildType, NativePlatform platform) {
-        this.isDebugBuild = (buildType.getName().equals(BuilderConstants.DEBUG));
+    public GccNativeToolSpecification(NativePlatform platform, boolean isDebugBuild) {
+        this.isDebugBuild = isDebugBuild;
         this.platform = platform;
     }
 
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NativeToolSpecificationFactory.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NativeToolSpecificationFactory.java
index d908ffb..cb91e06 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NativeToolSpecificationFactory.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NativeToolSpecificationFactory.java
@@ -30,15 +30,17 @@
     /**
      * Returns a NativeToolSpecification.
      *
-     * @param buildType Build type of the native binary.
      * @param platform  Target platform of the native binary.
+     * @param isDebugBuild Is the build debuggable.
      * @return A NativeToolSpecification for the targeted native binary.
      */
-    public static NativeToolSpecification create(NdkHandler ndkHandler, BuildType buildType,
-            NativePlatform platform) {
+    public static NativeToolSpecification create(
+            NdkHandler ndkHandler,
+            NativePlatform platform,
+            boolean isDebugBuild) {
         return (ndkHandler.getToolchain().equals(Toolchain.GCC)
-                ? new GccNativeToolSpecification(buildType, platform)
-                : new ClangNativeToolSpecification(ndkHandler, buildType, platform));
+                ? new GccNativeToolSpecification(platform, isDebugBuild)
+                : new ClangNativeToolSpecification(ndkHandler, platform, isDebugBuild));
     }
 
 }
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NdkConfiguration.java b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NdkConfiguration.java
index c463a33..65331d1 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NdkConfiguration.java
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/ndk/internal/NdkConfiguration.java
@@ -27,6 +27,7 @@
 import com.android.build.gradle.tasks.StripDebugSymbolTask;
 import com.android.builder.core.BuilderConstants;
 import com.android.utils.StringHelper;
+import com.google.common.base.Objects;
 
 import org.gradle.api.Action;
 import org.gradle.api.PolymorphicDomainObjectContainer;
@@ -55,7 +56,6 @@
             NativeLibrarySpec library,
             final AndroidComponentModelSourceSet sources,
             final File buildDir,
-            final NdkConfig ndkConfig,
             final NdkHandler ndkHandler) {
         for (Abi abi : ndkHandler.getSupportedAbis()) {
             library.targetPlatform(abi.getName());
@@ -146,8 +146,9 @@
 
         NativeToolSpecificationFactory.create(
                 ndkHandler,
-                binary.getBuildType(),
-                binary.getTargetPlatform()).apply(binary);
+                binary.getTargetPlatform(),
+                Objects.firstNonNull(ndkConfig.getIsDebuggable(), false)).apply(
+                binary);
 
         // Add flags defined in NdkConfig
         for (String flag : ndkConfig.getCFlags()) {
@@ -177,7 +178,7 @@
             File buildDir, NdkConfig ndkConfig, NdkHandler ndkHandler) {
         StlConfiguration.createStlCopyTask(ndkHandler, ndkConfig.getStl(), tasks, buildDir, binary);
 
-        if (binary.getBuildType().getName().equals(BuilderConstants.DEBUG)) {
+        if (Boolean.TRUE.equals(ndkConfig.getIsDebuggable())) {
             // TODO: Use AndroidTaskRegistry and scopes to create tasks in experimental plugin.
             setupNdkGdbDebug(tasks, binary, buildDir, ndkConfig, ndkHandler);
         }
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
index 48aa531..1ed9e4d 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
@@ -54,11 +54,6 @@
     android.ndk {
         moduleName = "hello-jni"
     }
-    android.buildTypes {
-        debug {
-            isJniDebuggable = true
-        }
-    }
 }
 """
     }
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/ComponentDslTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/ComponentDslTest.groovy
index ba7fb22..f58e310 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/ComponentDslTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/ComponentDslTest.groovy
@@ -59,11 +59,6 @@
     android.ndk {
         moduleName = "hello-jni"
     }
-    android.buildTypes {
-        debug {
-            isJniDebuggable = true
-        }
-    }
     android.productFlavors {
         create("f1") {
             proguardFiles += file("proguard.txt")
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentSplitTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentSplitTest.groovy
index 08a99b3..bc3b282 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentSplitTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentSplitTest.groovy
@@ -69,11 +69,6 @@
     android.ndk {
         moduleName = "hello-jni"
     }
-    android.buildTypes {
-        debug {
-            isJniDebuggable = true
-        }
-    }
 }
 """
     }
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentVariantTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentVariantTest.groovy
index 7714e31..d1df5bc 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentVariantTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/NdkComponentVariantTest.groovy
@@ -57,8 +57,8 @@
         moduleName = "hello-jni"
     }
     android.buildTypes {
-        debug {
-            isJniDebuggable = true
+        create("jniDebug") {
+            ndk.isDebuggable = true;
         }
     }
     android.productFlavors {
@@ -131,6 +131,32 @@
     }
 
     @Test
+    public void "check setting isDebuggable generates gdbserver and gdb.setup"() {
+        project.execute("assembleArmJniDebug")
+
+        File apk = project.getApk("arm", "jniDebug", "unsigned")
+        assertThatZip(apk).contains("lib/armeabi/libhello-jni.so")
+        assertThatZip(apk).contains("lib/armeabi/gdbserver")
+        assertThatZip(apk).contains("lib/armeabi/gdb.setup")
+        assertThatZip(apk).contains("lib/armeabi-v7a/libhello-jni.so")
+        assertThatZip(apk).contains("lib/armeabi-v7a/gdbserver")
+        assertThatZip(apk).contains("lib/armeabi-v7a/gdb.setup")
+    }
+
+    @Test
+    public void "check release build does not contain gdbserver and gdb.setup"() {
+        project.execute("assembleArmRelease")
+
+        File apk = project.getApk("arm", "release", "unsigned")
+        assertThatZip(apk).contains("lib/armeabi/libhello-jni.so")
+        assertThatZip(apk).doesNotContain("lib/armeabi/gdbserver")
+        assertThatZip(apk).doesNotContain("lib/armeabi/gdb.setup")
+        assertThatZip(apk).contains("lib/armeabi-v7a/libhello-jni.so")
+        assertThatZip(apk).doesNotContain("lib/armeabi-v7a/gdbserver")
+        assertThatZip(apk).doesNotContain("lib/armeabi-v7a/gdb.setup")
+    }
+
+    @Test
     @Category(DeviceTests.class)
     public void connectedAndroidTest() {
         if (GradleTestProject.DEVICE_PROVIDER_NAME.equals(BuilderConstants.CONNECTED)) {
diff --git a/build-system/integration-test/test-projects/ndkSanAngeles2/build.gradle b/build-system/integration-test/test-projects/ndkSanAngeles2/build.gradle
index 2a5665c..bb0bb79 100644
--- a/build-system/integration-test/test-projects/ndkSanAngeles2/build.gradle
+++ b/build-system/integration-test/test-projects/ndkSanAngeles2/build.gradle
@@ -15,12 +15,6 @@
         }
     }
 
-    android.buildTypes {
-        debug {
-            isJniDebuggable = true
-        }
-    }
-
     android.ndk {
         moduleName = "sanangeles"
         CFlags += "-DDISABLE_IMPORTGL"