diff options
author | Yuchao Zhou <superzhou@google.com> | 2015-09-16 22:53:10 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-09-16 22:53:10 +0000 |
commit | 88daa997fc609fdcbd1376657e3f18de4ca37193 (patch) | |
tree | e06c6f556df5452b7c5f5a912500d30c4ddbebe8 /core/tests | |
parent | 4873c549f7f4c45237a6f1185dd29216157965df (diff) | |
parent | c38ffecc348687ae30c5fa2dc1761d9138b406b6 (diff) | |
download | frameworks_base-88daa997fc609fdcbd1376657e3f18de4ca37193.zip frameworks_base-88daa997fc609fdcbd1376657e3f18de4ca37193.tar.gz frameworks_base-88daa997fc609fdcbd1376657e3f18de4ca37193.tar.bz2 |
am c38ffecc: Merge "Moving BTtraffic from experiment location to here" into cw-d-mr1-dev
* commit 'c38ffecc348687ae30c5fa2dc1761d9138b406b6':
Moving BTtraffic from experiment location to here
Diffstat (limited to 'core/tests')
-rw-r--r-- | core/tests/BTtraffic/Android.mk | 16 | ||||
-rw-r--r-- | core/tests/BTtraffic/AndroidManifest.xml | 22 | ||||
-rw-r--r-- | core/tests/BTtraffic/README | 45 | ||||
-rw-r--r-- | core/tests/BTtraffic/res/values/strings.xml | 3 | ||||
-rw-r--r-- | core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java | 328 | ||||
-rw-r--r-- | core/tests/SvcMonitor/Android.mk | 16 | ||||
-rw-r--r-- | core/tests/SvcMonitor/AndroidManifest.xml | 21 | ||||
-rw-r--r-- | core/tests/SvcMonitor/README | 27 | ||||
-rw-r--r-- | core/tests/SvcMonitor/res/values/strings.xml | 3 | ||||
-rw-r--r-- | core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java | 209 |
10 files changed, 690 insertions, 0 deletions
diff --git a/core/tests/BTtraffic/Android.mk b/core/tests/BTtraffic/Android.mk new file mode 100644 index 0000000..7d83527 --- /dev/null +++ b/core/tests/BTtraffic/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_RESOURCE_DIR := \ + $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := bttraffic +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/core/tests/BTtraffic/AndroidManifest.xml b/core/tests/BTtraffic/AndroidManifest.xml new file mode 100644 index 0000000..00d9707 --- /dev/null +++ b/core/tests/BTtraffic/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.experimental.bttraffic" > + + <uses-permission android:name="android.permission.BLUETOOTH"/> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> + + <uses-sdk + android:minSdkVersion="18" + android:targetSdkVersion="18" + /> + <application + android:allowBackup="false" + android:label="@string/app_name" > + <service + android:name=".BTtraffic" + android:enabled="true" + android:exported="true" > + </service> + </application> + +</manifest> diff --git a/core/tests/BTtraffic/README b/core/tests/BTtraffic/README new file mode 100644 index 0000000..430488f --- /dev/null +++ b/core/tests/BTtraffic/README @@ -0,0 +1,45 @@ +This is a tool to generate classic Bluetooth traffic with specified period and package size. +Together with the SvcMonitor, which will be called automatically in this android service, can be +used to measure the CPU usage from the Java layer Bluetooth code and the underlying system service +com.android.bluetooth. + +1. Server (Listener) - Client (Sender) model. Both run as an Android service. +2. No pairing needed. Communicate via unsecured RFcomm. Client establishes the connection by +providing the MAC addr of the server. +3. Bluetooth has to be turned on on both side. +4. Client can configure the traffic by specifying the transfer period and package size. +5. A separate monitor process will be automatically forked and will be reading from /proc file +system to calculate the cpu usage. The measurement is updated once per second. +6. The monitor process (com.google.android.experimental.svcmonitor/.ScvMonitor) can be run as an +independent service to measure cpu usage on any similarly configured tests (e.g. wifi, BLE). Refer +to SvcMonitor's README for usage and details. + +Usage: +To instal the test: +On both the server and client device, install the 2 apk: +$ adb install $OUT/system/app/bttraffic/bttraffic.apk +$ adb install $OUT/system/app/svcmonitor/svcmonitor.apk + +To start the service on the SERVER side: +$ adb shell am startservice -a start --ez ack true \ +com.google.android.experimental.bttraffic/.BTtraffic + +To start the service on the CLIENT side: +$ adb shell am startservice -a start \ +-e addr "F8:A9:D0:A8:74:8E" --ei size 1000 --ei period 15 \ +com.google.android.experimental.bttraffic/.BTtraffic + +To stop the test: +On either the server or client: +$ adb shell am startservice -a stop \ +com.google.android.experimental.bttraffic/.BTtraffic + +To look at the data: +$ adb logcat | grep bttraffic + +Options: +-e addr: MAC addr of the server, in uppercase letter. +--ei size: package size, unit: byte; default: 1024, MAX: 20MB +--ei period: system sleep time between sending each package, unit: ms, default: 5000 + ** if -1 is provided, client will only send the package once. +--ez ack: whether acknowledge is required (true/false) diff --git a/core/tests/BTtraffic/res/values/strings.xml b/core/tests/BTtraffic/res/values/strings.xml new file mode 100644 index 0000000..e70276e --- /dev/null +++ b/core/tests/BTtraffic/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">Bluetooth Test</string> +</resources> diff --git a/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java b/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java new file mode 100644 index 0000000..286c0aa --- /dev/null +++ b/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java @@ -0,0 +1,328 @@ +package com.google.android.experimental.bttraffic; + +import android.app.Service; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothServerSocket; +import android.bluetooth.BluetoothSocket; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.SystemClock; +import android.util.Log; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.Exception; +import java.lang.Runtime; +import java.lang.RuntimeException; +import java.lang.Process; +import java.nio.ByteBuffer; +import java.util.Random; +import java.util.Set; +import java.util.UUID; + +public class BTtraffic extends Service { + public static final String TAG = "bttraffic"; + static final String SERVICE_NAME = "bttraffic"; + static final String SYS_SERVICE_NAME = "com.android.bluetooth"; + static final UUID SERVICE_UUID = UUID.fromString("5e8945b0-1234-5432-a5e2-0800200c9a67"); + volatile Thread mWorkerThread; + volatile boolean isShuttingDown = false; + volatile boolean isServer = false; + + public BTtraffic() {} + + static void safeClose(Closeable closeable) { + try { + closeable.close(); + } catch (IOException e) { + Log.d(TAG, "Unable to close resource.\n"); + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent == null) { + stopSelf(); + return 0; + } + if ("stop".equals(intent.getAction())) { + stopService(); + } else if ("start".equals(intent.getAction())) { + startWorker(intent); + } else { + Log.d(TAG, "unknown action: + " + intent.getAction()); + } + return 0; + } + + private void startWorker(Intent intent) { + if (mWorkerThread != null) { + Log.d(TAG, "worker thread already active"); + return; + } + isShuttingDown = false; + String remoteAddr = intent.getStringExtra("addr"); + Log.d(TAG, "startWorker: addr=" + remoteAddr); + Runnable worker = + remoteAddr == null + ? new ListenerRunnable(this, intent) + : new SenderRunnable(this, remoteAddr, intent); + isServer = remoteAddr == null ? true: false; + mWorkerThread = new Thread(worker, "BTtrafficWorker"); + try { + startMonitor(); + Log.d(TAG, "Monitor service started"); + mWorkerThread.start(); + Log.d(TAG, "Worker thread started"); + } catch (Exception e) { + Log.d(TAG, "Failed to start service", e); + } + } + + private void startMonitor() + throws Exception { + if (isServer) { + Log.d(TAG, "Start monitor on server"); + String[] startmonitorCmd = { + "/system/bin/am", + "startservice", + "-a", "start", + "-e", "java", SERVICE_NAME, + "-e", "hal", SYS_SERVICE_NAME, + "com.google.android.experimental.svcmonitor/.SvcMonitor" + }; + Process ps = new ProcessBuilder() + .command(startmonitorCmd) + .redirectErrorStream(true) + .start(); + } else { + Log.d(TAG, "No need to start SvcMonitor on client"); + } + } + + private void stopMonitor() + throws Exception { + if (isServer) { + Log.d(TAG, "StopMonitor on server"); + String[] stopmonitorCmd = { + "/system/bin/am", + "startservice", + "-a", "stop", + "com.google.android.experimental.svcmonitor/.SvcMonitor" + }; + Process ps = new ProcessBuilder() + .command(stopmonitorCmd) + .redirectErrorStream(true) + .start(); + } else { + Log.d(TAG, "No need to stop Svcmonitor on client"); + } + } + + public void stopService() { + if (mWorkerThread == null) { + Log.d(TAG, "no active thread"); + return; + } + + isShuttingDown = true; + + try { + stopMonitor(); + } catch (Exception e) { + Log.d(TAG, "Unable to stop SvcMonitor!", e); + } + + if (Thread.currentThread() != mWorkerThread) { + mWorkerThread.interrupt(); + Log.d(TAG, "Interrupting thread"); + try { + mWorkerThread.join(); + } catch (InterruptedException e) { + Log.d(TAG, "Unable to join thread!"); + } + } + + mWorkerThread = null; + stopSelf(); + Log.d(TAG, "Service stopped"); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + public static class ListenerRunnable implements Runnable { + private final BTtraffic bttraffic; + private final boolean sendAck; + private Intent intent; + private final int maxbuffersize = 20 * 1024 * 1024; + + public ListenerRunnable(BTtraffic bttraffic, Intent intent) { + this.bttraffic = bttraffic; + this.sendAck = intent.getBooleanExtra("ack", true); + this.intent = intent; + } + + @Override + public void run() { + BluetoothServerSocket serverSocket; + + try { + Log.d(TAG, "getting server socket"); + serverSocket = BluetoothAdapter.getDefaultAdapter() + .listenUsingInsecureRfcommWithServiceRecord( + SERVICE_NAME, SERVICE_UUID); + } catch (IOException e) { + Log.d(TAG, "error creating server socket, stopping thread"); + bttraffic.stopService(); + return; + } + + Log.d(TAG, "got server socket, starting accept loop"); + BluetoothSocket socket = null; + try { + Log.d(TAG, "accepting"); + socket = serverSocket.accept(); + + if (!Thread.interrupted()) { + Log.d(TAG, "accepted, listening"); + doListening(socket.getInputStream(), socket.getOutputStream()); + Log.d(TAG, "listen finished"); + } + } catch (IOException e) { + Log.d(TAG, "error while accepting or listening", e); + } finally { + Log.d(TAG, "Linster interruped"); + Log.d(TAG, "closing socket and stopping service"); + safeClose(serverSocket); + safeClose(socket); + if (!bttraffic.isShuttingDown) + bttraffic.stopService(); + } + + } + + private void doListening(InputStream inputStream, OutputStream outputStream) + throws IOException { + ByteBuffer byteBuffer = ByteBuffer.allocate(maxbuffersize); + + while (!Thread.interrupted()) { + readBytesIntoBuffer(inputStream, byteBuffer, 4); + byteBuffer.flip(); + int length = byteBuffer.getInt(); + if (Thread.interrupted()) + break; + readBytesIntoBuffer(inputStream, byteBuffer, length); + + if (sendAck) + outputStream.write(0x55); + } + } + + void readBytesIntoBuffer(InputStream inputStream, ByteBuffer byteBuffer, int numToRead) + throws IOException { + byteBuffer.clear(); + while (true) { + int position = byteBuffer.position(); + int remaining = numToRead - position; + if (remaining == 0) { + break; + } + int count = inputStream.read(byteBuffer.array(), position, remaining); + if (count < 0) { + throw new IOException("read the EOF"); + } + byteBuffer.position(position + count); + } + } + } + + public static class SenderRunnable implements Runnable { + private final BTtraffic bttraffic; + private final String remoteAddr; + private final int pkgsize, period; + private final int defaultpkgsize = 1024; + private final int defaultperiod = 5000; + private static ByteBuffer lengthBuffer = ByteBuffer.allocate(4); + + public SenderRunnable(BTtraffic bttraffic, String remoteAddr, Intent intent) { + this.bttraffic = bttraffic; + this.remoteAddr = remoteAddr; + this.pkgsize = intent.getIntExtra("size", defaultpkgsize); + this.period = intent.getIntExtra("period", defaultperiod); + } + + @Override + public void run() { + BluetoothDevice device = null; + try { + device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr); + } catch (IllegalArgumentException e) { + Log.d(TAG, "Invalid BT MAC address!\n"); + } + if (device == null) { + Log.d(TAG, "can't find matching device, stopping thread and service"); + bttraffic.stopService(); + return; + } + + BluetoothSocket socket = null; + try { + Log.d(TAG, "connecting to device with MAC addr: " + remoteAddr); + socket = device.createInsecureRfcommSocketToServiceRecord(SERVICE_UUID); + socket.connect(); + Log.d(TAG, "connected, starting to send"); + doSending(socket.getOutputStream()); + Log.d(TAG, "send stopped, stopping service"); + } catch (Exception e) { + Log.d(TAG, "error while sending", e); + } finally { + Log.d(TAG, "finishing, closing thread and service"); + safeClose(socket); + if (!bttraffic.isShuttingDown) + bttraffic.stopService(); + } + } + + private void doSending(OutputStream outputStream) throws IOException { + Log.w(TAG, "doSending"); + try { + Random random = new Random(System.currentTimeMillis()); + + byte[] bytes = new byte[pkgsize]; + random.nextBytes(bytes); + while (!Thread.interrupted()) { + writeBytes(outputStream, bytes.length); + outputStream.write(bytes, 0, bytes.length); + if (period < 0) + break; + if (period == 0) + continue; + + SystemClock.sleep(period); + } + Log.d(TAG, "Sender interrupted"); + } catch (IOException e) { + Log.d(TAG, "doSending got error", e); + } + } + + private static void writeBytes(OutputStream outputStream, int value) throws IOException { + lengthBuffer.putInt(value); + lengthBuffer.flip(); + outputStream.write(lengthBuffer.array(), lengthBuffer.position(), lengthBuffer.limit()); + } + } + +} diff --git a/core/tests/SvcMonitor/Android.mk b/core/tests/SvcMonitor/Android.mk new file mode 100644 index 0000000..2b80455 --- /dev/null +++ b/core/tests/SvcMonitor/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_RESOURCE_DIR := \ + $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := svcmonitor +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/core/tests/SvcMonitor/AndroidManifest.xml b/core/tests/SvcMonitor/AndroidManifest.xml new file mode 100644 index 0000000..de5a9bd --- /dev/null +++ b/core/tests/SvcMonitor/AndroidManifest.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.experimental.svcmonitor" > + + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> + + <uses-sdk + android:minSdkVersion="18" + android:targetSdkVersion="18" + /> + <application + android:allowBackup="false" + android:label="@string/app_name" > + <service + android:name=".SvcMonitor" + android:enabled="true" + android:exported="true" > + </service> + </application> + +</manifest> diff --git a/core/tests/SvcMonitor/README b/core/tests/SvcMonitor/README new file mode 100644 index 0000000..13a4380 --- /dev/null +++ b/core/tests/SvcMonitor/README @@ -0,0 +1,27 @@ +This Android service measures CPU usage of a program and an underlying system service it relies on. +An example of this would be an android app XYZ communicates to some other device via Bluetooth. The +SvcMonitor service can monitor the CPU usage of XYZ and com.android.bluetooth. + +Usage: + +To start the service: +$ adb shell am startservice -a start \ +-e java XYZ -e hal com.android.bluetooth \ +com.google.android.experimental.svcmonitor/.SvcMonitor + +To stop the service: +$ adb shell am startservice -a stop \ +com.google.android.experimental.svcmonitor/.SvcMonitor + +To stop the service config: +$ adb shell am startservice -a change \ +-e java NewName -e hal NewService \ +com.google.android.experimental.svcmonitor/.SvcMonitor + +To monitor the data: +$ adb logcat | grep XYZ + +Options: +-e java NameOfProgram: any running process’s name. +-e hal NameOfSysService: name of the system service the previous process relies on. +--ei period: period between each measurement (frequency). Unit: ms, Default:1000, Min: 100 diff --git a/core/tests/SvcMonitor/res/values/strings.xml b/core/tests/SvcMonitor/res/values/strings.xml new file mode 100644 index 0000000..e70276e --- /dev/null +++ b/core/tests/SvcMonitor/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">Bluetooth Test</string> +</resources> diff --git a/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java b/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java new file mode 100644 index 0000000..a451445 --- /dev/null +++ b/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java @@ -0,0 +1,209 @@ +package com.google.android.experimental.svcmonitor; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.SystemClock; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.lang.Runnable; +import java.lang.Thread; +import java.util.Set; + +public class SvcMonitor extends Service { + public static final String TAG = "svcmonitor"; + String javaProc, halProc; + volatile Thread tMonitor; + int period; + + public SvcMonitor() {}; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent == null) { + stopSelf(); + return 0; + } + Log.d(TAG, "Starting SvcMonitor"); + if ("stop".equals(intent.getAction())) { + stopService(); + } else if ("start".equals(intent.getAction())) { + startMonitor(intent); + } else if ("change".equals(intent.getAction())) { + changeConfig(intent); + } else { + Log.d(TAG, "unknown action: + " + intent.getAction()); + } + return 0; + } + + private void changeConfig(Intent intent) { + if (tMonitor == null) { + Log.d(TAG, "Service not active. Start service first"); + return; + } + stopThread(); + startMonitor(intent); + } + + private void startMonitor(Intent intent) { + if (tMonitor != null) { + Log.d(TAG, "thread already active"); + return; + } + javaProc = intent.getStringExtra("java"); + halProc = intent.getStringExtra("hal"); + period = intent.getIntExtra("period", 1000); + if (javaProc == null || halProc == null || period < 100) { + Log.d(TAG, "Failed starting monitor, invalid arguments."); + stopSelf(); + return; + } + Runnable monitor = new MonitorRunnable(this); + tMonitor = new Thread(monitor); + tMonitor.start(); + } + + private void stopService() { + stopThread(); + stopSelf(); + Log.d(TAG, "SvcMonitor stopped"); + } + + private void stopThread() { + if (tMonitor == null) { + Log.d(TAG, "no active thread"); + return; + } + Log.d(TAG, "interrupting monitor thread"); + tMonitor.interrupt(); + try { + tMonitor.join(); + } catch (InterruptedException e) { + Log.d(TAG, "Unable to finish monitor thread"); + } + tMonitor = null; + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + public static class MonitorRunnable implements Runnable { + long java_time_old, hal_time_old, cpu_time_old = -1; + String javaPID, halPID; + SvcMonitor svcmonitor; + static String javaProcTAG; + int period; + + public MonitorRunnable(SvcMonitor svcmonitor) { + this.svcmonitor = svcmonitor; + this.period = svcmonitor.period; + javaPID = getPIDof(svcmonitor.javaProc); + halPID = getPIDof(svcmonitor.halProc); + java_time_old = getPsTime(javaPID); + hal_time_old = getPsTime(halPID); + cpu_time_old = getPsTime(""); + javaProcTAG = String.valueOf(svcmonitor.javaProc.toCharArray()); + } + + @Override + public void run() { + if (halPID.isEmpty() || javaPID.isEmpty()) { + Log.d(javaProcTAG, "No such process: " + + (halPID.isEmpty() ? svcmonitor.halProc : svcmonitor.javaProc)); + return; + } + while (!Thread.interrupted()) { + calculateUsage(); + SystemClock.sleep(period); + } + Log.d(TAG, "Stopping monitor thread"); + } + + private void calculateUsage() { + long java_time = getPsTime(javaPID); + long hal_time = getPsTime(halPID); + long cpu_time = getPsTime(""); + + if (cpu_time_old >= 0) { + float java_diff = (float) (java_time - java_time_old); + float hal_diff = (float) (hal_time - hal_time_old); + float cpu_diff = (float) (cpu_time - cpu_time_old); + Log.w(javaProcTAG, "\n----------------\n"); + Log.w(javaProcTAG, "JAVA level CPU: " + + (java_diff * 100.0 / cpu_diff) + "%\n"); + Log.w(javaProcTAG, " HAL level CPU: " + + (hal_diff * 100.0 / cpu_diff) + "%\n"); + Log.w(javaProcTAG, " SYS level CPU: " + + ((java_diff + hal_diff) * 100.0 / cpu_diff) + "%\n"); + } else { + Log.w(TAG, "Waiting for status\n"); + } + + java_time_old = java_time; + hal_time_old = hal_time; + cpu_time_old = cpu_time; + } + + private String getPIDof(String psName) { + String pid = ""; + + try { + String[] cmd = {"/system/bin/sh", "-c", "ps | grep " + psName}; + Process ps = Runtime.getRuntime().exec(cmd); + BufferedReader in = new BufferedReader( + new InputStreamReader(ps.getInputStream())); + String temp = in.readLine(); + if (temp == null || temp.isEmpty()) + throw new IOException("No such process: " + psName); + pid = temp.split(" +")[1]; + in.close(); + } catch (IOException e) { + Log.d(javaProcTAG, "Error finding PID of process: " + psName + "\n", e); + } + return pid; + } + + private long getPsTime(String pid) { + String psStat = getPsStat("/" + pid); + String[] statBreakDown = psStat.split(" +"); + long psTime; + + if (pid.isEmpty()) { + psTime = Long.parseLong(statBreakDown[1]) + + Long.parseLong(statBreakDown[2]) + + Long.parseLong(statBreakDown[3]) + + Long.parseLong(statBreakDown[4]); + } else { + psTime = Long.parseLong(statBreakDown[13]) + + Long.parseLong(statBreakDown[14]); + } + + return psTime; + } + + private String getPsStat(String psname) { + String stat = ""; + try { + FileInputStream fs = new FileInputStream("/proc" + psname + "/stat"); + BufferedReader br = new BufferedReader(new InputStreamReader(fs)); + stat = br.readLine(); + fs.close(); + } catch (IOException e) { + Log.d(TAG, "Error retreiving stat. \n"); + } + return stat; + } + } +} |