Merge "Default to not allowing cleartext traffic for ephemeral apps"
diff --git a/core/java/android/security/net/config/ManifestConfigSource.java b/core/java/android/security/net/config/ManifestConfigSource.java
index 92bddb7..0f2994d 100644
--- a/core/java/android/security/net/config/ManifestConfigSource.java
+++ b/core/java/android/security/net/config/ManifestConfigSource.java
@@ -32,6 +32,7 @@
     private final int mApplicationInfoFlags;
     private final int mTargetSdkVersion;
     private final int mConfigResourceId;
+    private final boolean mEphemeralApp;
 
     private ConfigSource mConfigSource;
 
@@ -42,6 +43,7 @@
         mApplicationInfoFlags = info.flags;
         mTargetSdkVersion = info.targetSdkVersion;
         mConfigResourceId = info.networkSecurityConfigRes;
+        mEphemeralApp = info.isEphemeralApp();
     }
 
     @Override
@@ -69,14 +71,18 @@
                             + " debugBuild: " + debugBuild);
                 }
                 source = new XmlConfigSource(mContext, mConfigResourceId, debugBuild,
-                        mTargetSdkVersion);
+                        mTargetSdkVersion, mEphemeralApp);
             } else {
                 if (DBG) {
                     Log.d(LOG_TAG, "No Network Security Config specified, using platform default");
                 }
+                // the legacy FLAG_USES_CLEARTEXT_TRAFFIC is not supported for Ephemeral apps, they
+                // should use the network security config.
                 boolean usesCleartextTraffic =
-                        (mApplicationInfoFlags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0;
-                source = new DefaultConfigSource(usesCleartextTraffic, mTargetSdkVersion);
+                        (mApplicationInfoFlags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0
+                        && !mEphemeralApp;
+                source = new DefaultConfigSource(usesCleartextTraffic, mTargetSdkVersion,
+                        mEphemeralApp);
             }
             mConfigSource = source;
             return mConfigSource;
@@ -87,8 +93,10 @@
 
         private final NetworkSecurityConfig mDefaultConfig;
 
-        public DefaultConfigSource(boolean usesCleartextTraffic, int targetSdkVersion) {
-            mDefaultConfig = NetworkSecurityConfig.getDefaultBuilder(targetSdkVersion)
+        public DefaultConfigSource(boolean usesCleartextTraffic, int targetSdkVersion,
+                boolean ephemeralApp) {
+            mDefaultConfig = NetworkSecurityConfig.getDefaultBuilder(targetSdkVersion,
+                    ephemeralApp)
                     .setCleartextTrafficPermitted(usesCleartextTraffic)
                     .build();
         }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index b3a37d0..7923702 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -164,7 +164,8 @@
      * <p>
      * The default configuration has the following properties:
      * <ol>
-     * <li>Cleartext traffic is permitted.</li>
+     * <li>Cleartext traffic is permitted for non-ephemeral apps.</li>
+     * <li>Cleartext traffic is not permitted for ephemeral apps.</li>
      * <li>HSTS is not enforced.</li>
      * <li>No certificate pinning is used.</li>
      * <li>The system certificate store is trusted for connections.</li>
@@ -174,9 +175,9 @@
      *
      * @hide
      */
-    public static final Builder getDefaultBuilder(int targetSdkVersion) {
+    public static final Builder getDefaultBuilder(int targetSdkVersion, boolean ephemeralApp) {
         Builder builder = new Builder()
-                .setCleartextTrafficPermitted(DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED)
+                .setCleartextTrafficPermitted(!ephemeralApp)
                 .setHstsEnforced(DEFAULT_HSTS_ENFORCED)
                 // System certificate store, does not bypass static pins.
                 .addCertificatesEntryRef(
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index 4a5f827..38fe6b8 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -37,6 +37,7 @@
     private final int mResourceId;
     private final boolean mDebugBuild;
     private final int mTargetSdkVersion;
+    private final boolean mEphemeralApp;
 
     private boolean mInitialized;
     private NetworkSecurityConfig mDefaultConfig;
@@ -53,12 +54,19 @@
         this(context, resourceId, debugBuild, Build.VERSION_CODES.CUR_DEVELOPMENT);
     }
 
+    @VisibleForTesting
     public XmlConfigSource(Context context, int resourceId, boolean debugBuild,
             int targetSdkVersion) {
+        this(context, resourceId, debugBuild, targetSdkVersion, false);
+    }
+
+    public XmlConfigSource(Context context, int resourceId, boolean debugBuild,
+            int targetSdkVersion, boolean ephemeralApp) {
         mResourceId = resourceId;
         mContext = context;
         mDebugBuild = debugBuild;
         mTargetSdkVersion = targetSdkVersion;
+        mEphemeralApp = ephemeralApp;
     }
 
     public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() {
@@ -357,7 +365,7 @@
         // Use the platform default as the parent of the base config for any values not provided
         // there. If there is no base config use the platform default.
         NetworkSecurityConfig.Builder platformDefaultBuilder =
-                NetworkSecurityConfig.getDefaultBuilder(mTargetSdkVersion);
+                NetworkSecurityConfig.getDefaultBuilder(mTargetSdkVersion, mEphemeralApp);
         addDebugAnchorsIfNeeded(debugConfigBuilder, platformDefaultBuilder);
         if (baseConfigBuilder != null) {
             baseConfigBuilder.setParent(platformDefaultBuilder);
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
index eda3f5e..dc3b337 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
@@ -227,7 +227,7 @@
     public void testConfigBuilderUsesParents() throws Exception {
         // Check that a builder with a parent uses the parent's values when non is set.
         NetworkSecurityConfig config = new NetworkSecurityConfig.Builder()
-                .setParent(NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N))
+                .setParent(NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N, false))
                 .build();
         assert(!config.getTrustAnchors().isEmpty());
     }
@@ -268,9 +268,9 @@
             // Install the test CA.
             store.installCertificate(TEST_CA_CERT);
             NetworkSecurityConfig preNConfig =
-                    NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.M).build();
+                    NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.M, false).build();
             NetworkSecurityConfig nConfig =
-                    NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N).build();
+                    NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N, false).build();
             Set<TrustAnchor> preNAnchors = preNConfig.getTrustAnchors();
             Set<TrustAnchor> nAnchors = nConfig.getTrustAnchors();
             Set<X509Certificate> preNCerts = new HashSet<X509Certificate>();