Merge "Reduce persist threshold for lower warning/limit." into jb-dev
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index b716d8a..d3dd01a 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -25,6 +25,7 @@
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
+import android.net.TrafficStats;
 import android.test.AndroidTestCase;
 
 import com.android.frameworks.coretests.R;
@@ -86,6 +87,12 @@
         assertEquals(2147483647, kernelToTag("0x7fffffff00000000"));
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000"));
+
+        assertEquals(0, kernelToTag("0x0"));
+        assertEquals(0, kernelToTag("0xf00d"));
+        assertEquals(1, kernelToTag("0x100000000"));
+        assertEquals(14438007, kernelToTag("0xdc4e7700000000"));
+        assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
     }
 
     public void testNetworkStatsWithSet() throws Exception {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index dd650bf..e396a69 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -884,22 +884,25 @@
     @Override
     public boolean isActiveNetworkMetered() {
         enforceAccessPermission();
-
         final long token = Binder.clearCallingIdentity();
         try {
-            final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
-            if (state != null) {
-                try {
-                    return mPolicyManager.isNetworkMetered(state);
-                } catch (RemoteException e) {
-                }
-            }
-            return false;
+            return isNetworkMeteredUnchecked(mActiveDefaultNetwork);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
+    private boolean isNetworkMeteredUnchecked(int networkType) {
+        final NetworkState state = getNetworkStateUnchecked(networkType);
+        if (state != null) {
+            try {
+                return mPolicyManager.isNetworkMetered(state);
+            } catch (RemoteException e) {
+            }
+        }
+        return false;
+    }
+
     public boolean setRadios(boolean turnOn) {
         boolean result = true;
         enforceChangePermission();
@@ -993,7 +996,8 @@
     public int startUsingNetworkFeature(int networkType, String feature,
             IBinder binder) {
         if (VDBG) {
-            log("startUsingNetworkFeature for net " + networkType + ": " + feature);
+            log("startUsingNetworkFeature for net " + networkType + ": " + feature + ", uid="
+                    + Binder.getCallingUid());
         }
         enforceChangePermission();
         if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
@@ -1010,6 +1014,16 @@
             enforceConnectivityInternalPermission();
         }
 
+        // if UID is restricted, don't allow them to bring up metered APNs
+        final boolean networkMetered = isNetworkMeteredUnchecked(usedNetworkType);
+        final int uidRules;
+        synchronized (mRulesLock) {
+            uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
+        }
+        if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
+            return Phone.APN_REQUEST_FAILED;
+        }
+
         NetworkStateTracker network = mNetTrackers[usedNetworkType];
         if (network != null) {
             Integer currentPid = new Integer(getCallingPid());
@@ -1432,7 +1446,6 @@
                 mUidRules.put(uid, uidRules);
             }
 
-            // TODO: dispatch into NMS to push rules towards kernel module
             // TODO: notify UID when it has requested targeted updates
         }