Merge "Hide RTL related APIs - DO NOT MERGE" into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 5804c0f..a3c4901 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3762,12 +3762,18 @@
ctor public Notification.BigPictureStyle();
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
+ method public android.app.Notification build();
+ method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence);
}
public static class Notification.BigTextStyle extends android.app.Notification.Style {
ctor public Notification.BigTextStyle();
ctor public Notification.BigTextStyle(android.app.Notification.Builder);
method public android.app.Notification.BigTextStyle bigText(java.lang.CharSequence);
+ method public android.app.Notification build();
+ method public android.app.Notification.BigTextStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.app.Notification.BigTextStyle setSummaryText(java.lang.CharSequence);
}
public static class Notification.Builder {
@@ -3809,11 +3815,18 @@
ctor public Notification.InboxStyle();
ctor public Notification.InboxStyle(android.app.Notification.Builder);
method public android.app.Notification.InboxStyle addLine(java.lang.CharSequence);
+ method public android.app.Notification build();
+ method public android.app.Notification.InboxStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.app.Notification.InboxStyle setSummaryText(java.lang.CharSequence);
}
- public static class Notification.Style {
+ public static abstract class Notification.Style {
ctor public Notification.Style();
- method public android.app.Notification build();
+ method public abstract android.app.Notification build();
+ method protected void checkBuilder();
+ method protected android.widget.RemoteViews getStandardView(int);
+ method protected void internalSetBigContentTitle(java.lang.CharSequence);
+ method protected void internalSetSummaryText(java.lang.CharSequence);
method public void setBuilder(android.app.Notification.Builder);
field protected android.app.Notification.Builder mBuilder;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8f4efab..b60eed9 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1397,7 +1397,8 @@
if (mSubText != null) {
contentView.setTextViewText(R.id.text, mSubText);
- contentView.setViewVisibility(R.id.text2, View.VISIBLE);
+ contentView.setViewVisibility(R.id.text2,
+ mContentText != null ? View.VISIBLE : View.GONE);
} else {
contentView.setViewVisibility(R.id.text2, View.GONE);
if (mProgressMax != 0 || mProgressIndeterminate) {
@@ -1428,12 +1429,12 @@
int N = mActions.size();
if (N > 0) {
- Log.d("Notification", "has actions: " + mContentText);
+ // Log.d("Notification", "has actions: " + mContentText);
big.setViewVisibility(R.id.actions, View.VISIBLE);
if (N>3) N=3;
for (int i=0; i<N; i++) {
final RemoteViews button = generateActionButton(mActions.get(i));
- Log.d("Notification", "adding action " + i + ": " + mActions.get(i).title);
+ //Log.d("Notification", "adding action " + i + ": " + mActions.get(i).title);
big.addView(R.id.actions, button);
}
}
@@ -1549,9 +1550,28 @@
* An object that can apply a rich notification style to a {@link Notification.Builder}
* object.
*/
- public static class Style {
+ public static abstract class Style
+ {
+ private CharSequence mBigContentTitle;
+ private CharSequence mSummaryText = null;
+
protected Builder mBuilder;
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ protected void internalSetBigContentTitle(CharSequence title) {
+ mBigContentTitle = title;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ protected void internalSetSummaryText(CharSequence cs) {
+ mSummaryText = cs;
+ }
+
public void setBuilder(Builder builder) {
if (mBuilder != builder) {
mBuilder = builder;
@@ -1559,12 +1579,42 @@
}
}
- public Notification build() {
+ protected void checkBuilder() {
if (mBuilder == null) {
throw new IllegalArgumentException("Style requires a valid Builder object");
}
- return mBuilder.buildUnstyled();
}
+
+ protected RemoteViews getStandardView(int layoutId) {
+ checkBuilder();
+
+ if (mBigContentTitle != null) {
+ mBuilder.setContentTitle(mBigContentTitle);
+ }
+
+ if (mBuilder.mSubText == null) {
+ mBuilder.setContentText(null);
+ }
+
+ RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId);
+
+ if (mBuilder.mSubText == null) {
+ contentView.setViewVisibility(R.id.line3, View.GONE);
+ }
+
+ if (mBigContentTitle != null && mBigContentTitle.equals("")) {
+ contentView.setViewVisibility(R.id.line1, View.GONE);
+ }
+
+ if (mSummaryText != null && !mSummaryText.equals("")) {
+ contentView.setViewVisibility(R.id.overflow_title, View.VISIBLE);
+ contentView.setTextViewText(R.id.overflow_title, mSummaryText);
+ }
+
+ return contentView;
+ }
+
+ public abstract Notification build();
}
/**
@@ -1594,13 +1644,30 @@
setBuilder(builder);
}
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public BigPictureStyle setBigContentTitle(CharSequence title) {
+ internalSetBigContentTitle(title);
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public BigPictureStyle setSummaryText(CharSequence cs) {
+ internalSetSummaryText(cs);
+ return this;
+ }
+
public BigPictureStyle bigPicture(Bitmap b) {
mPicture = b;
return this;
}
private RemoteViews makeBigContentView() {
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_big_picture);
+ RemoteViews contentView = getStandardView(R.layout.notification_template_big_picture);
contentView.setImageViewBitmap(R.id.big_picture, mPicture);
@@ -1609,9 +1676,7 @@
@Override
public Notification build() {
- if (mBuilder == null) {
- throw new IllegalArgumentException("Style requires a valid Builder object");
- }
+ checkBuilder();
Notification wip = mBuilder.buildUnstyled();
wip.bigContentView = makeBigContentView();
return wip;
@@ -1645,26 +1710,39 @@
setBuilder(builder);
}
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public BigTextStyle setBigContentTitle(CharSequence title) {
+ internalSetBigContentTitle(title);
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public BigTextStyle setSummaryText(CharSequence cs) {
+ internalSetSummaryText(cs);
+ return this;
+ }
+
public BigTextStyle bigText(CharSequence cs) {
mBigText = cs;
return this;
}
private RemoteViews makeBigContentView() {
- int bigTextId = R.layout.notification_template_big_text;
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(bigTextId);
+ RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
contentView.setTextViewText(R.id.big_text, mBigText);
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
- contentView.setViewVisibility(R.id.text2, View.GONE);
return contentView;
}
@Override
public Notification build() {
- if (mBuilder == null) {
- throw new IllegalArgumentException("Style requires a valid Builder object");
- }
+ checkBuilder();
Notification wip = mBuilder.buildUnstyled();
wip.bigContentView = makeBigContentView();
return wip;
@@ -1678,12 +1756,14 @@
* <pre class="prettyprint">
* Notification noti = new Notification.InboxStyle(
* new Notification.Builder()
- * .setContentTitle("New mail from " + sender.toString())
+ * .setContentTitle("5 New mails from " + sender.toString())
* .setContentText(subject)
* .setSmallIcon(R.drawable.new_mail)
* .setLargeIcon(aBitmap))
* .addLine(str1)
* .addLine(str2)
+ * .setContentTitle("")
+ * .setSummaryText("+3 more")
* .build();
* </pre>
*
@@ -1699,16 +1779,35 @@
setBuilder(builder);
}
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public InboxStyle setBigContentTitle(CharSequence title) {
+ internalSetBigContentTitle(title);
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public InboxStyle setSummaryText(CharSequence cs) {
+ internalSetSummaryText(cs);
+ return this;
+ }
+
public InboxStyle addLine(CharSequence cs) {
mTexts.add(cs);
return this;
}
private RemoteViews makeBigContentView() {
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_inbox);
+ RemoteViews contentView = getStandardView(R.layout.notification_template_inbox);
+ contentView.setViewVisibility(R.id.text2, View.GONE);
- int[] rowIds = {R.id.inbox_text0, R.id.inbox_text1, R.id.inbox_text2, R.id.inbox_text3, R.id.inbox_text4};
-
+ int[] rowIds = {R.id.inbox_text0, R.id.inbox_text1, R.id.inbox_text2, R.id.inbox_text3,
+ R.id.inbox_text4};
+
int i=0;
while (i < mTexts.size() && i < rowIds.length) {
CharSequence str = mTexts.get(i);
@@ -1724,9 +1823,7 @@
@Override
public Notification build() {
- if (mBuilder == null) {
- throw new IllegalArgumentException("Style requires a valid Builder object");
- }
+ checkBuilder();
Notification wip = mBuilder.buildUnstyled();
wip.bigContentView = makeBigContentView();
return wip;
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 08d4c6c..b7b8731 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -42,5 +42,7 @@
void setUidForeground(int uid, boolean uidForeground);
/** Force update of statistics. */
void forceUpdate();
+ /** Advise persistance threshold; may be overridden internally. */
+ void advisePersistThreshold(long thresholdBytes);
}
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 4ac5e76..3c67bf9 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -158,9 +158,14 @@
}
} else if (type == TYPE_WIFI) {
- final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- final WifiInfo info = wifi.getConnectionInfo();
- networkId = info != null ? info.getSSID() : null;
+ if (state.networkId != null) {
+ networkId = state.networkId;
+ } else {
+ final WifiManager wifi = (WifiManager) context.getSystemService(
+ Context.WIFI_SERVICE);
+ final WifiInfo info = wifi.getConnectionInfo();
+ networkId = info != null ? info.getSSID() : null;
+ }
}
return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index 2fc69ad..fbe1f82 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -31,18 +31,20 @@
public final LinkCapabilities linkCapabilities;
/** Currently only used by testing. */
public final String subscriberId;
+ public final String networkId;
public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
LinkCapabilities linkCapabilities) {
- this(networkInfo, linkProperties, linkCapabilities, null);
+ this(networkInfo, linkProperties, linkCapabilities, null, null);
}
public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
- LinkCapabilities linkCapabilities, String subscriberId) {
+ LinkCapabilities linkCapabilities, String subscriberId, String networkId) {
this.networkInfo = networkInfo;
this.linkProperties = linkProperties;
this.linkCapabilities = linkCapabilities;
this.subscriberId = subscriberId;
+ this.networkId = networkId;
}
public NetworkState(Parcel in) {
@@ -50,6 +52,7 @@
linkProperties = in.readParcelable(null);
linkCapabilities = in.readParcelable(null);
subscriberId = in.readString();
+ networkId = in.readString();
}
@Override
@@ -63,6 +66,7 @@
out.writeParcelable(linkProperties, flags);
out.writeParcelable(linkCapabilities, flags);
out.writeString(subscriberId);
+ out.writeString(networkId);
}
public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 6ecc640..e7ea355 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -238,7 +238,8 @@
* Return global network statistics summarized at an interface level,
* without any UID-level granularity.
*/
- NetworkStats getNetworkStatsSummary();
+ NetworkStats getNetworkStatsSummaryDev();
+ NetworkStats getNetworkStatsSummaryXt();
/**
* Return detailed network statistics with UID-level granularity,
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
index b35dd1e..13a692e 100644
--- a/core/java/android/util/MathUtils.java
+++ b/core/java/android/util/MathUtils.java
@@ -39,6 +39,10 @@
return amount < low ? low : (amount > high ? high : amount);
}
+ public static long constrain(long amount, long low, long high) {
+ return amount < low ? low : (amount > high ? high : amount);
+ }
+
public static float constrain(float amount, float low, float high) {
return amount < low ? low : (amount > high ? high : amount);
}
diff --git a/core/java/android/webkit/AutoCompletePopup.java b/core/java/android/webkit/AutoCompletePopup.java
index 21d5e02..87e878b 100644
--- a/core/java/android/webkit/AutoCompletePopup.java
+++ b/core/java/android/webkit/AutoCompletePopup.java
@@ -28,12 +28,15 @@
import android.widget.Filterable;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
+import android.widget.PopupWindow.OnDismissListener;
-class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener {
+class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener,
+ OnDismissListener{
private static class AnchorView extends View {
AnchorView(Context context) {
super(context);
setFocusable(false);
+ setVisibility(INVISIBLE);
}
}
private static final int AUTOFILL_FORM = 100;
@@ -48,17 +51,10 @@
private WebViewClassic.WebViewInputConnection mInputConnection;
private WebViewClassic mWebView;
- public AutoCompletePopup(Context context,
- WebViewClassic webView,
+ public AutoCompletePopup(WebViewClassic webView,
WebViewClassic.WebViewInputConnection inputConnection) {
mInputConnection = inputConnection;
mWebView = webView;
- mPopup = new ListPopupWindow(context);
- mAnchor = new AnchorView(context);
- mWebView.getWebView().addView(mAnchor);
- mPopup.setOnItemClickListener(this);
- mPopup.setAnchorView(mAnchor);
- mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -72,6 +68,9 @@
}
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (mPopup == null) {
+ return false;
+ }
if (keyCode == KeyEvent.KEYCODE_BACK && mPopup.isShowing()) {
// special case for the back key, we do not even try to send it
// to the drop down list but instead, consume it immediately
@@ -112,11 +111,14 @@
public void clearAdapter() {
mAdapter = null;
mFilter = null;
- mPopup.dismiss();
- mPopup.setAdapter(null);
+ if (mPopup != null) {
+ mPopup.dismiss();
+ mPopup.setAdapter(null);
+ }
}
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+ ensurePopup();
mPopup.setAdapter(adapter);
mAdapter = adapter;
if (adapter != null) {
@@ -129,6 +131,7 @@
}
public void resetRect() {
+ ensurePopup();
int left = mWebView.contentToViewX(mWebView.mEditTextContentBounds.left);
int right = mWebView.contentToViewX(mWebView.mEditTextContentBounds.right);
int width = right - left;
@@ -164,6 +167,9 @@
// AdapterView.OnItemClickListener implementation
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (mPopup == null) {
+ return;
+ }
if (id == 0 && position == 0 && mInputConnection.getIsAutoFillable()) {
mText = "";
pushTextToInputConnection();
@@ -206,6 +212,7 @@
@Override
public void onFilterComplete(int count) {
+ ensurePopup();
boolean showDropDown = (count > 0) &&
(mInputConnection.getIsAutoFillable() || mText.length() > 0);
if (showDropDown) {
@@ -219,5 +226,23 @@
mPopup.dismiss();
}
}
+
+ @Override
+ public void onDismiss() {
+ mWebView.getWebView().removeView(mAnchor);
+ }
+
+ private void ensurePopup() {
+ if (mPopup == null) {
+ mPopup = new ListPopupWindow(mWebView.getContext());
+ mAnchor = new AnchorView(mWebView.getContext());
+ mWebView.getWebView().addView(mAnchor);
+ mPopup.setOnItemClickListener(this);
+ mPopup.setAnchorView(mAnchor);
+ mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
+ } else if (mWebView.getWebView().indexOfChild(mAnchor) < 0) {
+ mWebView.getWebView().addView(mAnchor);
+ }
+ }
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 75e7b57..1bab91f 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -4696,8 +4696,7 @@
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (mInputConnection == null) {
mInputConnection = new WebViewInputConnection();
- mAutoCompletePopup = new AutoCompletePopup(mContext, this,
- mInputConnection);
+ mAutoCompletePopup = new AutoCompletePopup(this, mInputConnection);
}
mInputConnection.setupEditorInfo(outAttrs);
return mInputConnection;
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index d59585f..8b222f0 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -24,20 +24,12 @@
import android.net.NetworkStats;
import android.os.StrictMode;
import android.os.SystemClock;
-import android.util.Slog;
import com.android.internal.util.ProcFileReader;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.StringTokenizer;
import libcore.io.IoUtils;
@@ -50,14 +42,10 @@
// TODO: consider moving parsing to native code
- /** Path to {@code /proc/net/dev}. */
- @Deprecated
- private final File mStatsIface;
- /** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
- @Deprecated
- private final File mStatsXtIface;
/** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
private final File mStatsXtIfaceAll;
+ /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */
+ private final File mStatsXtIfaceFmt;
/** Path to {@code /proc/net/xt_qtaguid/stats}. */
private final File mStatsXtUid;
@@ -67,28 +55,20 @@
// @VisibleForTesting
public NetworkStatsFactory(File procRoot) {
- mStatsIface = new File(procRoot, "net/dev");
- mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
- mStatsXtIface = new File(procRoot, "net/xt_qtaguid/iface_stat");
mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
+ mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
+ mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
}
/**
- * Parse and return interface-level summary {@link NetworkStats}. Values
- * monotonically increase since device boot, and may include details about
- * inactive interfaces.
+ * Parse and return interface-level summary {@link NetworkStats} measured
+ * using {@code /proc/net/dev} style hooks, which may include non IP layer
+ * traffic. Values monotonically increase since device boot, and may include
+ * details about inactive interfaces.
*
* @throws IllegalStateException when problem parsing stats.
*/
- public NetworkStats readNetworkStatsSummary() throws IllegalStateException {
- if (mStatsXtIfaceAll.exists()) {
- return readNetworkStatsSummarySingleFile();
- } else {
- return readNetworkStatsSummaryMultipleFiles();
- }
- }
-
- private NetworkStats readNetworkStatsSummarySingleFile() {
+ public NetworkStats readNetworkStatsSummaryDev() throws IllegalStateException {
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
@@ -137,79 +117,40 @@
}
/**
- * @deprecated remove once {@code iface_stat_all} is merged to all kernels.
+ * Parse and return interface-level summary {@link NetworkStats}. Designed
+ * to return only IP layer traffic. Values monotonically increase since
+ * device boot, and may include details about inactive interfaces.
+ *
+ * @throws IllegalStateException when problem parsing stats.
*/
- @Deprecated
- private NetworkStats readNetworkStatsSummaryMultipleFiles() {
+ public NetworkStats readNetworkStatsSummaryXt() throws IllegalStateException {
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+ // return null when kernel doesn't support
+ if (!mStatsXtIfaceFmt.exists()) return null;
+
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
final NetworkStats.Entry entry = new NetworkStats.Entry();
- final HashSet<String> knownIfaces = Sets.newHashSet();
- final HashSet<String> activeIfaces = Sets.newHashSet();
-
- // collect any historical stats and active state
- for (String iface : fileListWithoutNull(mStatsXtIface)) {
- final File ifacePath = new File(mStatsXtIface, iface);
-
- final long active = readSingleLongFromFile(new File(ifacePath, "active"));
- if (active == 1) {
- knownIfaces.add(iface);
- activeIfaces.add(iface);
- } else if (active == 0) {
- knownIfaces.add(iface);
- } else {
- continue;
- }
-
- entry.iface = iface;
- entry.uid = UID_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
- entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes"));
- entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets"));
- entry.txBytes = readSingleLongFromFile(new File(ifacePath, "tx_bytes"));
- entry.txPackets = readSingleLongFromFile(new File(ifacePath, "tx_packets"));
-
- stats.addValues(entry);
- }
-
- final ArrayList<String> values = Lists.newArrayList();
-
- BufferedReader reader = null;
+ ProcFileReader reader = null;
try {
- reader = new BufferedReader(new FileReader(mStatsIface));
+ // open and consume header line
+ reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceFmt));
+ reader.finishLine();
- // skip first two header lines
- reader.readLine();
- reader.readLine();
+ while (reader.hasMoreData()) {
+ entry.iface = reader.nextString();
+ entry.uid = UID_ALL;
+ entry.set = SET_ALL;
+ entry.tag = TAG_NONE;
- // parse remaining lines
- String line;
- while ((line = reader.readLine()) != null) {
- splitLine(line, values);
+ entry.rxBytes = reader.nextLong();
+ entry.rxPackets = reader.nextLong();
+ entry.txBytes = reader.nextLong();
+ entry.txPackets = reader.nextLong();
- try {
- entry.iface = values.get(0);
- entry.uid = UID_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
- entry.rxBytes = Long.parseLong(values.get(1));
- entry.rxPackets = Long.parseLong(values.get(2));
- entry.txBytes = Long.parseLong(values.get(9));
- entry.txPackets = Long.parseLong(values.get(10));
-
- if (activeIfaces.contains(entry.iface)) {
- // combine stats when iface is active
- stats.combineValues(entry);
- } else if (!knownIfaces.contains(entry.iface)) {
- // add stats when iface is unknown
- stats.addValues(entry);
- }
- } catch (NumberFormatException e) {
- Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);
- }
+ stats.addValues(entry);
+ reader.finishLine();
}
} catch (NullPointerException e) {
throw new IllegalStateException("problem parsing stats: " + e);
@@ -221,7 +162,6 @@
IoUtils.closeQuietly(reader);
StrictMode.setThreadPolicy(savedPolicy);
}
-
return stats;
}
@@ -286,41 +226,4 @@
return stats;
}
-
- /**
- * Split given line into {@link ArrayList}.
- */
- @Deprecated
- private static void splitLine(String line, ArrayList<String> outSplit) {
- outSplit.clear();
-
- final StringTokenizer t = new StringTokenizer(line, " \t\n\r\f:");
- while (t.hasMoreTokens()) {
- outSplit.add(t.nextToken());
- }
- }
-
- /**
- * Utility method to read a single plain-text {@link Long} from the given
- * {@link File}, usually from a {@code /proc/} filesystem.
- */
- private static long readSingleLongFromFile(File file) {
- try {
- final byte[] buffer = IoUtils.readFileAsByteArray(file.toString());
- return Long.parseLong(new String(buffer).trim());
- } catch (NumberFormatException e) {
- return -1;
- } catch (IOException e) {
- return -1;
- }
- }
-
- /**
- * Wrapper for {@link File#list()} that returns empty array instead of
- * {@code null}.
- */
- private static String[] fileListWithoutNull(File file) {
- final String[] list = file.list();
- return list != null ? list : new String[0];
- }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 86118b1..5157385 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5719,7 +5719,7 @@
if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
try {
- mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummary();
+ mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummaryDev();
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e);
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index a33b46a..2bd36c3 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -739,18 +739,18 @@
#endif
}
-
-size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
- // Reset kerning
- mShaperItem.kerning_applied = false;
-
- // Update Harfbuzz Shaper
- mShaperItem.item.bidiLevel = isRTL;
-
- SkTypeface* typeface = paint->getTypeface();
-
+/**
+ * Return the first typeface in the logical change, starting with this typeface,
+ * that contains the specified unichar, or NULL if none is found.
+ *
+ * Note that this function does _not_ increment the reference count on the typeface, as the
+ * assumption is that its lifetime is managed elsewhere - in particular, the fallback typefaces
+ * for the default font live in a global cache.
+ */
+SkTypeface* TextLayoutShaper::typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
+ SkUnichar unichar, HB_Script script) {
// Set the correct Typeface depending on the script
- switch (mShaperItem.item.script) {
+ switch (script) {
case HB_Script_Arabic:
typeface = getCachedTypeface(&mArabicTypeface, TYPEFACE_ARABIC);
#if DEBUG_GLYPHS
@@ -815,32 +815,31 @@
break;
default:
- if (!typeface) {
- typeface = mDefaultTypeface;
#if DEBUG_GLYPHS
- ALOGD("Using Default Typeface");
-#endif
- } else {
-#if DEBUG_GLYPHS
+ if (typeface) {
ALOGD("Using Paint Typeface");
-#endif
}
+#endif
break;
}
+ return typeface;
+}
- mShapingPaint.setTypeface(typeface);
- mShaperItem.face = getCachedHBFace(typeface);
+size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
+ // Reset kerning
+ mShaperItem.kerning_applied = false;
-#if DEBUG_GLYPHS
- ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
- typeface, typeface->uniqueID(), mShaperItem.face);
-#endif
+ // Update Harfbuzz Shaper
+ mShaperItem.item.bidiLevel = isRTL;
+
+ SkTypeface* typeface = paint->getTypeface();
// Get the glyphs base count for offsetting the glyphIDs returned by Harfbuzz
// This is needed as the Typeface used for shaping can be not the default one
// when we are shaping any script that needs to use a fallback Font.
// If we are a "common" script we dont need to shift
size_t baseGlyphCount = 0;
+ SkUnichar firstUnichar = 0;
switch (mShaperItem.item.script) {
case HB_Script_Arabic:
case HB_Script_Hebrew:
@@ -849,7 +848,11 @@
case HB_Script_Tamil:
case HB_Script_Thai:{
const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
- SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16);
+ const uint16_t* text16End = text16 + mShaperItem.item.length;
+ firstUnichar = SkUTF16_NextUnichar(&text16);
+ while (firstUnichar == ' ' && text16 < text16End) {
+ firstUnichar = SkUTF16_NextUnichar(&text16);
+ }
baseGlyphCount = paint->getBaseGlyphCount(firstUnichar);
break;
}
@@ -857,6 +860,25 @@
break;
}
+ // We test the baseGlyphCount to see if the typeface supports the requested script
+ if (baseGlyphCount != 0) {
+ typeface = typefaceForUnichar(paint, typeface, firstUnichar, mShaperItem.item.script);
+ }
+
+ if (!typeface) {
+ typeface = mDefaultTypeface;
+#if DEBUG_GLYPHS
+ ALOGD("Using Default Typeface");
+#endif
+ }
+ mShapingPaint.setTypeface(typeface);
+ mShaperItem.face = getCachedHBFace(typeface);
+
+#if DEBUG_GLYPHS
+ ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
+ typeface, typeface->uniqueID(), mShaperItem.face);
+#endif
+
// Shape
assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0.
ensureShaperItemGlyphArrays(mShaperItem.item.length * 3 / 2);
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 3c834a4..7d7caac 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -217,6 +217,9 @@
*/
UnicodeString mBuffer;
+ SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
+ SkUnichar unichar, HB_Script script);
+
size_t shapeFontRun(const SkPaint* paint, bool isRTL);
void computeValues(const SkPaint* paint, const UChar* chars,
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index ae29537..63d20e4 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -85,6 +85,16 @@
android:ellipsize="marquee"
android:visibility="gone"
/>
+ <TextView android:id="@+id/overflow_title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
@@ -129,14 +139,5 @@
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
- <LinearLayout
- android:id="@+id/actions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone"
- >
- <!-- actions will be added here -->
- </LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
index 5de584d..097d15d 100644
--- a/core/res/res/layout/notification_template_big_base.xml
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -137,12 +137,13 @@
style="?android:attr/progressBarStyleHorizontal"
/>
<LinearLayout
- android:id="@+id/actions"
+ android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:orientation="vertical"
android:visibility="gone"
- >
- <!-- actions will be added here -->
+ >
+ <!-- actions will be added here -->
</LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index ee6adc6..a225ab1 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -100,7 +100,7 @@
/>
</LinearLayout>
<LinearLayout
- android:id="@+id/actions"
+ android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -108,6 +108,16 @@
>
<!-- actions will be added here -->
</LinearLayout>
+ <TextView android:id="@+id/overflow_title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
index 82342d4..05a3d62 100644
--- a/core/res/res/layout/notification_template_inbox.xml
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -87,6 +87,8 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:visibility="gone"
/>
<TextView android:id="@+id/inbox_text1"
@@ -95,6 +97,8 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:visibility="gone"
/>
<TextView android:id="@+id/inbox_text2"
@@ -103,6 +107,8 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:visibility="gone"
/>
<TextView android:id="@+id/inbox_text3"
@@ -111,6 +117,8 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:visibility="gone"
/>
<TextView android:id="@+id/inbox_text4"
@@ -119,9 +127,30 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:visibility="gone"
/>
<LinearLayout
+ android:id="@+id/actions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone"
+ >
+ <!-- actions will be added here -->
+ </LinearLayout>
+ <TextView android:id="@+id/overflow_title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:visibility="gone"
+ android:layout_weight="1"
+ />
+ <LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -165,13 +194,5 @@
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
- <LinearLayout
- android:id="@+id/actions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- >
- <!-- actions will be added here -->
- </LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a05ecdd..f06e30f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -99,6 +99,7 @@
<java-symbol type="id" name="issued_on" />
<java-symbol type="id" name="left_icon" />
<java-symbol type="id" name="leftSpacer" />
+ <java-symbol type="id" name="line1" />
<java-symbol type="id" name="line3" />
<java-symbol type="id" name="list_footer" />
<java-symbol type="id" name="list_item" />
@@ -121,6 +122,7 @@
<java-symbol type="id" name="old_app_action" />
<java-symbol type="id" name="old_app_description" />
<java-symbol type="id" name="old_app_icon" />
+ <java-symbol type="id" name="overflow_title" />
<java-symbol type="id" name="package_label" />
<java-symbol type="id" name="packages_list" />
<java-symbol type="id" name="pause" />
diff --git a/core/tests/coretests/res/raw/net_dev_typical b/core/tests/coretests/res/raw/net_dev_typical
deleted file mode 100644
index 290bf03..0000000
--- a/core/tests/coretests/res/raw/net_dev_typical
+++ /dev/null
@@ -1,8 +0,0 @@
-Inter-| Receive | Transmit
- face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
- lo: 8308 116 0 0 0 0 0 0 8308 116 0 0 0 0 0 0
-rmnet0: 1507570 2205 0 0 0 0 0 0 489339 2237 0 0 0 0 0 0
- ifb0: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0
- ifb1: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0
- sit0: 0 0 0 0 0 0 0 0 0 0 148 0 0 0 0 0
-ip6tnl0: 0 0 0 0 0 0 0 0 0 0 151 151 0 0 0 0
diff --git a/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical b/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical
new file mode 100644
index 0000000..656d5bb
--- /dev/null
+++ b/core/tests/coretests/res/raw/xt_qtaguid_iface_fmt_typical
@@ -0,0 +1,4 @@
+ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes total_skb_tx_packets
+rmnet2 4968 35 3081 39
+rmnet1 11153922 8051 190226 2468
+rmnet0 6824 16 5692 10
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 b994483..d3dd01a 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -81,58 +81,6 @@
assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
}
- public void testNetworkStatsSummary() throws Exception {
- stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertEquals(6, stats.size());
- assertStatsEntry(stats, "lo", UID_ALL, SET_ALL, TAG_NONE, 8308L, 8308L);
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
- assertStatsEntry(stats, "ifb0", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
- assertStatsEntry(stats, "ifb1", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
- assertStatsEntry(stats, "sit0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
- assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
- }
-
- public void testNetworkStatsSummaryDown() throws Exception {
- stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev"));
- stageLong(1L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/active"));
- stageLong(1024L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_bytes"));
- stageLong(128L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_packets"));
- stageLong(2048L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/tx_bytes"));
- stageLong(256L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/tx_packets"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertEquals(7, stats.size());
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
- assertStatsEntry(stats, "wlan0", UID_ALL, SET_ALL, TAG_NONE, 1024L, 2048L);
- }
-
- public void testNetworkStatsCombined() throws Exception {
- stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev"));
- stageLong(1L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/active"));
- stageLong(10L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_bytes"));
- stageLong(20L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_packets"));
- stageLong(30L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_bytes"));
- stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L + 10L,
- 2205L + 20L, 489339L + 30L, 2237L + 40L);
- }
-
- public void testNetworkStatsCombinedInactive() throws Exception {
- stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev"));
- stageLong(0L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/active"));
- stageLong(10L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_bytes"));
- stageLong(20L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_packets"));
- stageLong(30L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_bytes"));
- stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
-
- final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 10L, 20L, 30L, 40L);
- }
-
public void testKernelTags() throws Exception {
assertEquals(0, kernelToTag("0x0000000000000000"));
assertEquals(0x32, kernelToTag("0x0000003200000000"));
@@ -159,13 +107,24 @@
public void testNetworkStatsSingle() throws Exception {
stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
- final NetworkStats stats = mFactory.readNetworkStatsSummary();
+ final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
assertEquals(6, stats.size());
assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L);
assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L);
assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
}
+ public void testNetworkStatsXt() throws Exception {
+ stageFile(R.raw.xt_qtaguid_iface_fmt_typical,
+ new File(mTestProc, "net/xt_qtaguid/iface_stat_fmt"));
+
+ final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
+ assertEquals(3, stats.size());
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
+ assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, 2468L);
+ assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
+ }
+
/**
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
* testing purposes.
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
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 817d04d..4536a6d 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -989,9 +989,15 @@
}
@Override
- public NetworkStats getNetworkStatsSummary() {
+ public NetworkStats getNetworkStatsSummaryDev() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- return mStatsFactory.readNetworkStatsSummary();
+ return mStatsFactory.readNetworkStatsSummaryDev();
+ }
+
+ @Override
+ public NetworkStats getNetworkStatsSummaryXt() {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ return mStatsFactory.readNetworkStatsSummaryXt();
}
@Override
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index 2155147..f35a5af 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -511,7 +511,7 @@
long incRead = 0;
long incWrite = 0;
try {
- final NetworkStats stats = mNMService.getNetworkStatsSummary();
+ final NetworkStats stats = mNMService.getNetworkStatsSummaryDev();
final int index = stats.findIndex(mIface, NetworkStats.UID_ALL,
NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 8ebe224..961d042 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -118,6 +118,7 @@
import android.text.format.Formatter;
import android.text.format.Time;
import android.util.Log;
+import android.util.MathUtils;
import android.util.NtpTrustedTime;
import android.util.Slog;
import android.util.SparseArray;
@@ -166,7 +167,7 @@
*/
public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String TAG = "NetworkPolicy";
- private static final boolean LOGD = true;
+ private static final boolean LOGD = false;
private static final boolean LOGV = false;
private static final int VERSION_INIT = 1;
@@ -962,6 +963,7 @@
}
}
+ long lowestRule = Long.MAX_VALUE;
final HashSet<String> newMeteredIfaces = Sets.newHashSet();
// apply each policy that we found ifaces for; compute remaining data
@@ -985,6 +987,7 @@
+ Arrays.toString(ifaces));
}
+ final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
if (hasLimit || policy.metered) {
final long quotaBytes;
@@ -1014,6 +1017,23 @@
newMeteredIfaces.add(iface);
}
}
+
+ // keep track of lowest warning or limit of active policies
+ if (hasWarning && policy.warningBytes < lowestRule) {
+ lowestRule = policy.warningBytes;
+ }
+ if (hasLimit && policy.limitBytes < lowestRule) {
+ lowestRule = policy.limitBytes;
+ }
+ }
+
+ try {
+ // make sure stats are recorded frequently enough; we aim for 2MB
+ // threshold for 2GB/month rules.
+ final long persistThreshold = lowestRule / 1000;
+ mNetworkStats.advisePersistThreshold(persistThreshold);
+ } catch (RemoteException e) {
+ // ignored; service lives in system_server
}
// remove quota on any trailing interfaces
diff --git a/services/java/com/android/server/net/NetworkStatsCollection.java b/services/java/com/android/server/net/NetworkStatsCollection.java
index 2892a74..c2e475a 100644
--- a/services/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/java/com/android/server/net/NetworkStatsCollection.java
@@ -186,12 +186,12 @@
if (history.size() == 0) return;
noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
- final NetworkStatsHistory existing = mStats.get(key);
- if (existing != null) {
- existing.recordEntireHistory(history);
- } else {
- mStats.put(key, history);
+ NetworkStatsHistory target = mStats.get(key);
+ if (target == null) {
+ target = new NetworkStatsHistory(history.getBucketDuration());
+ mStats.put(key, target);
}
+ target.recordEntireHistory(history);
}
/**
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 57ad158..2ce7771 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -17,6 +17,8 @@
package com.android.server.net;
import static android.net.NetworkStats.TAG_NONE;
+import static android.net.TrafficStats.KB_IN_BYTES;
+import static android.net.TrafficStats.MB_IN_BYTES;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.net.NetworkStats;
@@ -25,6 +27,7 @@
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.util.Log;
+import android.util.MathUtils;
import android.util.Slog;
import com.android.internal.util.FileRotator;
@@ -58,9 +61,9 @@
private final String mCookie;
private final long mBucketDuration;
- private final long mPersistThresholdBytes;
private final boolean mOnlyTags;
+ private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
private NetworkStats mLastSnapshot;
private final NetworkStatsCollection mPending;
@@ -71,13 +74,12 @@
private WeakReference<NetworkStatsCollection> mComplete;
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
- String cookie, long bucketDuration, long persistThresholdBytes, boolean onlyTags) {
+ String cookie, long bucketDuration, boolean onlyTags) {
mRotator = checkNotNull(rotator, "missing FileRotator");
mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
mCookie = cookie;
mBucketDuration = bucketDuration;
- mPersistThresholdBytes = persistThresholdBytes;
mOnlyTags = onlyTags;
mPending = new NetworkStatsCollection(bucketDuration);
@@ -86,6 +88,12 @@
mPendingRewriter = new CombiningRewriter(mPending);
}
+ public void setPersistThreshold(long thresholdBytes) {
+ if (LOGV) Slog.v(TAG, "setPersistThreshold() with " + thresholdBytes);
+ mPersistThresholdBytes = MathUtils.constrain(
+ thresholdBytes, 1 * KB_IN_BYTES, 100 * MB_IN_BYTES);
+ }
+
public void resetLocked() {
mLastSnapshot = null;
mPending.reset();
@@ -128,6 +136,9 @@
Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
final HashSet<String> unknownIfaces = Sets.newHashSet();
+ // skip recording when snapshot missing
+ if (snapshot == null) return;
+
// assume first snapshot is bootstrap and don't record
if (mLastSnapshot == null) {
mLastSnapshot = snapshot;
@@ -150,7 +161,7 @@
continue;
}
- // skip when no delta occured
+ // skip when no delta occurred
if (entry.isEmpty()) continue;
// only record tag data when requested
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 1c3e24f..a9d4b59 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -36,6 +36,7 @@
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
+import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
@@ -49,6 +50,10 @@
import static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE;
import static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES;
import static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE;
+import static android.provider.Settings.Secure.NETSTATS_UID_TAG_BUCKET_DURATION;
+import static android.provider.Settings.Secure.NETSTATS_UID_TAG_DELETE_AGE;
+import static android.provider.Settings.Secure.NETSTATS_UID_TAG_PERSIST_BYTES;
+import static android.provider.Settings.Secure.NETSTATS_UID_TAG_ROTATE_AGE;
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
@@ -94,10 +99,12 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
+import android.provider.Settings.Secure;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.EventLog;
import android.util.Log;
+import android.util.MathUtils;
import android.util.NtpTrustedTime;
import android.util.Slog;
import android.util.SparseIntArray;
@@ -159,6 +166,7 @@
private PendingIntent mPollIntent;
private static final String PREFIX_DEV = "dev";
+ private static final String PREFIX_XT = "xt";
private static final String PREFIX_UID = "uid";
private static final String PREFIX_UID_TAG = "uid_tag";
@@ -168,27 +176,30 @@
public interface NetworkStatsSettings {
public long getPollInterval();
public long getTimeCacheMaxAge();
- public long getGlobalAlertBytes();
public boolean getSampleEnabled();
public static class Config {
public final long bucketDuration;
- public final long persistBytes;
public final long rotateAgeMillis;
public final long deleteAgeMillis;
- public Config(long bucketDuration, long persistBytes, long rotateAgeMillis,
- long deleteAgeMillis) {
+ public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
this.bucketDuration = bucketDuration;
- this.persistBytes = persistBytes;
this.rotateAgeMillis = rotateAgeMillis;
this.deleteAgeMillis = deleteAgeMillis;
}
}
public Config getDevConfig();
+ public Config getXtConfig();
public Config getUidConfig();
public Config getUidTagConfig();
+
+ public long getGlobalAlertBytes(long def);
+ public long getDevPersistBytes(long def);
+ public long getXtPersistBytes(long def);
+ public long getUidPersistBytes(long def);
+ public long getUidTagPersistBytes(long def);
}
private final Object mStatsLock = new Object();
@@ -204,6 +215,7 @@
new DropBoxNonMonotonicObserver();
private NetworkStatsRecorder mDevRecorder;
+ private NetworkStatsRecorder mXtRecorder;
private NetworkStatsRecorder mUidRecorder;
private NetworkStatsRecorder mUidTagRecorder;
@@ -220,6 +232,8 @@
private final Handler mHandler;
private boolean mSystemReady;
+ private long mPersistThreshold = 2 * MB_IN_BYTES;
+ private long mGlobalAlertBytes;
public NetworkStatsService(
Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
@@ -268,9 +282,12 @@
// create data recorders along with historical rotators
mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
+ mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
+ updatePersistThresholds();
+
synchronized (mStatsLock) {
// upgrade any legacy stats, migrating them to rotated files
maybeUpgradeLegacyStatsLocked();
@@ -321,10 +338,9 @@
private NetworkStatsRecorder buildRecorder(
String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
- return new NetworkStatsRecorder(
- new FileRotator(mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
- mNonMonotonicObserver, prefix, config.bucketDuration, config.persistBytes,
- includeTags);
+ return new NetworkStatsRecorder(new FileRotator(
+ mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
+ mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
}
private void shutdownLocked() {
@@ -343,10 +359,12 @@
// persist any pending stats
mDevRecorder.forcePersistLocked(currentTime);
+ mXtRecorder.forcePersistLocked(currentTime);
mUidRecorder.forcePersistLocked(currentTime);
mUidTagRecorder.forcePersistLocked(currentTime);
mDevRecorder = null;
+ mXtRecorder = null;
mUidRecorder = null;
mUidTagRecorder = null;
@@ -408,8 +426,7 @@
*/
private void registerGlobalAlert() {
try {
- final long alertBytes = mSettings.getGlobalAlertBytes();
- mNetworkManager.setGlobalAlert(alertBytes);
+ mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
} catch (IllegalStateException e) {
Slog.w(TAG, "problem registering for global alert: " + e);
} catch (RemoteException e) {
@@ -431,14 +448,18 @@
private NetworkStatsCollection getUidComplete() {
if (mUidComplete == null) {
- mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
+ synchronized (mStatsLock) {
+ mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
+ }
}
return mUidComplete;
}
private NetworkStatsCollection getUidTagComplete() {
if (mUidTagComplete == null) {
- mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
+ synchronized (mStatsLock) {
+ mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
+ }
}
return mUidTagComplete;
}
@@ -578,6 +599,45 @@
}
}
+ @Override
+ public void advisePersistThreshold(long thresholdBytes) {
+ mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
+ assertBandwidthControlEnabled();
+
+ // clamp threshold into safe range
+ mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
+ updatePersistThresholds();
+
+ if (LOGV) {
+ Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
+ + mPersistThreshold);
+ }
+
+ // persist if beyond new thresholds
+ final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
+ : System.currentTimeMillis();
+ mDevRecorder.maybePersistLocked(currentTime);
+ mXtRecorder.maybePersistLocked(currentTime);
+ mUidRecorder.maybePersistLocked(currentTime);
+ mUidTagRecorder.maybePersistLocked(currentTime);
+
+ // re-arm global alert
+ registerGlobalAlert();
+ }
+
+ /**
+ * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
+ * reflect current {@link #mPersistThreshold} value. Always defers to
+ * {@link Secure} values when defined.
+ */
+ private void updatePersistThresholds() {
+ mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
+ mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
+ mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
+ mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
+ mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
+ }
+
/**
* Receiver that watches for {@link IConnectivityManager} to claim network
* interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
@@ -772,9 +832,11 @@
// snapshot and record current counters; read UID stats first to
// avoid overcounting dev stats.
final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
- final NetworkStats devSnapshot = getNetworkStatsSummary();
+ final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
+ final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
+ mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
@@ -824,9 +886,11 @@
// snapshot and record current counters; read UID stats first to
// avoid overcounting dev stats.
final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
- final NetworkStats devSnapshot = getNetworkStatsSummary();
+ final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
+ final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
+ mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
@@ -841,11 +905,13 @@
// persist any pending data depending on requested flags
if (persistForce) {
mDevRecorder.forcePersistLocked(currentTime);
+ mXtRecorder.forcePersistLocked(currentTime);
mUidRecorder.forcePersistLocked(currentTime);
mUidTagRecorder.forcePersistLocked(currentTime);
} else {
if (persistNetwork) {
mDevRecorder.maybePersistLocked(currentTime);
+ mXtRecorder.maybePersistLocked(currentTime);
}
if (persistUid) {
mUidRecorder.maybePersistLocked(currentTime);
@@ -884,7 +950,7 @@
// collect mobile sample
template = buildTemplateMobileWildcard();
devTotal = mDevRecorder.getTotalSinceBootLocked(template);
- xtTotal = new NetworkStats.Entry();
+ xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
EventLogTags.writeNetstatsMobileSample(
@@ -896,7 +962,7 @@
// collect wifi sample
template = buildTemplateWifiWildcard();
devTotal = mDevRecorder.getTotalSinceBootLocked(template);
- xtTotal = new NetworkStats.Entry();
+ xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
EventLogTags.writeNetstatsWifiSample(
@@ -970,6 +1036,11 @@
mDevRecorder.dumpLocked(pw, fullHistory);
pw.decreaseIndent();
+ pw.println("Xt stats:");
+ pw.increaseIndent();
+ mXtRecorder.dumpLocked(pw, fullHistory);
+ pw.decreaseIndent();
+
if (includeUid) {
pw.println("UID stats:");
pw.increaseIndent();
@@ -986,10 +1057,6 @@
}
}
- private NetworkStats getNetworkStatsSummary() throws RemoteException {
- return mNetworkManager.getNetworkStatsSummary();
- }
-
/**
* Return snapshot of current UID statistics, including any
* {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
@@ -1109,36 +1176,50 @@
return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
}
@Override
- public long getGlobalAlertBytes() {
- return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, 2 * MB_IN_BYTES);
+ public long getGlobalAlertBytes(long def) {
+ return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
}
@Override
public boolean getSampleEnabled() {
return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
}
-
@Override
public Config getDevConfig() {
return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
- getSecureLong(NETSTATS_DEV_PERSIST_BYTES, 2 * MB_IN_BYTES),
getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
-
+ @Override
+ public Config getXtConfig() {
+ return getDevConfig();
+ }
@Override
public Config getUidConfig() {
return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
- getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
-
@Override
public Config getUidTagConfig() {
- return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
- getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
- getSecureLong(NETSTATS_UID_ROTATE_AGE, 5 * DAY_IN_MILLIS),
- getSecureLong(NETSTATS_UID_DELETE_AGE, 15 * DAY_IN_MILLIS));
+ return new Config(getSecureLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
+ }
+ @Override
+ public long getDevPersistBytes(long def) {
+ return getSecureLong(NETSTATS_DEV_PERSIST_BYTES, def);
+ }
+ @Override
+ public long getXtPersistBytes(long def) {
+ return getDevPersistBytes(def);
+ }
+ @Override
+ public long getUidPersistBytes(long def) {
+ return getSecureLong(NETSTATS_UID_PERSIST_BYTES, def);
+ }
+ @Override
+ public long getUidTagPersistBytes(long def) {
+ return getSecureLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index ba3fd3c..9b371ac 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -106,8 +106,9 @@
private static final long TEST_START = 1194220800000L;
private static final String TEST_IFACE = "test0";
+ private static final String TEST_SSID = "AndroidAP";
- private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi();
+ private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID);
private BroadcastInterceptingContext mServiceContext;
private File mPolicyDir;
@@ -860,7 +861,7 @@
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null);
+ return new NetworkState(info, prop, null, null, TEST_SSID);
}
private void expectCurrentTime() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 6d9bb29..332d198 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -30,7 +30,7 @@
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifi;
+import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED;
import static android.net.TrafficStats.UID_TETHERING;
@@ -93,8 +93,9 @@
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
+ private static final String TEST_SSID = "AndroidAP";
- private static NetworkTemplate sTemplateWifi = buildTemplateWifi();
+ private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
@@ -136,7 +137,6 @@
mService = new NetworkStatsService(
mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
mService.bindConnectivityManager(mConnManager);
- mSession = mService.openSession();
mElapsedRealtime = 0L;
@@ -154,6 +154,7 @@
replay();
mService.systemReady();
+ mSession = mService.openSession();
verifyAndReset();
mNetworkObserver = networkObserver.getValue();
@@ -162,9 +163,7 @@
@Override
public void tearDown() throws Exception {
- for (File file : mStatsDir.listFiles()) {
- file.delete();
- }
+ IoUtils.deleteContents(mStatsDir);
mServiceContext = null;
mStatsDir = null;
@@ -820,7 +819,8 @@
}
private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
- expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
+ expect(mNetManager.getNetworkStatsSummaryDev()).andReturn(summary).atLeastOnce();
+ expect(mNetManager.getNetworkStatsSummaryXt()).andReturn(summary).atLeastOnce();
}
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
@@ -846,13 +846,19 @@
throws Exception {
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
- expect(mSettings.getGlobalAlertBytes()).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
- final Config config = new Config(bucketDuration, persistBytes, deleteAge, deleteAge);
+ final Config config = new Config(bucketDuration, deleteAge, deleteAge);
expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
+ expect(mSettings.getXtConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
+
+ expect(mSettings.getGlobalAlertBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
+ expect(mSettings.getDevPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
+ expect(mSettings.getXtPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
+ expect(mSettings.getUidPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
+ expect(mSettings.getUidTagPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
}
private void expectCurrentTime() throws Exception {
@@ -903,7 +909,7 @@
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null);
+ return new NetworkState(info, prop, null, null, TEST_SSID);
}
private static NetworkState buildMobile3gState(String subscriberId) {
@@ -912,7 +918,7 @@
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, subscriberId);
+ return new NetworkState(info, prop, null, subscriberId, null);
}
private static NetworkState buildMobile4gState(String iface) {
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index 6a9778e..afa0eec 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -232,7 +232,8 @@
final INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
// test is currently no-op, just exercises stats apis
- Log.d(TAG, nmService.getNetworkStatsSummary().toString());
+ Log.d(TAG, nmService.getNetworkStatsSummaryDev().toString());
+ Log.d(TAG, nmService.getNetworkStatsSummaryXt().toString());
Log.d(TAG, nmService.getNetworkStatsDetail().toString());
}
@@ -286,7 +287,7 @@
}
/**
- * Expect {@link NetworkManagementService#getNetworkStatsSummary()} mock
+ * Expect {@link NetworkManagementService#getNetworkStatsSummaryDev()} mock
* calls, responding with the given counter values.
*/
public void expectGetInterfaceCounter(long rx, long tx) throws Exception {
@@ -294,7 +295,7 @@
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
stats.addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, rx, 0L, tx, 0L, 0);
- expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
+ expect(mMockNMService.getNetworkStatsSummaryDev()).andReturn(stats).atLeastOnce();
}
/**
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index a90af15..70e2aac 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -715,20 +715,28 @@
new Test("Ten Notifications") {
public void run() {
for (int i = 0; i < 2; i++) {
- Notification n = new Notification(NotificationTestList.this,
+ Notification n = new Notification(
kNumberedIconResIDs[i],
- null, System.currentTimeMillis(), "Persistent #" + i,
- "Notify me!!!" + i, null);
- n.flags |= Notification.FLAG_ONGOING_EVENT;
+ null, System.currentTimeMillis());
n.number = i;
+ n.setLatestEventInfo(
+ NotificationTestList.this,
+ "Persistent #" + i,
+ "Notify me!!!" + i,
+ null);
+ n.flags |= Notification.FLAG_ONGOING_EVENT;
mNM.notify((i+1)*10, n);
}
for (int i = 2; i < 10; i++) {
- Notification n = new Notification(NotificationTestList.this,
+ Notification n = new Notification(
kNumberedIconResIDs[i],
- null, System.currentTimeMillis(), "Persistent #" + i,
- "Notify me!!!" + i, null);
+ null, System.currentTimeMillis());
n.number = i;
+ n.setLatestEventInfo(
+ NotificationTestList.this,
+ "Persistent #" + i,
+ "Notify me!!!" + i,
+ null);
mNM.notify((i+1)*10, n);
}
}