diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 2ef9b62..6f475cc 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -182,6 +182,7 @@
     CtsHostJank \
     CtsHostsideNetworkTests \
     CtsHostUi \
+    CtsJdwpSecurityHostTestCases \
     CtsMonkeyTestCases \
     CtsThemeHostTestCases \
     CtsSecurityHostTestCases \
@@ -204,6 +205,7 @@
 
 cts_device_jars := \
     CtsDeviceJank \
+    CtsJdwpApp \
     CtsPrintInstrument
 
 cts_device_executables := \
diff --git a/hostsidetests/jdwpsecurity/Android.mk b/hostsidetests/jdwpsecurity/Android.mk
new file mode 100644
index 0000000..561d346
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsJdwpSecurityHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.jdwpsecurity
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/jdwpsecurity/app/Android.mk b/hostsidetests/jdwpsecurity/app/Android.mk
new file mode 100644
index 0000000..13b5be4
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/app/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := CtsJdwpApp
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+include $(BUILD_JAVA_LIBRARY)
+
+# Copy the built module to the cts dir
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+	$(copy-file-to-target)
+
+# Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
+$(my_register_name) : $(cts_library_jar)
+
diff --git a/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java b/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java
new file mode 100644
index 0000000..f2e5980
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.cts.jdwpsecurity;
+
+public class JdwpTest {
+    private static final long LOOP_TIMEOUT_MS = 60 * 1000;
+
+    public static void main(String[] args) throws Exception {
+        // Print pid so the test knows who we are.
+        int pid = android.os.Process.myPid();
+        System.out.println(pid);
+
+        // Loop to keep alive so the host test has the time to check whether we have a JDWP
+        // connection.
+        // Note: we use a timeout to avoid indefinite loop in case something wrong happens
+        // with the test harness.
+        long start = System.currentTimeMillis();
+        while(getElapsedTime(start) < LOOP_TIMEOUT_MS) {
+            Thread.sleep(100);
+        }
+    }
+
+    private static long getElapsedTime(long start) {
+        return System.currentTimeMillis() - start;
+    }
+}
diff --git a/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
new file mode 100644
index 0000000..8e276ed
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
@@ -0,0 +1,284 @@
+/*
+ * 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 android.jdwpsecurity.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.ArrayUtil;
+import com.android.tradefed.util.RunUtil;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test to check non-zygote apps do not have an active JDWP connection.
+ */
+public class JdwpSecurityHostTest extends DeviceTestCase implements IBuildReceiver {
+
+    private static final String DEVICE_LOCATION = "/data/local/tmp/jdwpsecurity";
+    private static final String DEVICE_SCRIPT_FILENAME = "jdwptest";
+    private static final String DEVICE_JAR_FILENAME = "CtsJdwpApp.jar";
+    private static final String JAR_MAIN_CLASS_NAME = "com.android.cts.jdwpsecurity.JdwpTest";
+
+    private CtsBuildHelper mCtsBuild;
+
+    private static String getDeviceScriptFilepath() {
+        return DEVICE_LOCATION + File.separator + DEVICE_SCRIPT_FILENAME;
+    }
+
+    private static String getDeviceJarFilepath() {
+        return DEVICE_LOCATION + File.separator + DEVICE_JAR_FILENAME;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Create test directory on the device.
+        createRemoteDir(DEVICE_LOCATION);
+
+        // Also create the dalvik-cache directory. It needs to exist before the runtime starts.
+        createRemoteDir(DEVICE_LOCATION + File.separator + "dalvik-cache");
+
+        // Create and push script on the device.
+        File tempFile = createScriptTempFile();
+        try {
+            boolean success = getDevice().pushFile(tempFile, getDeviceScriptFilepath());
+            assertTrue("Failed to push script to " + getDeviceScriptFilepath(), success);
+        } finally {
+            if (tempFile != null) {
+                tempFile.delete();
+            }
+        }
+
+        // Make the script executable.
+        getDevice().executeShellCommand("chmod 755 " + getDeviceScriptFilepath());
+
+        // Push jar file.
+        File jarFile = mCtsBuild.getTestApp(DEVICE_JAR_FILENAME);
+        boolean success = getDevice().pushFile(jarFile, getDeviceJarFilepath());
+        assertTrue("Failed to push jar file to " + getDeviceScriptFilepath(), success);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Delete the whole test directory on the device.
+        getDevice().executeShellCommand(String.format("rm -r %s", DEVICE_LOCATION));
+
+        super.tearDown();
+    }
+
+    /**
+     * Tests a non-zygote app does not have a JDWP connection, thus not being
+     * debuggable.
+     *
+     * Runs a script executing a Java app (jar file) with app_process,
+     * without forking from zygote. Then checks its pid is not returned
+     * by 'adb jdwp', meaning it has no JDWP connection and cannot be
+     * debugged.
+     *
+     * @throws Exception
+     */
+    public void testNonZygoteProgramIsNotDebuggable() throws Exception {
+        String scriptFilepath = getDeviceScriptFilepath();
+        Process scriptProcess = null;
+        String scriptPid = null;
+        List<String> activeJdwpPids = null;
+        try {
+            // Run the script on the background so it's running when we collect the list of
+            // pids with a JDWP connection using 'adb jdwp'.
+            // command.
+            scriptProcess = runScriptInBackground(scriptFilepath);
+
+            // On startup, the script will print its pid on its output.
+            scriptPid = readScriptPid(scriptProcess);
+
+            // Collect the list of pids with a JDWP connection.
+            activeJdwpPids = getJdwpPids();
+        } finally {
+            // Stop the script.
+            if (scriptProcess != null) {
+                scriptProcess.destroy();
+            }
+        }
+
+        assertNotNull("Failed to get script pid", scriptPid);
+        assertNotNull("Failed to get active JDWP pids", activeJdwpPids);
+        assertFalse("Test app should not have an active JDWP connection" +
+                " (pid " + scriptPid + " is returned by 'adb jdwp')",
+                activeJdwpPids.contains(scriptPid));
+    }
+
+    private Process runScriptInBackground(String scriptFilepath) throws IOException {
+        String[] shellScriptCommand = buildAdbCommand("shell", scriptFilepath);
+        return RunUtil.getDefault().runCmdInBackground(shellScriptCommand);
+    }
+
+    private String readScriptPid(Process scriptProcess) throws IOException {
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new InputStreamReader(scriptProcess.getInputStream()));
+            // We only expect to read one line containing the pid.
+            return br.readLine();
+        } finally {
+            if (br != null) {
+                br.close();
+            }
+        }
+    }
+
+    private List<String> getJdwpPids() throws Exception {
+        return new AdbJdwpOutputReader().listPidsWithAdbJdwp();
+    }
+
+    /**
+     * Creates the script file on the host so it can be pushed onto the device.
+     *
+     * @return the script file
+     * @throws IOException
+     */
+    private static File createScriptTempFile() throws IOException {
+        File tempFile = File.createTempFile("jdwptest", ".tmp");
+
+        PrintWriter pw = null;
+        try {
+            pw = new PrintWriter(tempFile);
+
+            // We need a dalvik-cache in /data/local/tmp so we have read-write access.
+            // Note: this will cause the runtime to optimize the DEX file (contained in
+            // the jar file) before executing it.
+            pw.println(String.format("export ANDROID_DATA=%s", DEVICE_LOCATION));
+            pw.println(String.format("export CLASSPATH=%s", getDeviceJarFilepath()));
+            pw.println(String.format("exec app_process /system/bin %s \"$@\"",
+                    JAR_MAIN_CLASS_NAME));
+        } finally {
+            if (pw != null) {
+                pw.close();
+            }
+        }
+
+        return tempFile;
+    }
+
+    /**
+     * Helper class collecting all pids returned by 'adb jdwp' command.
+     */
+    private class AdbJdwpOutputReader implements Runnable {
+        /**
+         * A list of all pids with a JDWP connection returned by 'adb jdwp'.
+         */
+        private final List<String> lines = new ArrayList<String>();
+
+        /**
+         * The input stream of the process running 'adb jdwp'.
+         */
+        private InputStream in;
+
+        public List<String> listPidsWithAdbJdwp() throws Exception {
+            // The 'adb jdwp' command does not return normally, it only terminates with Ctrl^C.
+            // Therefore we cannot use ITestDevice.executeAdbCommand but need to run that command
+            // in the background. Since we know the tested app is already running, we only need to
+            // capture the output for a short amount of time before stopping the 'adb jdwp'
+            // command.
+            String[] adbJdwpCommand = buildAdbCommand("jdwp");
+            Process adbProcess = RunUtil.getDefault().runCmdInBackground(adbJdwpCommand);
+            in = adbProcess.getInputStream();
+
+            // Read the output for 5s in a separate thread before stopping the command.
+            Thread t = new Thread(this);
+            t.start();
+            Thread.sleep(5000);
+
+            // Kill the 'adb jdwp' process and wait for the thread to stop.
+            adbProcess.destroy();
+            t.join();
+
+            return lines;
+        }
+
+        @Override
+        public void run() {
+            BufferedReader br = null;
+            try {
+                br = new BufferedReader(new InputStreamReader(in));
+                String line;
+                while ((line = readLineIgnoreException(br)) != null) {
+                    lines.add(line);
+                }
+            } catch (IOException e) {
+                CLog.e(e);
+            } finally {
+                if (br != null) {
+                    try {
+                        br.close();
+                    } catch (IOException e) {
+                        // Ignore it.
+                    }
+                }
+            }
+        }
+
+        private String readLineIgnoreException(BufferedReader reader) throws IOException {
+            try {
+                return reader.readLine();
+            } catch (IOException e) {
+                if (e instanceof EOFException) {
+                    // This is expected when the process's input stream is closed.
+                    return null;
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
+
+    private String[] buildAdbCommand(String... args) {
+        return ArrayUtil.buildArray(new String[] {"adb", "-s", getDevice().getSerialNumber()},
+                args);
+    }
+
+    private boolean createRemoteDir(String remoteFilePath) throws DeviceNotAvailableException {
+        if (getDevice().doesFileExist(remoteFilePath)) {
+            return true;
+        }
+        File remoteFile = new File(remoteFilePath);
+        String parentPath = remoteFile.getParent();
+        if (parentPath != null) {
+            if (!createRemoteDir(parentPath)) {
+                return false;
+            }
+        }
+        getDevice().executeShellCommand(String.format("mkdir %s", remoteFilePath));
+        return getDevice().doesFileExist(remoteFilePath);
+    }
+}
