DO NOT MERGE Fix malformed log statement.
am: d7423d12a9

Change-Id: Ie52f24f39305f325e01972f5046247482053db28
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index fe69320..0c0872a 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -34,9 +34,13 @@
 import java.net.UnknownHostException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 import javax.net.SocketFactory;
 
 import com.android.okhttp.ConnectionPool;
+import com.android.okhttp.Dns;
 import com.android.okhttp.HttpHandler;
 import com.android.okhttp.HttpsHandler;
 import com.android.okhttp.OkHttpClient;
@@ -62,10 +66,10 @@
     // Objects used to perform per-network operations such as getSocketFactory
     // and openConnection, and a lock to protect access to them.
     private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
-    // mLock should be used to control write access to mConnectionPool and mNetwork.
+    // mLock should be used to control write access to mConnectionPool and mDns.
     // maybeInitHttpClient() must be called prior to reading either variable.
     private volatile ConnectionPool mConnectionPool = null;
-    private volatile com.android.okhttp.internal.Network mNetwork = null;
+    private volatile Dns mDns = null;
     private final Object mLock = new Object();
 
     // Default connection pool values. These are evaluated at startup, just
@@ -219,17 +223,17 @@
     // out) ConnectionPools.
     private void maybeInitHttpClient() {
         synchronized (mLock) {
-            if (mNetwork == null) {
-                mNetwork = new com.android.okhttp.internal.Network() {
+            if (mDns == null) {
+                mDns = new Dns() {
                     @Override
-                    public InetAddress[] resolveInetAddresses(String host) throws UnknownHostException {
-                        return Network.this.getAllByName(host);
+                    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
+                        return Arrays.asList(Network.this.getAllByName(hostname));
                     }
                 };
             }
             if (mConnectionPool == null) {
                 mConnectionPool = new ConnectionPool(httpMaxConnections,
-                        httpKeepAliveDurationMs);
+                        httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
             }
         }
     }
@@ -288,9 +292,8 @@
         }
         OkHttpClient client = okUrlFactory.client();
         client.setSocketFactory(getSocketFactory()).setConnectionPool(mConnectionPool);
-
-        // Use internal APIs to change the Network.
-        Internal.instance.setNetwork(client, mNetwork);
+        // Let network traffic go via mDns
+        client.setDns(mDns);
 
         return okUrlFactory.open(url);
     }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 56eba4f..dacea55 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -418,8 +418,15 @@
      */
     public static final int TRANSPORT_VPN = 4;
 
+    /**
+     * Indicates this network uses a Wi-Fi Aware transport.
+     *
+     * @hide PROPOSED_AWARE_API
+     */
+    public static final int TRANSPORT_WIFI_AWARE = 5;
+
     private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
-    private static final int MAX_TRANSPORT = TRANSPORT_VPN;
+    private static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE;
 
     /**
      * Adds the given transport type to this {@code NetworkCapability} instance.
@@ -889,6 +896,7 @@
                 case TRANSPORT_BLUETOOTH:   transports += "BLUETOOTH"; break;
                 case TRANSPORT_ETHERNET:    transports += "ETHERNET"; break;
                 case TRANSPORT_VPN:         transports += "VPN"; break;
+                case TRANSPORT_WIFI_AWARE:  transports += "WIFI_AWARE"; break;
             }
             if (++i < types.length) transports += "|";
         }
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index eb105d2..3e99521 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -25,11 +25,8 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <linux/filter.h>
-#include <linux/if.h>
 #include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <net/if_ether.h>
+#include <netinet/ether.h>
 #include <netinet/icmp6.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2693272..750b841 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -132,6 +132,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.DataConnectionStats;
 import com.android.server.connectivity.KeepaliveTracker;
+import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.LingerMonitor;
 import com.android.server.connectivity.NetworkAgentInfo;
@@ -719,16 +720,6 @@
         mHandler = new InternalHandler(mHandlerThread.getLooper());
         mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
 
-        // setup our unique device name
-        if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
-            String id = Settings.Secure.getString(context.getContentResolver(),
-                    Settings.Secure.ANDROID_ID);
-            if (id != null && id.length() > 0) {
-                String name = new String("android-").concat(id);
-                SystemProperties.set("net.hostname", name);
-            }
-        }
-
         mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
                 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
 
@@ -815,7 +806,8 @@
         mTestMode = SystemProperties.get("cm.test.mode").equals("true")
                 && SystemProperties.get("ro.build.type").equals("eng");
 
-        mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager);
+        mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager,
+                                   IoThread.get().getLooper(), new MockableSystemProperties());
 
         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
 
@@ -4592,28 +4584,9 @@
         } catch (Exception e) {
             loge("Exception in setDnsConfigurationForNetwork: " + e);
         }
-        final NetworkAgentInfo defaultNai = getDefaultNetwork();
-        if (defaultNai != null && defaultNai.network.netId == netId) {
-            setDefaultDnsSystemProperties(dnses);
-        }
         flushVmDnsCache();
     }
 
-    private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) {
-        int last = 0;
-        for (InetAddress dns : dnses) {
-            ++last;
-            String key = "net.dns" + last;
-            String value = dns.getHostAddress();
-            SystemProperties.set(key, value);
-        }
-        for (int i = last + 1; i <= mNumDnsEntries; ++i) {
-            String key = "net.dns" + i;
-            SystemProperties.set(key, "");
-        }
-        mNumDnsEntries = last;
-    }
-
     private String getNetworkPermission(NetworkCapabilities nc) {
         // TODO: make these permission strings AIDL constants instead.
         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
@@ -4830,7 +4803,6 @@
         notifyLockdownVpn(newNetwork);
         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
         updateTcpBufferSizes(newNetwork);
-        setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
     }
 
     private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 7cd1b7b..e084ff8 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -55,9 +55,9 @@
  */
 public class PermissionMonitor {
     private static final String TAG = "PermissionMonitor";
-    private static final boolean DBG = false;
-    private static final boolean SYSTEM = true;
-    private static final boolean NETWORK = false;
+    private static final boolean DBG = true;
+    private static final Boolean SYSTEM = Boolean.TRUE;
+    private static final Boolean NETWORK = Boolean.FALSE;
 
     private final Context mContext;
     private final PackageManager mPackageManager;
@@ -228,30 +228,40 @@
         update(users, mApps, false);
     }
 
