summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/WallpaperManager.java3
-rw-r--r--core/java/android/net/NetworkStats.java79
-rw-r--r--core/java/android/net/NetworkStatsHistory.java16
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml6
-rw-r--r--core/tests/coretests/src/android/net/NetworkStatsTest.java57
-rw-r--r--services/camera/libcameraservice/CameraHardwareInterface.h6
-rw-r--r--services/input/InputDispatcher.cpp36
-rw-r--r--services/input/InputDispatcher.h6
-rw-r--r--services/java/com/android/server/NetworkManagementService.java16
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java457
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java234
-rw-r--r--services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java5
14 files changed, 636 insertions, 297 deletions
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 3626bf5..7fd5a7d 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -676,7 +676,8 @@ public class WallpaperManager {
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
- if (bm.getWidth() == width && bm.getHeight() == height) {
+ if (width <= 0 || height <= 0
+ || (bm.getWidth() == width && bm.getHeight() == height)) {
return bm;
}
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 6354e9a..60f740e 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -23,6 +23,7 @@ import android.util.SparseBooleanArray;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashSet;
/**
@@ -48,74 +49,60 @@ public class NetworkStats implements Parcelable {
* generated.
*/
public final long elapsedRealtime;
- public final String[] iface;
- public final int[] uid;
- public final long[] rx;
- public final long[] tx;
+ public int size;
+ public String[] iface;
+ public int[] uid;
+ public long[] rx;
+ public long[] tx;
// TODO: add fg/bg stats once reported by kernel
- private NetworkStats(long elapsedRealtime, String[] iface, int[] uid, long[] rx, long[] tx) {
+ public NetworkStats(long elapsedRealtime, int initialSize) {
this.elapsedRealtime = elapsedRealtime;
- this.iface = iface;
- this.uid = uid;
- this.rx = rx;
- this.tx = tx;
+ this.size = 0;
+ this.iface = new String[initialSize];
+ this.uid = new int[initialSize];
+ this.rx = new long[initialSize];
+ this.tx = new long[initialSize];
}
public NetworkStats(Parcel parcel) {
elapsedRealtime = parcel.readLong();
+ size = parcel.readInt();
iface = parcel.createStringArray();
uid = parcel.createIntArray();
rx = parcel.createLongArray();
tx = parcel.createLongArray();
}
- public static class Builder {
- private long mElapsedRealtime;
- private final String[] mIface;
- private final int[] mUid;
- private final long[] mRx;
- private final long[] mTx;
-
- private int mIndex = 0;
-
- public Builder(long elapsedRealtime, int size) {
- mElapsedRealtime = elapsedRealtime;
- mIface = new String[size];
- mUid = new int[size];
- mRx = new long[size];
- mTx = new long[size];
+ public NetworkStats addEntry(String iface, int uid, long rx, long tx) {
+ if (size >= this.iface.length) {
+ final int newLength = Math.max(this.iface.length, 10) * 3 / 2;
+ this.iface = Arrays.copyOf(this.iface, newLength);
+ this.uid = Arrays.copyOf(this.uid, newLength);
+ this.rx = Arrays.copyOf(this.rx, newLength);
+ this.tx = Arrays.copyOf(this.tx, newLength);
}
- public Builder addEntry(String iface, int uid, long rx, long tx) {
- mIface[mIndex] = iface;
- mUid[mIndex] = uid;
- mRx[mIndex] = rx;
- mTx[mIndex] = tx;
- mIndex++;
- return this;
- }
+ this.iface[size] = iface;
+ this.uid[size] = uid;
+ this.rx[size] = rx;
+ this.tx[size] = tx;
+ size++;
- public NetworkStats build() {
- if (mIndex != mIface.length) {
- throw new IllegalArgumentException("unexpected number of entries");
- }
- return new NetworkStats(mElapsedRealtime, mIface, mUid, mRx, mTx);
- }
+ return this;
}
+ @Deprecated
public int length() {
- // length is identical for all fields
- return iface.length;
+ return size;
}
/**
* Find first stats index that matches the requested parameters.
*/
public int findIndex(String iface, int uid) {
- final int length = length();
- for (int i = 0; i < length; i++) {
+ for (int i = 0; i < size; i++) {
if (equal(iface, this.iface[i]) && uid == this.uid[i]) {
return i;
}
@@ -195,9 +182,8 @@ public class NetworkStats implements Parcelable {
}
// result will have our rows, and elapsed time between snapshots
- final int length = length();
- final NetworkStats.Builder result = new NetworkStats.Builder(deltaRealtime, length);
- for (int i = 0; i < length; i++) {
+ final NetworkStats result = new NetworkStats(deltaRealtime, size);
+ for (int i = 0; i < size; i++) {
final String iface = this.iface[i];
final int uid = this.uid[i];
@@ -221,7 +207,7 @@ public class NetworkStats implements Parcelable {
}
}
- return result.build();
+ return result;
}
private static boolean equal(Object a, Object b) {
@@ -255,6 +241,7 @@ public class NetworkStats implements Parcelable {
/** {@inheritDoc} */
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(elapsedRealtime);
+ dest.writeInt(size);
dest.writeStringArray(iface);
dest.writeIntArray(uid);
dest.writeLongArray(rx);
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index a697e96..5fa8e21 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -53,11 +53,15 @@ public class NetworkStatsHistory implements Parcelable {
public long[] tx;
public NetworkStatsHistory(long bucketDuration) {
+ this(bucketDuration, 10);
+ }
+
+ public NetworkStatsHistory(long bucketDuration, int initialSize) {
this.bucketDuration = bucketDuration;
- bucketStart = new long[0];
- rx = new long[0];
- tx = new long[0];
- bucketCount = bucketStart.length;
+ bucketStart = new long[initialSize];
+ rx = new long[initialSize];
+ tx = new long[initialSize];
+ bucketCount = 0;
}
public NetworkStatsHistory(Parcel in) {
@@ -168,8 +172,8 @@ public class NetworkStatsHistory implements Parcelable {
*/
private void insertBucket(int index, long start) {
// create more buckets when needed
- if (bucketCount + 1 > bucketStart.length) {
- final int newLength = bucketStart.length + 10;
+ if (bucketCount >= bucketStart.length) {
+ final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
bucketStart = Arrays.copyOf(bucketStart, newLength);
rx = Arrays.copyOf(rx, newLength);
tx = Arrays.copyOf(tx, newLength);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6ab7738..1025b20 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3800,13 +3800,13 @@ public final class Settings {
/** {@hide} */
public static final String NETSTATS_PERSIST_THRESHOLD = "netstats_persist_threshold";
/** {@hide} */
- public static final String NETSTATS_SUMMARY_BUCKET_DURATION = "netstats_summary_bucket_duration";
+ public static final String NETSTATS_NETWORK_BUCKET_DURATION = "netstats_network_bucket_duration";
/** {@hide} */
- public static final String NETSTATS_SUMMARY_MAX_HISTORY = "netstats_summary_max_history";
+ public static final String NETSTATS_NETWORK_MAX_HISTORY = "netstats_network_max_history";
/** {@hide} */
- public static final String NETSTATS_DETAIL_BUCKET_DURATION = "netstats_detail_bucket_duration";
+ public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
/** {@hide} */
- public static final String NETSTATS_DETAIL_MAX_HISTORY = "netstats_detail_max_history";
+ public static final String NETSTATS_UID_MAX_HISTORY = "netstats_uid_max_history";
/**
* @hide
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index c83f910..37bb522 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -50,8 +50,8 @@
android:layout_width="0dip"
android:gravity="center_horizontal|center_vertical">
- <com.android.internal.widget.WaveView
- android:id="@+id/unlock_widget"
+ <TextView
+ android:id="@+id/screenLocked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
@@ -75,7 +75,7 @@
<com.android.internal.widget.WaveView
- android:id="@+id/wave_view"
+ android:id="@+id/unlock_widget"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal"
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 8a3e871..5250a7c 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -16,7 +16,6 @@
package android.net;
-import android.os.SystemClock;
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -25,12 +24,14 @@ import junit.framework.TestCase;
public class NetworkStatsTest extends TestCase {
private static final String TEST_IFACE = "test0";
+ private static final int TEST_UID = 1001;
+ private static final long TEST_START = 1194220800000L;
public void testFindIndex() throws Exception {
- final NetworkStats stats = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 3)
+ final NetworkStats stats = new NetworkStats(TEST_START, 3)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024)
- .addEntry(TEST_IFACE, 102, 1024, 1024).build();
+ .addEntry(TEST_IFACE, 102, 1024, 1024);
assertEquals(2, stats.findIndex(TEST_IFACE, 102));
assertEquals(2, stats.findIndex(TEST_IFACE, 102));
@@ -38,14 +39,40 @@ public class NetworkStatsTest extends TestCase {
assertEquals(-1, stats.findIndex(TEST_IFACE, 6));
}
+ public void testAddEntryGrow() throws Exception {
+ final NetworkStats stats = new NetworkStats(TEST_START, 2);
+
+ assertEquals(0, stats.size);
+ assertEquals(2, stats.iface.length);
+
+ stats.addEntry(TEST_IFACE, TEST_UID, 1L, 2L);
+ stats.addEntry(TEST_IFACE, TEST_UID, 2L, 2L);
+
+ assertEquals(2, stats.size);
+ assertEquals(2, stats.iface.length);
+
+ stats.addEntry(TEST_IFACE, TEST_UID, 3L, 4L);
+ stats.addEntry(TEST_IFACE, TEST_UID, 4L, 4L);
+ stats.addEntry(TEST_IFACE, TEST_UID, 5L, 5L);
+
+ assertEquals(5, stats.size);
+ assertTrue(stats.iface.length >= 5);
+
+ assertEquals(1L, stats.rx[0]);
+ assertEquals(2L, stats.rx[1]);
+ assertEquals(3L, stats.rx[2]);
+ assertEquals(4L, stats.rx[3]);
+ assertEquals(5L, stats.rx[4]);
+ }
+
public void testSubtractIdenticalData() throws Exception {
- final NetworkStats before = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 2)
+ final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024).build();
+ .addEntry(TEST_IFACE, 101, 0, 1024);
- final NetworkStats after = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 2)
+ final NetworkStats after = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024).build();
+ .addEntry(TEST_IFACE, 101, 0, 1024);
final NetworkStats result = after.subtract(before);
@@ -57,13 +84,13 @@ public class NetworkStatsTest extends TestCase {
}
public void testSubtractIdenticalRows() throws Exception {
- final NetworkStats before = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 2)
+ final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024).build();
+ .addEntry(TEST_IFACE, 101, 0, 1024);
- final NetworkStats after = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 2)
+ final NetworkStats after = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1025, 2)
- .addEntry(TEST_IFACE, 101, 3, 1028).build();
+ .addEntry(TEST_IFACE, 101, 3, 1028);
final NetworkStats result = after.subtract(before);
@@ -75,14 +102,14 @@ public class NetworkStatsTest extends TestCase {
}
public void testSubtractNewRows() throws Exception {
- final NetworkStats before = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 2)
+ final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024).build();
+ .addEntry(TEST_IFACE, 101, 0, 1024);
- final NetworkStats after = new NetworkStats.Builder(SystemClock.elapsedRealtime(), 3)
+ final NetworkStats after = new NetworkStats(TEST_START, 3)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024)
- .addEntry(TEST_IFACE, 102, 1024, 1024).build();
+ .addEntry(TEST_IFACE, 102, 1024, 1024);
final NetworkStats result = after.subtract(before);
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 7a18831..a3749cf 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -552,7 +552,7 @@ private:
#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
static int __dequeue_buffer(struct preview_stream_ops* w,
- buffer_handle_t** buffer)
+ buffer_handle_t** buffer, int *stride)
{
int rc;
ANativeWindow *a = anw(w);
@@ -560,8 +560,10 @@ private:
rc = a->dequeueBuffer(a, &anb);
if (!rc) {
rc = a->lockBuffer(a, anb);
- if (!rc)
+ if (!rc) {
*buffer = &anb->handle;
+ *stride = anb->stride;
+ }
else
a->cancelBuffer(a, anb);
}
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 4c6098d..eff65c2 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1464,6 +1464,23 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
injectionPermission = INJECTION_PERMISSION_GRANTED;
}
+ // Check whether windows listening for outside touches are owned by the same UID. If it is
+ // set the policy flag that we will not reveal coordinate information to this window.
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+ const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
+ const int32_t foregroundWindowUid = foregroundWindow->ownerUid;
+ for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+ const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+ if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
+ const InputWindow* inputWindow = touchedWindow.window;
+ if (inputWindow->ownerUid != foregroundWindowUid) {
+ mTempTouchState.addOrUpdateWindow(inputWindow,
+ InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
+ }
+ }
+ }
+ }
+
// Ensure all touched foreground windows are ready for new input.
for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
@@ -1987,7 +2004,8 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
// Set the X and Y offset depending on the input source.
float xOffset, yOffset, scaleFactor;
- if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+ if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER
+ && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
scaleFactor = dispatchEntry->scaleFactor;
xOffset = dispatchEntry->xOffset * scaleFactor;
yOffset = dispatchEntry->yOffset * scaleFactor;
@@ -2002,6 +2020,14 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
xOffset = 0.0f;
yOffset = 0.0f;
scaleFactor = 1.0f;
+
+ // We don't want the dispatch target to know.
+ if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
+ for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+ scaledCoords[i].clear();
+ }
+ usingCoords = scaledCoords;
+ }
}
// Update the connection's input state.
@@ -2030,9 +2056,11 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
MotionSample* nextMotionSample = firstMotionSample->next;
for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
if (usingCoords == scaledCoords) {
- for (size_t i = 0; i < motionEntry->pointerCount; i++) {
- scaledCoords[i] = nextMotionSample->pointerCoords[i];
- scaledCoords[i].scale(scaleFactor);
+ if (!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
+ for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+ scaledCoords[i] = nextMotionSample->pointerCoords[i];
+ scaledCoords[i].scale(scaleFactor);
+ }
}
} else {
usingCoords = nextMotionSample->pointerCoords;
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 37cef90..39d4aeb 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -96,6 +96,12 @@ struct InputTarget {
/* This flag indicates that a motion event is being split across multiple windows. */
FLAG_SPLIT = 1 << 2,
+ /* This flag indicates that the pointer coordinates dispatched to the application
+ * will be zeroed out to avoid revealing information to an application. This is
+ * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
+ * the same UID from watching all touches. */
+ FLAG_ZERO_COORDS = 1 << 3,
+
/* This flag indicates that the event should be sent as is.
* Should always be set unless the event is to be transmuted. */
FLAG_DISPATCH_AS_IS = 1 << 8,
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 8f179f5..2190b30 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -882,8 +882,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
final String[] ifaces = listInterfaces();
- final NetworkStats.Builder stats = new NetworkStats.Builder(
- SystemClock.elapsedRealtime(), ifaces.length);
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), ifaces.length);
for (String iface : ifaces) {
final long rx = getInterfaceCounter(iface, true);
@@ -891,7 +890,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
stats.addEntry(iface, NetworkStats.UID_ALL, rx, tx);
}
- return stats.build();
+ return stats;
}
@Override
@@ -900,7 +899,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
final String[] knownUids = PATH_PROC_UID_STAT.list();
- final NetworkStats.Builder stats = new NetworkStats.Builder(
+ final NetworkStats stats = new NetworkStats(
SystemClock.elapsedRealtime(), knownUids.length);
for (String uid : knownUids) {
@@ -908,7 +907,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
collectNetworkStatsDetail(stats, uidInt);
}
- return stats.build();
+ return stats;
}
@Override
@@ -918,13 +917,12 @@ class NetworkManagementService extends INetworkManagementService.Stub {
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
}
- final NetworkStats.Builder stats = new NetworkStats.Builder(
- SystemClock.elapsedRealtime(), 1);
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
collectNetworkStatsDetail(stats, uid);
- return stats.build();
+ return stats;
}
- private void collectNetworkStatsDetail(NetworkStats.Builder stats, int uid) {
+ private void collectNetworkStatsDetail(NetworkStats stats, int uid) {
// TODO: kernel module will provide interface-level stats in future
// TODO: migrate these stats to come across netd in bulk, instead of all
// these individual file reads.
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 161c393..de69849 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -23,12 +23,12 @@ import static android.Manifest.permission.SHUTDOWN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.UID_ALL;
-import static android.provider.Settings.Secure.NETSTATS_DETAIL_BUCKET_DURATION;
-import static android.provider.Settings.Secure.NETSTATS_DETAIL_MAX_HISTORY;
+import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
+import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
import static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
-import static android.provider.Settings.Secure.NETSTATS_SUMMARY_BUCKET_DURATION;
-import static android.provider.Settings.Secure.NETSTATS_SUMMARY_MAX_HISTORY;
+import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
+import static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -38,6 +38,7 @@ import android.app.AlarmManager;
import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -88,6 +89,7 @@ import libcore.io.IoUtils;
public class NetworkStatsService extends INetworkStatsService.Stub {
private static final String TAG = "NetworkStats";
private static final boolean LOGD = true;
+ private static final boolean LOGV = false;
/** File header magic number: "ANET" */
private static final int FILE_MAGIC = 0x414E4554;
@@ -97,6 +99,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final INetworkManagementService mNetworkManager;
private final IAlarmManager mAlarmManager;
private final TrustedTime mTime;
+ private final NetworkStatsSettings mSettings;
private IConnectivityManager mConnManager;
@@ -112,22 +115,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES;
private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES;
- private LongSecureSetting mPollInterval = new LongSecureSetting(
- NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
- private LongSecureSetting mPersistThreshold = new LongSecureSetting(
- NETSTATS_PERSIST_THRESHOLD, 16 * KB_IN_BYTES);
-
- // TODO: adjust these timings for production builds
- private LongSecureSetting mSummaryBucketDuration = new LongSecureSetting(
- NETSTATS_SUMMARY_BUCKET_DURATION, 1 * HOUR_IN_MILLIS);
- private LongSecureSetting mSummaryMaxHistory = new LongSecureSetting(
- NETSTATS_SUMMARY_MAX_HISTORY, 90 * DAY_IN_MILLIS);
- private LongSecureSetting mDetailBucketDuration = new LongSecureSetting(
- NETSTATS_DETAIL_BUCKET_DURATION, 2 * HOUR_IN_MILLIS);
- private LongSecureSetting mDetailMaxHistory = new LongSecureSetting(
- NETSTATS_DETAIL_MAX_HISTORY, 90 * DAY_IN_MILLIS);
-
- private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
+ /**
+ * Settings that can be changed externally.
+ */
+ public interface NetworkStatsSettings {
+ public long getPollInterval();
+ public long getPersistThreshold();
+ public long getNetworkBucketDuration();
+ public long getNetworkMaxHistory();
+ public long getUidBucketDuration();
+ public long getUidMaxHistory();
+ public long getTimeCacheMaxAge();
+ }
private final Object mStatsLock = new Object();
@@ -135,19 +134,23 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private HashMap<String, InterfaceIdentity> mActiveIface = Maps.newHashMap();
/** Set of historical stats for known ifaces. */
- private HashMap<InterfaceIdentity, NetworkStatsHistory> mSummaryStats = Maps.newHashMap();
+ private HashMap<InterfaceIdentity, NetworkStatsHistory> mNetworkStats = Maps.newHashMap();
/** Set of historical stats for known UIDs. */
- private SparseArray<NetworkStatsHistory> mDetailStats = new SparseArray<NetworkStatsHistory>();
+ private SparseArray<NetworkStatsHistory> mUidStats = new SparseArray<NetworkStatsHistory>();
+
+ /** Flag if {@link #mUidStats} have been loaded from disk. */
+ private boolean mUidStatsLoaded = false;
- private NetworkStats mLastSummaryPoll;
- private NetworkStats mLastSummaryPersist;
+ private NetworkStats mLastNetworkPoll;
+ private NetworkStats mLastNetworkPersist;
- private NetworkStats mLastDetailPoll;
+ private NetworkStats mLastUidPoll;
private final HandlerThread mHandlerThread;
private final Handler mHandler;
- private final AtomicFile mSummaryFile;
+ private final AtomicFile mNetworkFile;
+ private final AtomicFile mUidFile;
// TODO: collect detailed uid stats, storing tag-granularity data until next
// dropbox, and uid summary for a specific bucket count.
@@ -157,7 +160,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public NetworkStatsService(
Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
// TODO: move to using cached NtpTrustedTime
- this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir());
+ this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir(),
+ new DefaultNetworkStatsSettings(context));
}
private static File getSystemDir() {
@@ -165,17 +169,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
public NetworkStatsService(Context context, INetworkManagementService networkManager,
- IAlarmManager alarmManager, TrustedTime time, File systemDir) {
+ IAlarmManager alarmManager, TrustedTime time, File systemDir,
+ NetworkStatsSettings settings) {
mContext = checkNotNull(context, "missing Context");
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
mTime = checkNotNull(time, "missing TrustedTime");
+ mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
- mSummaryFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+ mNetworkFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+ mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin"));
}
public void bindConnectivityManager(IConnectivityManager connManager) {
@@ -184,8 +191,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public void systemReady() {
synchronized (mStatsLock) {
- // read historical stats from disk
- readStatsLocked();
+ // read historical network stats from disk, since policy service
+ // might need them right away. we delay loading detailed UID stats
+ // until actually needed.
+ readNetworkStatsLocked();
}
// watch for network interfaces to be claimed
@@ -214,14 +223,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext.unregisterReceiver(mPollReceiver);
mContext.unregisterReceiver(mShutdownReceiver);
- writeStatsLocked();
- mSummaryStats.clear();
- mDetailStats.clear();
+ writeNetworkStatsLocked();
+ writeUidStatsLocked();
+ mNetworkStats.clear();
+ mUidStats.clear();
+ mUidStatsLoaded = false;
}
/**
* Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
- * reschedule based on current {@link #mPollInterval} value.
+ * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
*/
private void registerPollAlarmLocked() throws RemoteException {
if (mPollIntent != null) {
@@ -232,8 +243,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
final long currentRealtime = SystemClock.elapsedRealtime();
- mAlarmManager.setInexactRepeating(
- AlarmManager.ELAPSED_REALTIME, currentRealtime, mPollInterval.get(), mPollIntent);
+ mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+ mSettings.getPollInterval(), mPollIntent);
}
@Override
@@ -244,9 +255,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// combine all interfaces that match template
final String subscriberId = getActiveSubscriberId();
final NetworkStatsHistory combined = new NetworkStatsHistory(
- mSummaryBucketDuration.get());
- for (InterfaceIdentity ident : mSummaryStats.keySet()) {
- final NetworkStatsHistory history = mSummaryStats.get(ident);
+ mSettings.getNetworkBucketDuration(), estimateNetworkBuckets());
+ for (InterfaceIdentity ident : mNetworkStats.keySet()) {
+ final NetworkStatsHistory history = mNetworkStats.get(ident);
if (ident.matchesTemplate(networkTemplate, subscriberId)) {
combined.recordEntireHistory(history);
}
@@ -259,8 +270,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public NetworkStatsHistory getHistoryForUid(int uid, int networkTemplate) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
- // TODO: return history for requested uid
- return null;
+ synchronized (mStatsLock) {
+ // TODO: combine based on template, if we store that granularity
+ ensureUidStatsLoadedLocked();
+ return mUidStats.get(uid);
+ }
}
@Override
@@ -274,8 +288,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
long[] networkTotal = new long[2];
// combine total from all interfaces that match template
- for (InterfaceIdentity ident : mSummaryStats.keySet()) {
- final NetworkStatsHistory history = mSummaryStats.get(ident);
+ for (InterfaceIdentity ident : mNetworkStats.keySet()) {
+ final NetworkStatsHistory history = mNetworkStats.get(ident);
if (ident.matchesTemplate(networkTemplate, subscriberId)) {
networkTotal = history.getTotalData(start, end, networkTotal);
rx += networkTotal[0];
@@ -283,9 +297,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- final NetworkStats.Builder stats = new NetworkStats.Builder(end - start, 1);
+ final NetworkStats stats = new NetworkStats(end - start, 1);
stats.addEntry(IFACE_ALL, UID_ALL, tx, tx);
- return stats.build();
+ return stats;
}
}
@@ -296,17 +310,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// TODO: apply networktemplate once granular uid stats are stored.
synchronized (mStatsLock) {
- final int size = mDetailStats.size();
- final NetworkStats.Builder stats = new NetworkStats.Builder(end - start, size);
+ ensureUidStatsLoadedLocked();
+
+ final int size = mUidStats.size();
+ final NetworkStats stats = new NetworkStats(end - start, size);
long[] total = new long[2];
for (int i = 0; i < size; i++) {
- final int uid = mDetailStats.keyAt(i);
- final NetworkStatsHistory history = mDetailStats.valueAt(i);
+ final int uid = mUidStats.keyAt(i);
+ final NetworkStatsHistory history = mUidStats.valueAt(i);
total = history.getTotalData(start, end, total);
stats.addEntry(IFACE_ALL, uid, total[0], total[1]);
}
- return stats.build();
+ return stats;
}
}
@@ -333,7 +349,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// permission above.
synchronized (mStatsLock) {
// TODO: acquire wakelock while performing poll
- performPollLocked();
+ performPollLocked(true);
}
}
};
@@ -355,13 +371,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* {@link InterfaceIdentity}.
*/
private void updateIfacesLocked() {
- if (LOGD) Slog.v(TAG, "updateIfacesLocked()");
+ if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
// take one last stats snapshot before updating iface mapping. this
// isn't perfect, since the kernel may already be counting traffic from
// the updated network.
- // TODO: verify that we only poll summary stats, not uid details
- performPollLocked();
+ performPollLocked(false);
final NetworkState[] states;
try {
@@ -384,11 +399,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private void performPollLocked() {
- if (LOGD) Slog.v(TAG, "performPollLocked()");
+ /**
+ * Periodic poll operation, reading current statistics and recording into
+ * {@link NetworkStatsHistory}.
+ *
+ * @param detailedPoll Indicate if detailed UID stats should be collected
+ * during this poll operation.
+ */
+ private void performPollLocked(boolean detailedPoll) {
+ if (LOGV) Slog.v(TAG, "performPollLocked()");
// try refreshing time source when stale
- if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
+ if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
mTime.forceRefresh();
}
@@ -396,42 +418,45 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
: System.currentTimeMillis();
- final NetworkStats summary;
- final NetworkStats detail;
+ final NetworkStats networkStats;
+ final NetworkStats uidStats;
try {
- summary = mNetworkManager.getNetworkStatsSummary();
- detail = mNetworkManager.getNetworkStatsDetail();
+ networkStats = mNetworkManager.getNetworkStatsSummary();
+ uidStats = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null;
} catch (RemoteException e) {
Slog.w(TAG, "problem reading network stats");
return;
}
- performSummaryPollLocked(summary, currentTime);
- performDetailPollLocked(detail, currentTime);
+ performNetworkPollLocked(networkStats, currentTime);
+ if (detailedPoll) {
+ performUidPollLocked(uidStats, currentTime);
+ }
// decide if enough has changed to trigger persist
- final NetworkStats persistDelta = computeStatsDelta(mLastSummaryPersist, summary);
- final long persistThreshold = mPersistThreshold.get();
+ final NetworkStats persistDelta = computeStatsDelta(mLastNetworkPersist, networkStats);
+ final long persistThreshold = mSettings.getPersistThreshold();
for (String iface : persistDelta.getUniqueIfaces()) {
final int index = persistDelta.findIndex(iface, UID_ALL);
if (persistDelta.rx[index] > persistThreshold
|| persistDelta.tx[index] > persistThreshold) {
- writeStatsLocked();
- mLastSummaryPersist = summary;
+ writeNetworkStatsLocked();
+ writeUidStatsLocked();
+ mLastNetworkPersist = networkStats;
break;
}
}
}
/**
- * Update {@link #mSummaryStats} historical usage.
+ * Update {@link #mNetworkStats} historical usage.
*/
- private void performSummaryPollLocked(NetworkStats summary, long currentTime) {
+ private void performNetworkPollLocked(NetworkStats networkStats, long currentTime) {
final ArrayList<String> unknownIface = Lists.newArrayList();
- final NetworkStats delta = computeStatsDelta(mLastSummaryPoll, summary);
+ final NetworkStats delta = computeStatsDelta(mLastNetworkPoll, networkStats);
final long timeStart = currentTime - delta.elapsedRealtime;
- final long maxHistory = mSummaryMaxHistory.get();
+ final long maxHistory = mSettings.getNetworkMaxHistory();
for (String iface : delta.getUniqueIfaces()) {
final InterfaceIdentity ident = mActiveIface.get(iface);
if (ident == null) {
@@ -443,11 +468,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final long rx = delta.rx[index];
final long tx = delta.tx[index];
- final NetworkStatsHistory history = findOrCreateSummaryLocked(ident);
+ final NetworkStatsHistory history = findOrCreateNetworkLocked(ident);
history.recordData(timeStart, currentTime, rx, tx);
history.removeBucketsBefore(currentTime - maxHistory);
}
- mLastSummaryPoll = summary;
+ mLastNetworkPoll = networkStats;
if (LOGD && unknownIface.size() > 0) {
Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats");
@@ -455,40 +480,71 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
- * Update {@link #mDetailStats} historical usage.
+ * Update {@link #mUidStats} historical usage.
*/
- private void performDetailPollLocked(NetworkStats detail, long currentTime) {
- final NetworkStats delta = computeStatsDelta(mLastDetailPoll, detail);
+ private void performUidPollLocked(NetworkStats uidStats, long currentTime) {
+ ensureUidStatsLoadedLocked();
+
+ final NetworkStats delta = computeStatsDelta(mLastUidPoll, uidStats);
final long timeStart = currentTime - delta.elapsedRealtime;
- final long maxHistory = mDetailMaxHistory.get();
+ final long maxHistory = mSettings.getUidMaxHistory();
for (int uid : delta.getUniqueUids()) {
+ // TODO: traverse all ifaces once surfaced in stats
final int index = delta.findIndex(IFACE_ALL, uid);
- final long rx = delta.rx[index];
- final long tx = delta.tx[index];
+ if (index != -1) {
+ final long rx = delta.rx[index];
+ final long tx = delta.tx[index];
- final NetworkStatsHistory history = findOrCreateDetailLocked(uid);
- history.recordData(timeStart, currentTime, rx, tx);
- history.removeBucketsBefore(currentTime - maxHistory);
+ final NetworkStatsHistory history = findOrCreateUidLocked(uid);
+ history.recordData(timeStart, currentTime, rx, tx);
+ history.removeBucketsBefore(currentTime - maxHistory);
+ }
}
- mLastDetailPoll = detail;
+ mLastUidPoll = uidStats;
}
- private NetworkStatsHistory findOrCreateSummaryLocked(InterfaceIdentity ident) {
- NetworkStatsHistory stats = mSummaryStats.get(ident);
- if (stats == null) {
- stats = new NetworkStatsHistory(mSummaryBucketDuration.get());
- mSummaryStats.put(ident, stats);
+ private NetworkStatsHistory findOrCreateNetworkLocked(InterfaceIdentity ident) {
+ final long bucketDuration = mSettings.getNetworkBucketDuration();
+ final NetworkStatsHistory existing = mNetworkStats.get(ident);
+
+ // update when no existing, or when bucket duration changed
+ NetworkStatsHistory updated = null;
+ if (existing == null) {
+ updated = new NetworkStatsHistory(bucketDuration, 10);
+ } else if (existing.bucketDuration != bucketDuration) {
+ updated = new NetworkStatsHistory(
+ bucketDuration, estimateResizeBuckets(existing, bucketDuration));
+ updated.recordEntireHistory(existing);
+ }
+
+ if (updated != null) {
+ mNetworkStats.put(ident, updated);
+ return updated;
+ } else {
+ return existing;
}
- return stats;
}
- private NetworkStatsHistory findOrCreateDetailLocked(int uid) {
- NetworkStatsHistory stats = mDetailStats.get(uid);
- if (stats == null) {
- stats = new NetworkStatsHistory(mDetailBucketDuration.get());
- mDetailStats.put(uid, stats);
+ private NetworkStatsHistory findOrCreateUidLocked(int uid) {
+ final long bucketDuration = mSettings.getUidBucketDuration();
+ final NetworkStatsHistory existing = mUidStats.get(uid);
+
+ // update when no existing, or when bucket duration changed
+ NetworkStatsHistory updated = null;
+ if (existing == null) {
+ updated = new NetworkStatsHistory(bucketDuration, 10);
+ } else if (existing.bucketDuration != bucketDuration) {
+ updated = new NetworkStatsHistory(
+ bucketDuration, estimateResizeBuckets(existing, bucketDuration));
+ updated.recordEntireHistory(existing);
+ }
+
+ if (updated != null) {
+ mUidStats.put(uid, updated);
+ return updated;
+ } else {
+ return existing;
}
- return stats;
}
private InterfaceIdentity findOrCreateInterfaceLocked(String iface) {
@@ -500,15 +556,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return ident;
}
- private void readStatsLocked() {
- if (LOGD) Slog.v(TAG, "readStatsLocked()");
+ private void readNetworkStatsLocked() {
+ if (LOGV) Slog.v(TAG, "readNetworkStatsLocked()");
// clear any existing stats and read from disk
- mSummaryStats.clear();
+ mNetworkStats.clear();
FileInputStream fis = null;
try {
- fis = mSummaryFile.openRead();
+ fis = mNetworkFile.openRead();
final DataInputStream in = new DataInputStream(fis);
// verify file magic header intact
@@ -521,13 +577,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
switch (version) {
case VERSION_CURRENT: {
// file format is pairs of interfaces and stats:
- // summary := size *(InterfaceIdentity NetworkStatsHistory)
+ // network := size *(InterfaceIdentity NetworkStatsHistory)
final int size = in.readInt();
for (int i = 0; i < size; i++) {
final InterfaceIdentity ident = new InterfaceIdentity(in);
final NetworkStatsHistory history = new NetworkStatsHistory(in);
- mSummaryStats.put(ident, history);
+
+ mNetworkStats.put(ident, history);
}
break;
}
@@ -544,30 +601,113 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private void writeStatsLocked() {
- if (LOGD) Slog.v(TAG, "writeStatsLocked()");
+ private void ensureUidStatsLoadedLocked() {
+ if (!mUidStatsLoaded) {
+ readUidStatsLocked();
+ mUidStatsLoaded = true;
+ }
+ }
+
+ private void readUidStatsLocked() {
+ if (LOGV) Slog.v(TAG, "readUidStatsLocked()");
+
+ // clear any existing stats and read from disk
+ mUidStats.clear();
+
+ FileInputStream fis = null;
+ try {
+ fis = mUidFile.openRead();
+ final DataInputStream in = new DataInputStream(fis);
+
+ // verify file magic header intact
+ final int magic = in.readInt();
+ if (magic != FILE_MAGIC) {
+ throw new ProtocolException("unexpected magic: " + magic);
+ }
+
+ final int version = in.readInt();
+ switch (version) {
+ case VERSION_CURRENT: {
+ // file format is pairs of UIDs and stats:
+ // uid := size *(UID NetworkStatsHistory)
+
+ final int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ final int uid = in.readInt();
+ final NetworkStatsHistory history = new NetworkStatsHistory(in);
+
+ mUidStats.put(uid, history);
+ }
+ break;
+ }
+ default: {
+ throw new ProtocolException("unexpected version: " + version);
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // missing stats is okay, probably first boot
+ } catch (IOException e) {
+ Slog.e(TAG, "problem reading uid stats", e);
+ } finally {
+ IoUtils.closeQuietly(fis);
+ }
+ }
+
+ private void writeNetworkStatsLocked() {
+ if (LOGV) Slog.v(TAG, "writeNetworkStatsLocked()");
// TODO: consider duplicating stats and releasing lock while writing
FileOutputStream fos = null;
try {
- fos = mSummaryFile.startWrite();
+ fos = mNetworkFile.startWrite();
final DataOutputStream out = new DataOutputStream(fos);
out.writeInt(FILE_MAGIC);
out.writeInt(VERSION_CURRENT);
- out.writeInt(mSummaryStats.size());
- for (InterfaceIdentity ident : mSummaryStats.keySet()) {
- final NetworkStatsHistory history = mSummaryStats.get(ident);
+ out.writeInt(mNetworkStats.size());
+ for (InterfaceIdentity ident : mNetworkStats.keySet()) {
+ final NetworkStatsHistory history = mNetworkStats.get(ident);
ident.writeToStream(out);
history.writeToStream(out);
}
- mSummaryFile.finishWrite(fos);
+ mNetworkFile.finishWrite(fos);
} catch (IOException e) {
if (fos != null) {
- mSummaryFile.failWrite(fos);
+ mNetworkFile.failWrite(fos);
+ }
+ }
+ }
+
+ private void writeUidStatsLocked() {
+ if (LOGV) Slog.v(TAG, "writeUidStatsLocked()");
+
+ // TODO: consider duplicating stats and releasing lock while writing
+
+ FileOutputStream fos = null;
+ try {
+ fos = mUidFile.startWrite();
+ final DataOutputStream out = new DataOutputStream(fos);
+
+ out.writeInt(FILE_MAGIC);
+ out.writeInt(VERSION_CURRENT);
+
+ final int size = mUidStats.size();
+
+ out.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ final int uid = mUidStats.keyAt(i);
+ final NetworkStatsHistory history = mUidStats.valueAt(i);
+ out.writeInt(uid);
+ history.writeToStream(out);
+ }
+
+ mUidFile.finishWrite(fos);
+ } catch (IOException e) {
+ if (fos != null) {
+ mUidFile.failWrite(fos);
}
}
}
@@ -590,7 +730,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
if (argSet.contains("poll")) {
- performPollLocked();
+ performPollLocked(true);
pw.println("Forced poll");
return;
}
@@ -603,17 +743,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
pw.println("Known historical stats:");
- for (InterfaceIdentity ident : mSummaryStats.keySet()) {
- final NetworkStatsHistory stats = mSummaryStats.get(ident);
+ for (InterfaceIdentity ident : mNetworkStats.keySet()) {
+ final NetworkStatsHistory stats = mNetworkStats.get(ident);
pw.print(" ident="); pw.println(ident.toString());
stats.dump(" ", pw);
}
if (argSet.contains("detail")) {
- pw.println("Known detail stats:");
- for (int i = 0; i < mDetailStats.size(); i++) {
- final int uid = mDetailStats.keyAt(i);
- final NetworkStatsHistory stats = mDetailStats.valueAt(i);
+ // since explicitly requested with argument, we're okay to load
+ // from disk if not already in memory.
+ ensureUidStatsLoadedLocked();
+ pw.println("Known UID stats:");
+ for (int i = 0; i < mUidStats.size(); i++) {
+ final int uid = mUidStats.keyAt(i);
+ final NetworkStatsHistory stats = mUidStats.valueAt(i);
pw.print(" UID="); pw.println(uid);
stats.dump(" ", pw);
}
@@ -627,47 +770,29 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Deprecated
private void generateRandomLocked() {
long end = System.currentTimeMillis();
- long start = end - mSummaryMaxHistory.get();
+ long start = end - mSettings.getNetworkMaxHistory();
long rx = 3 * GB_IN_BYTES;
long tx = 2 * GB_IN_BYTES;
- mSummaryStats.clear();
+ mNetworkStats.clear();
for (InterfaceIdentity ident : mActiveIface.values()) {
- final NetworkStatsHistory stats = findOrCreateSummaryLocked(ident);
+ final NetworkStatsHistory stats = findOrCreateNetworkLocked(ident);
stats.generateRandom(start, end, rx, tx);
}
end = System.currentTimeMillis();
- start = end - mDetailMaxHistory.get();
+ start = end - mSettings.getUidMaxHistory();
rx = 500 * MB_IN_BYTES;
tx = 100 * MB_IN_BYTES;
- mDetailStats.clear();
+ mUidStats.clear();
for (ApplicationInfo info : mContext.getPackageManager().getInstalledApplications(0)) {
final int uid = info.uid;
- final NetworkStatsHistory stats = findOrCreateDetailLocked(uid);
+ final NetworkStatsHistory stats = findOrCreateUidLocked(uid);
stats.generateRandom(start, end, rx, tx);
}
}
- private class LongSecureSetting {
- private String mKey;
- private long mDefaultValue;
-
- public LongSecureSetting(String key, long defaultValue) {
- mKey = key;
- mDefaultValue = defaultValue;
- }
-
- public long get() {
- if (mContext != null) {
- return Settings.Secure.getLong(mContext.getContentResolver(), mKey, mDefaultValue);
- } else {
- return mDefaultValue;
- }
- }
- }
-
/**
* Return the delta between two {@link NetworkStats} snapshots, where {@code
* before} can be {@code null}.
@@ -686,4 +811,54 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return telephony.getSubscriberId();
}
+ private int estimateNetworkBuckets() {
+ return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration());
+ }
+
+ private int estimateUidBuckets() {
+ return (int) (mSettings.getUidMaxHistory() / mSettings.getUidBucketDuration());
+ }
+
+ private static int estimateResizeBuckets(NetworkStatsHistory existing, long newBucketDuration) {
+ return (int) (existing.bucketCount * existing.bucketDuration / newBucketDuration);
+ }
+
+ /**
+ * Default external settings that read from {@link Settings.Secure}.
+ */
+ private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
+ private final ContentResolver mResolver;
+
+ public DefaultNetworkStatsSettings(Context context) {
+ mResolver = checkNotNull(context.getContentResolver());
+ // TODO: adjust these timings for production builds
+ }
+
+ private long getSecureLong(String name, long def) {
+ return Settings.Secure.getLong(mResolver, name, def);
+ }
+
+ public long getPollInterval() {
+ return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
+ }
+ public long getPersistThreshold() {
+ return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 16 * KB_IN_BYTES);
+ }
+ public long getNetworkBucketDuration() {
+ return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS);
+ }
+ public long getNetworkMaxHistory() {
+ return getSecureLong(NETSTATS_NETWORK_MAX_HISTORY, 90 * DAY_IN_MILLIS);
+ }
+ public long getUidBucketDuration() {
+ return getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS);
+ }
+ public long getUidMaxHistory() {
+ return getSecureLong(NETSTATS_UID_MAX_HISTORY, 90 * DAY_IN_MILLIS);
+ }
+ public long getTimeCacheMaxAge() {
+ return DAY_IN_MILLIS;
+ }
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 1eeb56b..f831ca3 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -357,8 +357,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
expectTime(TIME_MAR_10 + elapsedRealtime);
// pretend that 512 bytes total have happened
- stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
- TEST_IFACE, UID_ALL, 256L, 256L).build();
+ stats = new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, 256L, 256L);
expect(mStatsService.getSummaryForNetwork(TIME_FEB_15, TIME_MAR_10, TEMPLATE_WIFI, null))
.andReturn(stats).atLeastOnce();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 9846372..2457ff3 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -18,10 +18,13 @@ package com.android.server;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.TEMPLATE_WIFI;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
import static org.easymock.EasyMock.anyLong;
import static org.easymock.EasyMock.createMock;
@@ -47,6 +50,7 @@ import android.test.suitebuilder.annotation.LargeTest;
import android.util.TrustedTime;
import com.android.server.net.NetworkStatsService;
+import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import org.easymock.EasyMock;
@@ -62,12 +66,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private static final String TEST_IFACE = "test0";
private static final long TEST_START = 1194220800000L;
+ private static final int TEST_UID_1 = 1001;
+ private static final int TEST_UID_2 = 1002;
+
private BroadcastInterceptingContext mServiceContext;
private File mStatsDir;
private INetworkManagementService mNetManager;
private IAlarmManager mAlarmManager;
private TrustedTime mTime;
+ private NetworkStatsSettings mSettings;
private IConnectivityManager mConnManager;
private NetworkStatsService mService;
@@ -82,12 +90,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mNetManager = createMock(INetworkManagementService.class);
mAlarmManager = createMock(IAlarmManager.class);
mTime = createMock(TrustedTime.class);
+ mSettings = createMock(NetworkStatsSettings.class);
mConnManager = createMock(IConnectivityManager.class);
mService = new NetworkStatsService(
- mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir);
+ mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
mService.bindConnectivityManager(mConnManager);
+ expectDefaultSettings();
expectSystemReady();
replay();
@@ -114,115 +124,93 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
super.tearDown();
}
- private static NetworkState buildWifi() {
- final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
- info.setDetailedState(DetailedState.CONNECTED, null, null);
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null);
- }
-
- public void testHistoryForWifi() throws Exception {
+ public void testSummaryStatsWifi() throws Exception {
long elapsedRealtime = 0;
- NetworkState[] state = null;
- NetworkStats stats = null;
- NetworkStats detail = null;
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- state = new NetworkState[] { buildWifi() };
- stats = new NetworkStats.Builder(elapsedRealtime, 0).build();
- detail = new NetworkStats.Builder(elapsedRealtime, 0).build();
-
- expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkState(buildWifiState());
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
- verifyAndReset();
// verify service has empty history for wifi
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
+ verifyAndReset();
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
- stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
- TEST_IFACE, UID_ALL, 1024L, 2048L).build();
-
- expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
+ expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- verifyAndReset();
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
+ verifyAndReset();
// and bump forward again, with counters going higher. this is
// important, since polling should correctly subtract last snapshot.
elapsedRealtime += DAY_IN_MILLIS;
- stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
- TEST_IFACE, UID_ALL, 4096L, 8192L).build();
-
- expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, 4096L, 8192L));
+ expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- verifyAndReset();
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 4096L, 8192L);
+ verifyAndReset();
+
}
- public void testHistoryForRebootPersist() throws Exception {
+ public void testStatsRebootPersist() throws Exception {
long elapsedRealtime = 0;
- NetworkState[] state = null;
- NetworkStats stats = null;
- NetworkStats detail = null;
-
- // assert that no stats file exists
- final File statsFile = new File(mStatsDir, "netstats.bin");
- assertFalse(statsFile.exists());
+ assertStatsFilesExist(false);
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- state = new NetworkState[] { buildWifi() };
- stats = new NetworkStats.Builder(elapsedRealtime, 0).build();
- detail = new NetworkStats.Builder(elapsedRealtime, 0).build();
-
- expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkState(buildWifiState());
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
- verifyAndReset();
// verify service has empty history for wifi
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
+ verifyAndReset();
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
- stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
- TEST_IFACE, UID_ALL, 1024L, 2048L).build();
-
- expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
+ // TODO: switch these stats to specific iface
+ expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
+ .addEntry(IFACE_ALL, TEST_UID_1, 512L, 256L)
+ .addEntry(IFACE_ALL, TEST_UID_2, 128L, 128L));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- verifyAndReset();
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
+ assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
+ assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
+ verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
// clear any values in memory.
@@ -230,18 +218,84 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// talk with zombie service to assert stats have gone; and assert that
// we persisted them to file.
+ expectDefaultSettings();
+ replay();
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
- assertTrue(statsFile.exists());
+ verifyAndReset();
+
+ assertStatsFilesExist(true);
// boot through serviceReady() again
+ expectDefaultSettings();
expectSystemReady();
replay();
mService.systemReady();
- verifyAndReset();
// after systemReady(), we should have historical stats loaded again
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
+ assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
+ assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
+ verifyAndReset();
+
+ }
+
+ public void testStatsBucketResize() throws Exception {
+ long elapsedRealtime = 0;
+ NetworkStatsHistory history = null;
+ long[] total = null;
+
+ assertStatsFilesExist(false);
+
+ // pretend that wifi network comes online; service should ask about full
+ // network state, and poll any existing interfaces before updating.
+ expectTime(TEST_START + elapsedRealtime);
+ expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ expectNetworkState(buildWifiState());
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
+ verifyAndReset();
+
+ // modify some number on wifi, and trigger poll event
+ elapsedRealtime += 2 * HOUR_IN_MILLIS;
+ expectTime(TEST_START + elapsedRealtime);
+ expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, 512L, 512L));
+ expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify service recorded history
+ history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
+ total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
+ assertEquals(512L, total[0]);
+ assertEquals(512L, total[1]);
+ assertEquals(HOUR_IN_MILLIS, history.bucketDuration);
+ assertEquals(2, history.bucketCount);
+ verifyAndReset();
+
+ // now change bucket duration setting and trigger another poll with
+ // exact same values, which should resize existing buckets.
+ expectTime(TEST_START + elapsedRealtime);
+ expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify identical stats, but spread across 4 buckets now
+ history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
+ total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
+ assertEquals(512L, total[0]);
+ assertEquals(512L, total[1]);
+ assertEquals(30 * MINUTE_IN_MILLIS, history.bucketDuration);
+ assertEquals(4, history.bucketCount);
+ verifyAndReset();
}
@@ -252,6 +306,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertEquals(tx, total[1]);
}
+ private void assertUidTotal(int uid, int template, long rx, long tx) {
+ final NetworkStatsHistory history = mService.getHistoryForUid(uid, template);
+ final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
+ assertEquals(rx, total[0]);
+ assertEquals(tx, total[1]);
+ }
+
private void expectSystemReady() throws Exception {
mAlarmManager.remove(isA(PendingIntent.class));
expectLastCall().anyTimes();
@@ -261,7 +322,34 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectLastCall().atLeastOnce();
}
- public void expectTime(long currentTime) throws Exception {
+ private void expectNetworkState(NetworkState... state) throws Exception {
+ expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
+ }
+
+ private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
+ expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
+ }
+
+ private void expectNetworkStatsDetail(NetworkStats detail) throws Exception {
+ expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
+ }
+
+ private void expectDefaultSettings() throws Exception {
+ expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ }
+
+ private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
+ throws Exception {
+ expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
+ expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
+ expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();
+ expect(mSettings.getNetworkMaxHistory()).andReturn(maxHistory).anyTimes();
+ expect(mSettings.getUidBucketDuration()).andReturn(bucketDuration).anyTimes();
+ expect(mSettings.getUidMaxHistory()).andReturn(maxHistory).anyTimes();
+ expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
+ }
+
+ private void expectTime(long currentTime) throws Exception {
expect(mTime.forceRefresh()).andReturn(false).anyTimes();
expect(mTime.hasCache()).andReturn(true).anyTimes();
expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes();
@@ -269,12 +357,36 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
+ private void assertStatsFilesExist(boolean exist) {
+ final File summaryFile = new File(mStatsDir, "netstats.bin");
+ final File detailFile = new File(mStatsDir, "netstats_uid.bin");
+ if (exist) {
+ assertTrue(summaryFile.exists());
+ assertTrue(detailFile.exists());
+ } else {
+ assertFalse(summaryFile.exists());
+ assertFalse(detailFile.exists());
+ }
+ }
+
+ private static NetworkState buildWifiState() {
+ final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
+ info.setDetailedState(DetailedState.CONNECTED, null, null);
+ final LinkProperties prop = new LinkProperties();
+ prop.setInterfaceName(TEST_IFACE);
+ return new NetworkState(info, prop, null);
+ }
+
+ private static NetworkStats buildEmptyStats(long elapsedRealtime) {
+ return new NetworkStats(elapsedRealtime, 0);
+ }
+
private void replay() {
- EasyMock.replay(mNetManager, mAlarmManager, mTime, mConnManager);
+ EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
}
private void verifyAndReset() {
- EasyMock.verify(mNetManager, mAlarmManager, mTime, mConnManager);
- EasyMock.reset(mNetManager, mAlarmManager, mTime, mConnManager);
+ EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
+ EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index d1ee4f6..30afdd8 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -288,11 +288,10 @@ public class ThrottleServiceTest extends AndroidTestCase {
*/
public void expectGetInterfaceCounter(long rx, long tx) throws Exception {
// TODO: provide elapsedRealtime mock to match TimeAuthority
- final NetworkStats.Builder stats = new NetworkStats.Builder(
- SystemClock.elapsedRealtime(), 1);
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
stats.addEntry(TEST_IFACE, NetworkStats.UID_ALL, rx, tx);
- expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats.build()).atLeastOnce();
+ expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
}
/**