Merge "Add hostname aware isCleartextTrafficPermitted"
diff --git a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
index d12ee3d..7bf0835 100644
--- a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -44,8 +44,11 @@
     }
 
     /**
-     * Returns whether cleartext network traffic (e.g. HTTP, FTP, XMPP, IMAP, SMTP -- without TLS or
-     * STARTTLS) is permitted for this process.
+     * Returns {@code true} if cleartext network traffic (e.g. HTTP, FTP, XMPP, IMAP, SMTP --
+     * without TLS or STARTTLS) is permitted for all network communications of this process.
+     *
+     * <p>{@link #isCleartextTrafficPermitted(String)} should be used to determine if cleartext
+     * traffic is permitted for a specific host.
      *
      * <p>When cleartext network traffic is not permitted, the platform's components (e.g. HTTP
      * stacks, {@code WebView}, {@code MediaPlayer}) will refuse this process's requests to use
@@ -63,10 +66,24 @@
      */
     public abstract boolean isCleartextTrafficPermitted();
 
+    /**
+     * Returns {@code true} if cleartext network traffic (e.g. HTTP, FTP, XMPP, IMAP, SMTP --
+     * without TLS or STARTTLS) is permitted for communicating with {@code hostname} for this
+     * process.
+     *
+     * <p>See {@link #isCleartextTrafficPermitted} for more details.
+     */
+    public abstract boolean isCleartextTrafficPermitted(String hostname);
+
     public static final class DefaultNetworkSecurityPolicy extends NetworkSecurityPolicy {
         @Override
         public boolean isCleartextTrafficPermitted() {
             return true;
         }
+
+        @Override
+        public boolean isCleartextTrafficPermitted(String hostname) {
+            return isCleartextTrafficPermitted();
+        }
     }
 }
diff --git a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
index fbcc3ae..7a57ac1 100644
--- a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
+++ b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
@@ -25,6 +25,8 @@
 import java.net.Socket;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
@@ -68,6 +70,27 @@
         assertEquals(true, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
     }
 
+    public void testHostnameAwareCleartextTrafficPolicySetterAndGetter() {
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
+        assertEquals(false,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted("localhost"));
+
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
+        assertEquals(true,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted("localhost"));
+
+        TestNetworkSecurityPolicy policy = new TestNetworkSecurityPolicy(false);
+        policy.addHostMapping("localhost", true);
+        policy.addHostMapping("example.com", false);
+        NetworkSecurityPolicy.setInstance(policy);
+        assertEquals(false, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
+        assertEquals(true,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted("localhost"));
+        assertEquals(false,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted("example.com"));
+
+    }
+
     public void testCleartextTrafficPolicyWithHttpURLConnection() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
         NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
@@ -313,14 +336,28 @@
 
     private static class TestNetworkSecurityPolicy extends NetworkSecurityPolicy {
         private final boolean mCleartextTrafficPermitted;
+        private final Map<String, Boolean> mHostMap = new HashMap<String, Boolean>();
 
         public TestNetworkSecurityPolicy(boolean cleartextTrafficPermitted) {
             mCleartextTrafficPermitted = cleartextTrafficPermitted;
         }
 
+        public void addHostMapping(String hostname, boolean isCleartextTrafficPermitted) {
+            mHostMap.put(hostname, isCleartextTrafficPermitted);
+        }
+
         @Override
         public boolean isCleartextTrafficPermitted() {
             return mCleartextTrafficPermitted;
         }
+
+        @Override
+        public boolean isCleartextTrafficPermitted(String hostname) {
+            if (mHostMap.containsKey(hostname)) {
+                return mHostMap.get(hostname);
+            }
+
+            return isCleartextTrafficPermitted();
+        }
     }
 }