summaryrefslogtreecommitdiffstats
path: root/core/java/android/os
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os')
-rw-r--r--core/java/android/os/BatteryStats.java305
-rw-r--r--core/java/android/os/Binder.java44
-rw-r--r--core/java/android/os/Build.java3
-rw-r--r--core/java/android/os/Debug.java26
-rw-r--r--core/java/android/os/Environment.java12
-rw-r--r--core/java/android/os/IBinder.java11
-rw-r--r--core/java/android/os/ICheckinService.aidl3
-rw-r--r--core/java/android/os/IMountService.aidl15
-rw-r--r--core/java/android/os/INetStatService.aidl15
-rw-r--r--core/java/android/os/NetStat.java187
10 files changed, 568 insertions, 53 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index ed7c366..017b14d 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -15,19 +15,26 @@ import android.util.SparseArray;
public abstract class BatteryStats {
/**
- * A constant indicating a partial wake lock.
+ * A constant indicating a partial wake lock timer.
*/
public static final int WAKE_TYPE_PARTIAL = 0;
/**
- * A constant indicating a full wake lock.
+ * A constant indicating a full wake lock timer.
*/
public static final int WAKE_TYPE_FULL = 1;
/**
- * A constant indicating a window wake lock.
+ * A constant indicating a window wake lock timer.
*/
public static final int WAKE_TYPE_WINDOW = 2;
+
+ /**
+ * A constant indicating a sensor timer.
+ *
+ * {@hide}
+ */
+ public static final int SENSOR = 3;
/**
* Include all of the data in the stats, including previously saved data.
@@ -48,6 +55,21 @@ public abstract class BatteryStats {
* Include only the run since the last time the device was unplugged in the stats.
*/
public static final int STATS_UNPLUGGED = 3;
+
+ /**
+ * Bump the version on this if the checkin format changes.
+ */
+ private static final int BATTERY_STATS_CHECKIN_VERSION = 1;
+
+ // TODO: Update this list if you add/change any stats above.
+ private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
+
+ private static final String APK_DATA = "apk";
+ private static final String PROCESS_DATA = "process";
+ private static final String SENSOR_DATA = "sensor";
+ private static final String WAKELOCK_DATA = "wakelock";
+ private static final String NETWORK_DATA = "network";
+ private static final String BATTERY_DATA = "battery";
private final StringBuilder mFormatBuilder = new StringBuilder(8);
private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -115,8 +137,28 @@ public abstract class BatteryStats {
* @return a Map from Strings to Uid.Pkg objects.
*/
public abstract Map<String, ? extends Pkg> getPackageStats();
+
+ /**
+ * {@hide}
+ */
+ public abstract int getUid();
+
+ /**
+ * {@hide}
+ */
+ public abstract long getTcpBytesReceived(int which);
+
+ /**
+ * {@hide}
+ */
+ public abstract long getTcpBytesSent(int which);
public static abstract class Sensor {
+ /**
+ * {@hide}
+ */
+ public abstract String getName();
+
public abstract Timer getSensorTime();
}
@@ -200,6 +242,22 @@ public abstract class BatteryStats {
* Returns the number of times the device has been started.
*/
public abstract int getStartCount();
+
+ /**
+ * Returns the time in milliseconds that the screen has been on while the device was
+ * running on battery.
+ *
+ * {@hide}
+ */
+ public abstract long getBatteryScreenOnTime();
+
+ /**
+ * Returns the time in milliseconds that the screen has been on while the device was
+ * plugged in.
+ *
+ * {@hide}
+ */
+ public abstract long getPluggedScreenOnTime();
/**
* Returns a SparseArray containing the statistics for each uid.
@@ -318,11 +376,14 @@ public abstract class BatteryStats {
* @param linePrefix a String to be prepended to each line of output.
* @return the line prefix
*/
- private final String printWakeLock(StringBuilder sb, Timer timer, long now,
+ private static final String printWakeLock(StringBuilder sb, Timer timer, long now,
String name, int which, String linePrefix) {
+
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTimeMillis = (timer.getTotalTime(now, which) + 500) / 1000;
+ long totalTimeMicros = timer.getTotalTime(now, which);
+ long totalTimeMillis = (totalTimeMicros + 500) / 1000;
+
int count = timer.getCount(which);
if (totalTimeMillis != 0) {
sb.append(linePrefix);
@@ -337,6 +398,184 @@ public abstract class BatteryStats {
}
return linePrefix;
}
+
+ /**
+ * Checkin version of wakelock printer. Prints simple comma-separated list.
+ *
+ * @param sb a StringBuilder object.
+ * @param timer a Timer object contining the wakelock times.
+ * @param now the current time in microseconds.
+ * @param name the name of the wakelock.
+ * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+ * @param linePrefix a String to be prepended to each line of output.
+ * @return the line prefix
+ */
+ private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
+ String name, int which, String linePrefix) {
+ long totalTimeMicros = 0;
+ int count = 0;
+ if (timer != null) {
+ totalTimeMicros = timer.getTotalTime(now, which);
+ count = timer.getCount(which);
+ }
+ sb.append(linePrefix);
+ sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
+ sb.append(',');
+ sb.append(name);
+ sb.append(',');
+ sb.append(count);
+ return ",";
+ }
+
+ /**
+ * Dump a comma-separated line of values for terse checkin mode.
+ *
+ * @param pw the PageWriter to dump log to
+ * @param category category of data (e.g. "total", "last", "unplugged", "current" )
+ * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
+ * @param args type-dependent data arguments
+ */
+ private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
+ Object... args ) {
+ pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+ pw.print(uid); pw.print(',');
+ pw.print(category); pw.print(',');
+ pw.print(type);
+
+ for (Object arg : args) {
+ pw.print(',');
+ pw.print(arg);
+ }
+ pw.print('\n');
+ }
+
+ /**
+ * Checkin server version of dump to produce more compact, computer-readable log.
+ *
+ * NOTE: all times are expressed in 'ms'.
+ * @param fd
+ * @param pw
+ * @param which
+ */
+ private final void dumpCheckinLocked(FileDescriptor fd, PrintWriter pw, int which) {
+ long uSecTime = SystemClock.elapsedRealtime() * 1000;
+ final long uSecNow = getBatteryUptime(uSecTime);
+
+ StringBuilder sb = new StringBuilder(128);
+ long batteryUptime = computeBatteryUptime(uSecNow, which);
+ long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
+ long elapsedRealtime = computeRealtime(uSecTime, which);
+ long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
+
+ String category = STAT_NAMES[which];
+
+ // Dump "battery" stat
+ dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
+ which == STATS_TOTAL ? getStartCount() : "N/A",
+ batteryUptime / 1000,
+ formatRatioLocked(batteryUptime, elapsedRealtime),
+ batteryRealtime / 1000,
+ formatRatioLocked(batteryRealtime, elapsedRealtime),
+ uptime / 1000,
+ elapsedRealtime / 1000);
+
+ SparseArray<? extends Uid> uidStats = getUidStats();
+ final int NU = uidStats.size();
+ for (int iu = 0; iu < NU; iu++) {
+ final int uid = uidStats.keyAt(iu);
+ Uid u = uidStats.valueAt(iu);
+ // Dump Network stats per uid, if any
+ long rx = u.getTcpBytesReceived(which);
+ long tx = u.getTcpBytesSent(which);
+ if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
+
+ Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
+ if (wakelocks.size() > 0) {
+ for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
+ : wakelocks.entrySet()) {
+ Uid.Wakelock wl = ent.getValue();
+ String linePrefix = "";
+ sb.setLength(0);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), uSecNow,
+ "full", which, linePrefix);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), uSecNow,
+ "partial", which, linePrefix);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), uSecNow,
+ "window", which, linePrefix);
+
+ // Only log if we had at lease one wakelock...
+ if (sb.length() > 0) {
+ dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
+ }
+ }
+ }
+
+ Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+ if (sensors.size() > 0) {
+ for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
+ : sensors.entrySet()) {
+ Uid.Sensor se = ent.getValue();
+ int sensorNumber = ent.getKey();
+ Timer timer = se.getSensorTime();
+ if (timer != null) {
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (timer.getTotalTime(uSecNow, which) + 500) / 1000;
+ int count = timer.getCount(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
+ }
+ }
+ }
+ }
+
+ Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+ if (processStats.size() > 0) {
+ for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+ : processStats.entrySet()) {
+ Uid.Proc ps = ent.getValue();
+
+ long userTime = ps.getUserTime(which);
+ long systemTime = ps.getSystemTime(which);
+ int starts = ps.getStarts(which);
+
+ if (userTime != 0 || systemTime != 0 || starts != 0) {
+ dumpLine(pw, uid, category, PROCESS_DATA,
+ ent.getKey(), // proc
+ userTime * 10, // cpu time in ms
+ systemTime * 10, // user time in ms
+ starts); // process starts
+ }
+ }
+ }
+
+ Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
+ if (packageStats.size() > 0) {
+ for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
+ : packageStats.entrySet()) {
+
+ Uid.Pkg ps = ent.getValue();
+ int wakeups = ps.getWakeups(which);
+ Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
+ for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
+ : serviceStats.entrySet()) {
+ BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
+ long startTime = ss.getStartTime(uSecNow, which);
+ int starts = ss.getStarts(which);
+ int launches = ss.getLaunches(which);
+ if (startTime != 0 || starts != 0 || launches != 0) {
+ dumpLine(pw, uid, category, APK_DATA,
+ wakeups, // wakeup alarms
+ ent.getKey(), // Apk
+ sent.getKey(), // service
+ startTime / 1000, // time spent started, in ms
+ starts,
+ launches);
+ }
+ }
+ }
+ }
+ }
+ }
@SuppressWarnings("unused")
private final void dumpLocked(FileDescriptor fd, PrintWriter pw, String prefix, int which) {
@@ -344,13 +583,22 @@ public abstract class BatteryStats {
final long uSecNow = getBatteryUptime(uSecTime);
StringBuilder sb = new StringBuilder(128);
- if (which == STATS_TOTAL) {
- pw.println(prefix + "Current and Historic Battery Usage Statistics:");
- pw.println(prefix + " System starts: " + getStartCount());
- } else if (which == STATS_LAST) {
- pw.println(prefix + "Last Battery Usage Statistics:");
- } else {
- pw.println(prefix + "Current Battery Usage Statistics:");
+ switch (which) {
+ case STATS_TOTAL:
+ pw.println(prefix + "Current and Historic Battery Usage Statistics:");
+ pw.println(prefix + " System starts: " + getStartCount());
+ break;
+ case STATS_LAST:
+ pw.println(prefix + "Last Battery Usage Statistics:");
+ break;
+ case STATS_UNPLUGGED:
+ pw.println(prefix + "Last Unplugged Battery Usage Statistics:");
+ break;
+ case STATS_CURRENT:
+ pw.println(prefix + "Current Battery Usage Statistics:");
+ break;
+ default:
+ throw new IllegalArgumentException("which = " + which);
}
long batteryUptime = computeBatteryUptime(uSecNow, which);
long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
@@ -359,7 +607,7 @@ public abstract class BatteryStats {
pw.println(prefix
+ " On battery: " + formatTimeMs(batteryUptime / 1000) + "("
- + formatRatioLocked(batteryUptime, batteryRealtime)
+ + formatRatioLocked(batteryUptime, elapsedRealtime)
+ ") uptime, "
+ formatTimeMs(batteryRealtime / 1000) + "("
+ formatRatioLocked(batteryRealtime, elapsedRealtime)
@@ -380,6 +628,9 @@ public abstract class BatteryStats {
Uid u = uidStats.valueAt(iu);
pw.println(prefix + " #" + uid + ":");
boolean uidActivity = false;
+
+ pw.println(prefix + " Network: " + u.getTcpBytesReceived(which) + " bytes received, "
+ + u.getTcpBytesSent(which) + " bytes sent");
Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
if (wakelocks.size() > 0) {
@@ -512,12 +763,30 @@ public abstract class BatteryStats {
*/
@SuppressWarnings("unused")
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+ boolean isCheckin = false;
+ if (args != null) {
+ for (String arg : args) {
+ if ("-c".equals(arg)) {
+ isCheckin = true;
+ break;
+ }
+ }
+ }
synchronized (this) {
- dumpLocked(fd, pw, "", STATS_TOTAL);
- pw.println("");
- dumpLocked(fd, pw, "", STATS_LAST);
- pw.println("");
- dumpLocked(fd, pw, "", STATS_CURRENT);
+ if (isCheckin) {
+ dumpCheckinLocked(fd, pw, STATS_TOTAL);
+ dumpCheckinLocked(fd, pw, STATS_LAST);
+ dumpCheckinLocked(fd, pw, STATS_UNPLUGGED);
+ dumpCheckinLocked(fd, pw, STATS_CURRENT);
+ } else {
+ dumpLocked(fd, pw, "", STATS_TOTAL);
+ pw.println("");
+ dumpLocked(fd, pw, "", STATS_LAST);
+ pw.println("");
+ dumpLocked(fd, pw, "", STATS_UNPLUGGED);
+ pw.println("");
+ dumpLocked(fd, pw, "", STATS_CURRENT);
+ }
}
}
}
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 528e6bd..df10c6a 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -33,7 +33,7 @@ import java.lang.reflect.Modifier;
* the standard support creating a local implementation of such an object.
*
* <p>Most developers will not implement this class directly, instead using the
- * <a href="{@docRoot}reference/aidl.html">aidl</a> tool to describe the desired
+ * <a href="{@docRoot}guide/developing/tools/aidl.html">aidl</a> tool to describe the desired
* interface, having it generate the appropriate Binder subclass. You can,
* however, derive directly from Binder to implement your own custom RPC
* protocol or simply instantiate a raw Binder object directly to use as a
@@ -194,18 +194,15 @@ public class Binder implements IBinder {
return true;
} else if (code == DUMP_TRANSACTION) {
ParcelFileDescriptor fd = data.readFileDescriptor();
- FileOutputStream fout = fd != null
- ? new FileOutputStream(fd.getFileDescriptor()) : null;
- PrintWriter pw = fout != null ? new PrintWriter(fout) : null;
- if (pw != null) {
- String[] args = data.readStringArray();
- dump(fd.getFileDescriptor(), pw, args);
- pw.flush();
- }
+ String[] args = data.readStringArray();
if (fd != null) {
try {
- fd.close();
- } catch (IOException e) {
+ dump(fd.getFileDescriptor(), args);
+ } finally {
+ try {
+ fd.close();
+ } catch (IOException e) {
+ }
}
}
return true;
@@ -214,6 +211,20 @@ public class Binder implements IBinder {
}
/**
+ * Implemented to call the more convenient version
+ * {@link #dump(FileDescriptor, PrintWriter, String[])}.
+ */
+ public void dump(FileDescriptor fd, String[] args) {
+ FileOutputStream fout = new FileOutputStream(fd);
+ PrintWriter pw = new PrintWriter(fout);
+ try {
+ dump(fd, pw, args);
+ } finally {
+ pw.flush();
+ }
+ }
+
+ /**
* Print the object's state into the given stream.
*
* @param fd The raw file descriptor that the dump is being sent to.
@@ -302,6 +313,17 @@ final class BinderProxy implements IBinder {
throws RemoteException;
public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
+ public void dump(FileDescriptor fd, String[] args) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeFileDescriptor(fd);
+ data.writeStringArray(args);
+ try {
+ transact(DUMP_TRANSACTION, data, null, 0);
+ } finally {
+ data.recycle();
+ }
+ }
+
BinderProxy() {
mSelf = new WeakReference(this);
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index cdf907b..467c17f 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -26,6 +26,9 @@ public class Build {
/** Either a changelist number, or a label like "M4-rc20". */
public static final String ID = getString("ro.build.id");
+ /** A build ID string meant for displaying to the user */
+ public static final String DISPLAY = getString("ro.build.display.id");
+
/** The name of the overall product. */
public static final String PRODUCT = getString("ro.product.name");
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 5f7f91f..950bb09 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -17,6 +17,7 @@
package android.os;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
@@ -28,12 +29,13 @@ import dalvik.bytecode.Opcodes;
import dalvik.system.VMDebug;
-/** Provides various debugging functions for Android applications, including
+/**
+ * Provides various debugging functions for Android applications, including
* tracing and allocation counts.
* <p><strong>Logging Trace Files</strong></p>
* <p>Debug can create log files that give details about an application, such as
* a call stack and start/stop times for any running methods. See <a
-href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Program</a> for
+href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
* information about reading trace files. To start logging trace files, call one
* of the startMethodTracing() methods. To stop tracing, call
* {@link #stopMethodTracing()}.
@@ -285,7 +287,7 @@ public final class Debug
/**
* Start method tracing with default log name and buffer size. See <a
-href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Program</a> for
+href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
* information about reading these files. Call stopMethodTracing() to stop
* tracing.
*/
@@ -297,7 +299,7 @@ href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Progra
* Start method tracing, specifying the trace log file name. The trace
* file will be put under "/sdcard" unless an absolute path is given.
* See <a
- href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Program</a> for
+ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
* information about reading trace files.
*
* @param traceName Name for the trace log file to create.
@@ -313,7 +315,7 @@ href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Progra
* Start method tracing, specifying the trace log file name and the
* buffer size. The trace files will be put under "/sdcard" unless an
* absolute path is given. See <a
- href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Program</a> for
+ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
* information about reading trace files.
* @param traceName Name for the trace log file to create.
* If no name argument is given, this value defaults to "/sdcard/dmtrace.trace".
@@ -330,7 +332,7 @@ href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Progra
* Start method tracing, specifying the trace log file name and the
* buffer size. The trace files will be put under "/sdcard" unless an
* absolute path is given. See <a
- href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Program</a> for
+ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
* information about reading trace files.
*
* <p>
@@ -581,6 +583,18 @@ href="{@docRoot}reference/traceview.html">Running the Traceview Debugging Progra
}
/**
+ * Dump "hprof" data to the specified file. This will cause a GC.
+ *
+ * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
+ * @throws UnsupportedOperationException if the VM was built without
+ * HPROF support.
+ * @throws IOException if an error occurs while opening or writing files.
+ */
+ public static void dumpHprofData(String fileName) throws IOException {
+ VMDebug.dumpHprofData(fileName);
+ }
+
+ /**
* Returns the number of sent transactions from this process.
* @return The number of sent transactions or -1 if it could not read t.
*/
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index e37b551..f761e8e 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -75,6 +75,18 @@ public class Environment {
public static final String MEDIA_UNMOUNTED = "unmounted";
/**
+ * getExternalStorageState() returns MEDIA_CHECKING if the media is present
+ * and being disk-checked
+ */
+ public static final String MEDIA_CHECKING = "checking";
+
+ /**
+ * getExternalStorageState() returns MEDIA_NOFS if the media is present
+ * but is blank or is using an unsupported filesystem
+ */
+ public static final String MEDIA_NOFS = "nofs";
+
+ /**
* getExternalStorageState() returns MEDIA_MOUNTED if the media is present
* and mounted at its mount point with read/write access.
*/
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 3ec0e9b..5c40c9a0 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -16,6 +16,9 @@
package android.os;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* Base interface for a remotable object, the core part of a lightweight
* remote procedure call mechanism designed for high performance when
@@ -145,6 +148,14 @@ public interface IBinder {
public IInterface queryLocalInterface(String descriptor);
/**
+ * Print the object's state into the given stream.
+ *
+ * @param fd The raw file descriptor that the dump is being sent to.
+ * @param args additional arguments to the dump request.
+ */
+ public void dump(FileDescriptor fd, String[] args) throws RemoteException;
+
+ /**
* Perform a generic operation with the object.
*
* @param code The action to perform. This should
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
index 70ad28e..11becc4 100644
--- a/core/java/android/os/ICheckinService.aidl
+++ b/core/java/android/os/ICheckinService.aidl
@@ -26,6 +26,9 @@ import android.os.IParentalControlCallback;
* {@hide}
*/
interface ICheckinService {
+ /** Synchronously attempt a checkin with the server, return true on success. */
+ boolean checkin();
+
/** Direct submission of crash data; returns after writing the crash. */
void reportCrashSync(in byte[] crashData);
diff --git a/core/java/android/os/IMountService.aidl b/core/java/android/os/IMountService.aidl
index 0397446..88dae85 100644
--- a/core/java/android/os/IMountService.aidl
+++ b/core/java/android/os/IMountService.aidl
@@ -48,4 +48,19 @@ interface IMountService
* Safely unmount external storage at given mount point.
*/
void unmountMedia(String mountPoint);
+
+ /**
+ * Format external storage given a mount point
+ */
+ void formatMedia(String mountPoint);
+
+ /**
+ * Returns true if media notification sounds are enabled.
+ */
+ boolean getPlayNotificationSounds();
+
+ /**
+ * Sets whether or not media notification sounds are played.
+ */
+ void setPlayNotificationSounds(boolean value);
}
diff --git a/core/java/android/os/INetStatService.aidl b/core/java/android/os/INetStatService.aidl
index fb840d8..a8f3de0 100644
--- a/core/java/android/os/INetStatService.aidl
+++ b/core/java/android/os/INetStatService.aidl
@@ -17,14 +17,19 @@
package android.os;
/**
- * Retrieves packet and byte counts for the phone data interface.
+ * Retrieves packet and byte counts for the phone data interface,
+ * and for all interfaces.
* Used for the data activity icon and the phone status in Settings.
*
* {@hide}
*/
interface INetStatService {
- int getTxPackets();
- int getRxPackets();
- int getTxBytes();
- int getRxBytes();
+ long getMobileTxPackets();
+ long getMobileRxPackets();
+ long getMobileTxBytes();
+ long getMobileRxBytes();
+ long getTotalTxPackets();
+ long getTotalRxPackets();
+ long getTotalTxBytes();
+ long getTotalRxBytes();
}
diff --git a/core/java/android/os/NetStat.java b/core/java/android/os/NetStat.java
index 7312236..733137a 100644
--- a/core/java/android/os/NetStat.java
+++ b/core/java/android/os/NetStat.java
@@ -16,36 +16,197 @@
package android.os;
+import android.util.Log;
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
/** @hide */
public class NetStat{
/**
- * Get total number of tx packets sent through ppp0
+ * Get total number of tx packets sent through rmnet0 or ppp0
*
- * @return number of Tx packets through ppp0
+ * @return number of Tx packets through rmnet0 or ppp0
*/
-
- public native static int netStatGetTxPkts();
+ public static long getMobileTxPkts() {
+ return getMobileStat("tx_packets");
+ }
/**
- * Get total number of rx packets received through ppp0
+ * Get total number of rx packets received through rmnet0 or ppp0
*
- * @return number of Rx packets through ppp0
+ * @return number of Rx packets through rmnet0 or ppp0
*/
- public native static int netStatGetRxPkts();
+ public static long getMobileRxPkts() {
+ return getMobileStat("rx_packets");
+ }
/**
- * Get total number of tx bytes received through ppp0
+ * Get total number of tx bytes received through rmnet0 or ppp0
+ *
+ * @return number of Tx bytes through rmnet0 or ppp0
+ */
+ public static long getMobileTxBytes() {
+ return getMobileStat("tx_bytes");
+ }
+
+ /**
+ * Get total number of rx bytes received through rmnet0 or ppp0
+ *
+ * @return number of Rx bytes through rmnet0 or ppp0
+ */
+ public static long getMobileRxBytes() {
+ return getMobileStat("rx_bytes");
+ }
+
+ /**
+ * Get the total number of packets sent through all network interfaces.
+ *
+ * @return the number of packets sent through all network interfaces
+ */
+ public static long getTotalTxPkts() {
+ return getTotalStat("tx_packets");
+ }
+
+ /**
+ * Get the total number of packets received through all network interfaces.
+ *
+ * @return the number of packets received through all network interfaces
+ */
+ public static long getTotalRxPkts() {
+ return getTotalStat("rx_packets");
+ }
+
+ /**
+ * Get the total number of bytes sent through all network interfaces.
+ *
+ * @return the number of bytes sent through all network interfaces
+ */
+ public static long getTotalTxBytes() {
+ return getTotalStat("tx_bytes");
+ }
+
+ /**
+ * Get the total number of bytes received through all network interfaces.
+ *
+ * @return the number of bytes received through all network interfaces
+ */
+ public static long getTotalRxBytes() {
+ return getTotalStat("rx_bytes");
+ }
+
+ /**
+ * Gets network bytes sent for this UID.
+ * The statistics are across all interfaces.
+ * The statistics come from /proc/uid_stat.
*
- * @return number of Tx bytes through ppp0
+ * {@see android.os.Process#myUid()}.
+ *
+ * @param uid
+ * @return byte count
*/
- public native static int netStatGetTxBytes();
+ public static long getUidTxBytes(int uid) {
+ return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_snd");
+ }
/**
- * Get total number of rx bytes received through ppp0
+ * Gets network bytes received for this UID.
+ * The statistics are across all interfaces.
+ * The statistics come from /proc/uid_stat.
*
- * @return number of Rx bytes through ppp0
+ * {@see android.os.Process#myUid()}.
+ *
+ * @param uid
+ * @return byte count
*/
- public native static int netStatGetRxBytes();
+ public static long getUidRxBytes(int uid) {
+ return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_rcv");
+ }
+
+ private static String TAG = "netstat";
+ private static final byte[] buf = new byte[16];
+
+ private static long getTotalStat(String whatStat) {
+ File netdir = new File("/sys/class/net");
+
+ File[] nets = netdir.listFiles();
+ if (nets == null) {
+ return 0;
+ }
+ long total = 0;
+ StringBuffer strbuf = new StringBuffer();
+ for (File net : nets) {
+ strbuf.append(net.getPath()).append(File.separator).append("statistics")
+ .append(File.separator).append(whatStat);
+ total += getNumberFromFilePath(strbuf.toString());
+ strbuf.setLength(0);
+ }
+ return total;
+ }
+
+ private static long getMobileStat(String whatStat) {
+ String filename = "/sys/class/net/rmnet0/statistics/" + whatStat;
+ RandomAccessFile raf = getFile(filename);
+ if (raf == null) {
+ filename = "/sys/class/net/ppp0/statistics/" + whatStat;
+ raf = getFile(filename);
+ }
+ if (raf == null) {
+ return 0L;
+ }
+ return getNumberFromFile(raf, filename);
+ }
+
+ // File will have format <number><newline>
+ private static long getNumberFromFilePath(String filename) {
+ RandomAccessFile raf = getFile(filename);
+ if (raf == null) {
+ return 0L;
+ }
+ return getNumberFromFile(raf, filename);
+ }
+
+ private static synchronized long getNumberFromFile(RandomAccessFile raf, String filename) {
+ try {
+ raf.read(buf);
+ raf.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Exception getting TCP bytes from " + filename, e);
+ return 0L;
+ } finally {
+ if (raf != null) {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Exception closing " + filename, e);
+ }
+ }
+ }
+
+ long num = 0L;
+ for (int i = 0; i < buf.length; i++) {
+ if (buf[i] < '0' || buf[i] > '9') {
+ break;
+ }
+ num *= 10;
+ num += buf[i] - '0';
+ }
+ return num;
+ }
+
+ private static RandomAccessFile getFile(String filename) {
+ File f = new File(filename);
+ if (!f.canRead()) {
+ return null;
+ }
+ try {
+ return new RandomAccessFile(f, "r");
+ } catch (IOException e) {
+ Log.w(TAG, "Exception opening TCP statistics file " + filename, e);
+ return null;
+ }
+ }
}