+
+    private Boolean highestPermissionForUid(Boolean currentPermission, String name) {
+        if (currentPermission == SYSTEM) {
+            return currentPermission;
+        }
+        try {
+            final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
+            final boolean isNetwork = hasNetworkPermission(app);
+            final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+            if (isNetwork || hasRestrictedPermission) {
+                currentPermission = hasRestrictedPermission;
+            }
+        } catch (NameNotFoundException e) {
+            // App not found.
+            loge("NameNotFoundException " + name);
+        }
+        return currentPermission;
+    }
+
     private synchronized void onAppAdded(String appName, int appUid) {
         if (TextUtils.isEmpty(appName) || appUid < 0) {
             loge("Invalid app in onAppAdded: " + appName + " | " + appUid);
             return;
         }
 
-        try {
-            PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS);
-            boolean isNetwork = hasNetworkPermission(app);
-            boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
-            if (isNetwork || hasRestrictedPermission) {
-                Boolean permission = mApps.get(appUid);
-                // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
-                // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
-                if (permission == null || permission == NETWORK) {
-                    mApps.put(appUid, hasRestrictedPermission);
+        // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
+        // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
+        final Boolean permission = highestPermissionForUid(mApps.get(appUid), appName);
+        if (permission != mApps.get(appUid)) {
+            mApps.put(appUid, permission);
 
-                    Map<Integer, Boolean> apps = new HashMap<>();
-                    apps.put(appUid, hasRestrictedPermission);
-                    update(mUsers, apps, true);
-                }
-            }
-        } catch (NameNotFoundException e) {
-            loge("NameNotFoundException in onAppAdded: " + e);
+            Map<Integer, Boolean> apps = new HashMap<>();
+            apps.put(appUid, permission);
+            update(mUsers, apps, true);
         }
     }
 
@@ -260,11 +270,33 @@
             loge("Invalid app in onAppRemoved: " + appUid);
             return;
         }
-        mApps.remove(appUid);
-
         Map<Integer, Boolean> apps = new HashMap<>();
-        apps.put(appUid, NETWORK);  // doesn't matter which permission we pick here
-        update(mUsers, apps, false);
+
+        Boolean permission = null;
+        String[] packages = mPackageManager.getPackagesForUid(appUid);
+        if (packages != null && packages.length > 0) {
+            for (String name : packages) {
+                permission = highestPermissionForUid(permission, name);
+                if (permission == SYSTEM) {
+                    // An app with this UID still has the SYSTEM permission.
+                    // Therefore, this UID must already have the SYSTEM permission.
+                    // Nothing to do.
+                    return;
+                }
+            }
+        }
+        if (permission == mApps.get(appUid)) {
+            // The permissions of this UID have not changed. Nothing to do.
+            return;
+        } else if (permission != null) {
+            mApps.put(appUid, permission);
+            apps.put(appUid, permission);
+            update(mUsers, apps, true);
+        } else {
+            mApps.remove(appUid);
+            apps.put(appUid, NETWORK);  // doesn't matter which permission we pick here
+            update(mUsers, apps, false);
+        }
     }
 
     private static void log(String s) {