diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-07-14 17:23:28 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-07-14 17:23:28 -0700 |
commit | b3a26f4d94f390d4baeac0fc11ccb9d451b67dbd (patch) | |
tree | 775cba20a95ca11406f6bfb09d82b0f76fb2c847 /services/java/com | |
parent | 7770b90129537dc8af0992d64a9f44d5d236562f (diff) | |
parent | 45ce864ef41ce90938cc34d42a8e1075f69e7a61 (diff) | |
download | frameworks_base-b3a26f4d94f390d4baeac0fc11ccb9d451b67dbd.zip frameworks_base-b3a26f4d94f390d4baeac0fc11ccb9d451b67dbd.tar.gz frameworks_base-b3a26f4d94f390d4baeac0fc11ccb9d451b67dbd.tar.bz2 |
Merge "Move LoadAverageService to the SystemUI apk."
Diffstat (limited to 'services/java/com')
4 files changed, 1 insertions, 1176 deletions
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java index b9ff8d0..6665614 100644 --- a/services/java/com/android/server/BootReceiver.java +++ b/services/java/com/android/server/BootReceiver.java @@ -17,7 +17,6 @@ package com.android.server; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -28,7 +27,6 @@ import android.os.FileObserver; import android.os.FileUtils; import android.os.RecoverySystem; import android.os.SystemProperties; -import android.provider.Settings; import android.util.Slog; import java.io.File; @@ -59,17 +57,6 @@ public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { - try { - // Start the load average overlay, if activated - ContentResolver res = context.getContentResolver(); - if (Settings.System.getInt(res, Settings.System.SHOW_PROCESSES, 0) != 0) { - Intent loadavg = new Intent(context, com.android.server.LoadAverageService.class); - context.startService(loadavg); - } - } catch (Exception e) { - Slog.e(TAG, "Can't start load average service", e); - } - // Log boot events in the background to avoid blocking the main thread with I/O new Thread() { @Override diff --git a/services/java/com/android/server/LoadAverageService.java b/services/java/com/android/server/LoadAverageService.java deleted file mode 100644 index e05b570..0000000 --- a/services/java/com/android/server/LoadAverageService.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.view.Gravity; -import android.view.View; -import android.view.WindowManager; - -public class LoadAverageService extends Service { - private View mView; - - private static final class Stats extends ProcessStats { - String mLoadText; - int mLoadWidth; - - private final Paint mPaint; - - Stats(Paint paint) { - super(false); - mPaint = paint; - } - - @Override - public void onLoadChanged(float load1, float load5, float load15) { - mLoadText = load1 + " / " + load5 + " / " + load15; - mLoadWidth = (int)mPaint.measureText(mLoadText); - } - - @Override - public int onMeasureProcessName(String name) { - return (int)mPaint.measureText(name); - } - } - - private class LoadView extends View { - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (msg.what == 1) { - mStats.update(); - updateDisplay(); - Message m = obtainMessage(1); - sendMessageDelayed(m, 2000); - } - } - }; - - private final Stats mStats; - - private Paint mLoadPaint; - private Paint mAddedPaint; - private Paint mRemovedPaint; - private Paint mShadowPaint; - private Paint mShadow2Paint; - private Paint mIrqPaint; - private Paint mSystemPaint; - private Paint mUserPaint; - private float mAscent; - private int mFH; - - private int mNeededWidth; - private int mNeededHeight; - - LoadView(Context c) { - super(c); - - setPadding(4, 4, 4, 4); - //setBackgroundResource(com.android.internal.R.drawable.load_average_background); - - // Need to scale text size by density... but we won't do it - // linearly, because with higher dps it is nice to squeeze the - // text a bit to fit more of it. And with lower dps, trying to - // go much smaller will result in unreadable text. - int textSize = 10; - float density = c.getResources().getDisplayMetrics().density; - if (density < 1) { - textSize = 9; - } else { - textSize = (int)(10*density); - if (textSize < 10) { - textSize = 10; - } - } - mLoadPaint = new Paint(); - mLoadPaint.setAntiAlias(true); - mLoadPaint.setTextSize(textSize); - mLoadPaint.setARGB(255, 255, 255, 255); - - mAddedPaint = new Paint(); - mAddedPaint.setAntiAlias(true); - mAddedPaint.setTextSize(textSize); - mAddedPaint.setARGB(255, 128, 255, 128); - - mRemovedPaint = new Paint(); - mRemovedPaint.setAntiAlias(true); - mRemovedPaint.setStrikeThruText(true); - mRemovedPaint.setTextSize(textSize); - mRemovedPaint.setARGB(255, 255, 128, 128); - - mShadowPaint = new Paint(); - mShadowPaint.setAntiAlias(true); - mShadowPaint.setTextSize(textSize); - //mShadowPaint.setFakeBoldText(true); - mShadowPaint.setARGB(192, 0, 0, 0); - mLoadPaint.setShadowLayer(4, 0, 0, 0xff000000); - - mShadow2Paint = new Paint(); - mShadow2Paint.setAntiAlias(true); - mShadow2Paint.setTextSize(textSize); - //mShadow2Paint.setFakeBoldText(true); - mShadow2Paint.setARGB(192, 0, 0, 0); - mLoadPaint.setShadowLayer(2, 0, 0, 0xff000000); - - mIrqPaint = new Paint(); - mIrqPaint.setARGB(0x80, 0, 0, 0xff); - mIrqPaint.setShadowLayer(2, 0, 0, 0xff000000); - mSystemPaint = new Paint(); - mSystemPaint.setARGB(0x80, 0xff, 0, 0); - mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000); - mUserPaint = new Paint(); - mUserPaint.setARGB(0x80, 0, 0xff, 0); - mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000); - - mAscent = mLoadPaint.ascent(); - float descent = mLoadPaint.descent(); - mFH = (int)(descent - mAscent + .5f); - - mStats = new Stats(mLoadPaint); - mStats.init(); - updateDisplay(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mHandler.sendEmptyMessage(1); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mHandler.removeMessages(1); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec), - resolveSize(mNeededHeight, heightMeasureSpec)); - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - final int W = mNeededWidth; - final int RIGHT = getWidth()-1; - - final Stats stats = mStats; - final int userTime = stats.getLastUserTime(); - final int systemTime = stats.getLastSystemTime(); - final int iowaitTime = stats.getLastIoWaitTime(); - final int irqTime = stats.getLastIrqTime(); - final int softIrqTime = stats.getLastSoftIrqTime(); - final int idleTime = stats.getLastIdleTime(); - - final int totalTime = userTime+systemTime+iowaitTime+irqTime+softIrqTime+idleTime; - if (totalTime == 0) { - return; - } - int userW = (userTime*W)/totalTime; - int systemW = (systemTime*W)/totalTime; - int irqW = ((iowaitTime+irqTime+softIrqTime)*W)/totalTime; - - int x = RIGHT - mPaddingRight; - int top = mPaddingTop + 2; - int bottom = mPaddingTop + mFH - 2; - - if (irqW > 0) { - canvas.drawRect(x-irqW, top, x, bottom, mIrqPaint); - x -= irqW; - } - if (systemW > 0) { - canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint); - x -= systemW; - } - if (userW > 0) { - canvas.drawRect(x-userW, top, x, bottom, mUserPaint); - x -= userW; - } - - int y = mPaddingTop - (int)mAscent; - canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1, - y-1, mShadowPaint); - canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1, - y+1, mShadowPaint); - canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1, - y-1, mShadow2Paint); - canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1, - y+1, mShadow2Paint); - canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth, - y, mLoadPaint); - - int N = stats.countWorkingStats(); - for (int i=0; i<N; i++) { - Stats.Stats st = stats.getWorkingStats(i); - y += mFH; - top += mFH; - bottom += mFH; - - userW = (st.rel_utime*W)/totalTime; - systemW = (st.rel_stime*W)/totalTime; - x = RIGHT - mPaddingRight; - if (systemW > 0) { - canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint); - x -= systemW; - } - if (userW > 0) { - canvas.drawRect(x-userW, top, x, bottom, mUserPaint); - x -= userW; - } - - canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1, - y-1, mShadowPaint); - canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1, - y+1, mShadowPaint); - canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1, - y-1, mShadow2Paint); - canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1, - y+1, mShadow2Paint); - Paint p = mLoadPaint; - if (st.added) p = mAddedPaint; - if (st.removed) p = mRemovedPaint; - canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth, y, p); - } - } - - void updateDisplay() { - final Stats stats = mStats; - final int NW = stats.countWorkingStats(); - - int maxWidth = stats.mLoadWidth; - for (int i=0; i<NW; i++) { - Stats.Stats st = stats.getWorkingStats(i); - if (st.nameWidth > maxWidth) { - maxWidth = st.nameWidth; - } - } - - int neededWidth = mPaddingLeft + mPaddingRight + maxWidth; - int neededHeight = mPaddingTop + mPaddingBottom + (mFH*(1+NW)); - if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) { - mNeededWidth = neededWidth; - mNeededHeight = neededHeight; - requestLayout(); - } else { - invalidate(); - } - } - } - - @Override - public void onCreate() { - super.onCreate(); - mView = new LoadView(this); - WindowManager.LayoutParams params = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, - PixelFormat.TRANSLUCENT); - params.gravity = Gravity.RIGHT | Gravity.TOP; - params.setTitle("Load Average"); - WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE); - wm.addView(mView, params); - } - - @Override - public void onDestroy() { - super.onDestroy(); - ((WindowManager)getSystemService(WINDOW_SERVICE)).removeView(mView); - mView = null; - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - -} diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java deleted file mode 100644 index f693ed1..0000000 --- a/services/java/com/android/server/ProcessStats.java +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.os.Process.*; - -import android.os.Process; -import android.os.SystemClock; -import android.util.Slog; - -import java.io.File; -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.StringTokenizer; - -public class ProcessStats { - private static final String TAG = "ProcessStats"; - private static final boolean DEBUG = false; - private static final boolean localLOGV = DEBUG || false; - - private static final int[] PROCESS_STATS_FORMAT = new int[] { - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_PARENS, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 9: minor faults - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 11: major faults - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 13: utime - PROC_SPACE_TERM|PROC_OUT_LONG // 14: stime - }; - - static final int PROCESS_STAT_MINOR_FAULTS = 0; - static final int PROCESS_STAT_MAJOR_FAULTS = 1; - static final int PROCESS_STAT_UTIME = 2; - static final int PROCESS_STAT_STIME = 3; - - /** Stores user time and system time in 100ths of a second. */ - private final long[] mProcessStatsData = new long[4]; - /** Stores user time and system time in 100ths of a second. */ - private final long[] mSinglePidStatsData = new long[4]; - - private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] { - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING, // 1: name - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 9: minor faults - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 11: major faults - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 13: utime - PROC_SPACE_TERM|PROC_OUT_LONG, // 14: stime - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM, - PROC_SPACE_TERM|PROC_OUT_LONG, // 21: vsize - }; - - static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1; - static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2; - static final int PROCESS_FULL_STAT_UTIME = 3; - static final int PROCESS_FULL_STAT_STIME = 4; - static final int PROCESS_FULL_STAT_VSIZE = 5; - - private final String[] mProcessFullStatsStringData = new String[6]; - private final long[] mProcessFullStatsData = new long[6]; - - private static final int[] SYSTEM_CPU_FORMAT = new int[] { - PROC_SPACE_TERM|PROC_COMBINE, - PROC_SPACE_TERM|PROC_OUT_LONG, // 1: user time - PROC_SPACE_TERM|PROC_OUT_LONG, // 2: nice time - PROC_SPACE_TERM|PROC_OUT_LONG, // 3: sys time - PROC_SPACE_TERM|PROC_OUT_LONG, // 4: idle time - PROC_SPACE_TERM|PROC_OUT_LONG, // 5: iowait time - PROC_SPACE_TERM|PROC_OUT_LONG, // 6: irq time - PROC_SPACE_TERM|PROC_OUT_LONG // 7: softirq time - }; - - private final long[] mSystemCpuData = new long[7]; - - private static final int[] LOAD_AVERAGE_FORMAT = new int[] { - PROC_SPACE_TERM|PROC_OUT_FLOAT, // 0: 1 min - PROC_SPACE_TERM|PROC_OUT_FLOAT, // 1: 5 mins - PROC_SPACE_TERM|PROC_OUT_FLOAT // 2: 15 mins - }; - - private final float[] mLoadAverageData = new float[3]; - - private final boolean mIncludeThreads; - - private float mLoad1 = 0; - private float mLoad5 = 0; - private float mLoad15 = 0; - - private long mCurrentSampleTime; - private long mLastSampleTime; - - private long mCurrentSampleRealTime; - private long mLastSampleRealTime; - - private long mBaseUserTime; - private long mBaseSystemTime; - private long mBaseIoWaitTime; - private long mBaseIrqTime; - private long mBaseSoftIrqTime; - private long mBaseIdleTime; - private int mRelUserTime; - private int mRelSystemTime; - private int mRelIoWaitTime; - private int mRelIrqTime; - private int mRelSoftIrqTime; - private int mRelIdleTime; - - private int[] mCurPids; - private int[] mCurThreadPids; - - private final ArrayList<Stats> mProcStats = new ArrayList<Stats>(); - private final ArrayList<Stats> mWorkingProcs = new ArrayList<Stats>(); - private boolean mWorkingProcsSorted; - - private boolean mFirst = true; - - private byte[] mBuffer = new byte[256]; - - /** - * The time in microseconds that the CPU has been running at each speed. - */ - private long[] mCpuSpeedTimes; - - /** - * The relative time in microseconds that the CPU has been running at each speed. - */ - private long[] mRelCpuSpeedTimes; - - /** - * The different speeds that the CPU can be running at. - */ - private long[] mCpuSpeeds; - - public static class Stats { - public final int pid; - final String statFile; - final String cmdlineFile; - final String threadsDir; - final ArrayList<Stats> threadStats; - final ArrayList<Stats> workingThreads; - - public boolean interesting; - - public String baseName; - public String name; - int nameWidth; - - public long base_uptime; - public long rel_uptime; - - public long base_utime; - public long base_stime; - public int rel_utime; - public int rel_stime; - - public long base_minfaults; - public long base_majfaults; - public int rel_minfaults; - public int rel_majfaults; - - public boolean active; - public boolean working; - public boolean added; - public boolean removed; - - Stats(int _pid, int parentPid, boolean includeThreads) { - pid = _pid; - if (parentPid < 0) { - final File procDir = new File("/proc", Integer.toString(pid)); - statFile = new File(procDir, "stat").toString(); - cmdlineFile = new File(procDir, "cmdline").toString(); - threadsDir = (new File(procDir, "task")).toString(); - if (includeThreads) { - threadStats = new ArrayList<Stats>(); - workingThreads = new ArrayList<Stats>(); - } else { - threadStats = null; - workingThreads = null; - } - } else { - final File procDir = new File("/proc", Integer.toString( - parentPid)); - final File taskDir = new File( - new File(procDir, "task"), Integer.toString(pid)); - statFile = new File(taskDir, "stat").toString(); - cmdlineFile = null; - threadsDir = null; - threadStats = null; - workingThreads = null; - } - } - } - - private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() { - public final int - compare(Stats sta, Stats stb) { - int ta = sta.rel_utime + sta.rel_stime; - int tb = stb.rel_utime + stb.rel_stime; - if (ta != tb) { - return ta > tb ? -1 : 1; - } - if (sta.added != stb.added) { - return sta.added ? -1 : 1; - } - if (sta.removed != stb.removed) { - return sta.added ? -1 : 1; - } - return 0; - } - }; - - - public ProcessStats(boolean includeThreads) { - mIncludeThreads = includeThreads; - } - - public void onLoadChanged(float load1, float load5, float load15) { - } - - public int onMeasureProcessName(String name) { - return 0; - } - - public void init() { - if (DEBUG) Slog.v(TAG, "Init: " + this); - mFirst = true; - update(); - } - - public void update() { - if (DEBUG) Slog.v(TAG, "Update: " + this); - mLastSampleTime = mCurrentSampleTime; - mCurrentSampleTime = SystemClock.uptimeMillis(); - mLastSampleRealTime = mCurrentSampleRealTime; - mCurrentSampleRealTime = SystemClock.elapsedRealtime(); - - final long[] sysCpu = mSystemCpuData; - if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, - null, sysCpu, null)) { - // Total user time is user + nice time. - final long usertime = sysCpu[0]+sysCpu[1]; - // Total system time is simply system time. - final long systemtime = sysCpu[2]; - // Total idle time is simply idle time. - final long idletime = sysCpu[3]; - // Total irq time is iowait + irq + softirq time. - final long iowaittime = sysCpu[4]; - final long irqtime = sysCpu[5]; - final long softirqtime = sysCpu[6]; - - mRelUserTime = (int)(usertime - mBaseUserTime); - mRelSystemTime = (int)(systemtime - mBaseSystemTime); - mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime); - mRelIrqTime = (int)(irqtime - mBaseIrqTime); - mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime); - mRelIdleTime = (int)(idletime - mBaseIdleTime); - - if (DEBUG) { - Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1] - + " S:" + sysCpu[2] + " I:" + sysCpu[3] - + " W:" + sysCpu[4] + " Q:" + sysCpu[5] - + " O:" + sysCpu[6]); - Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime - + " I:" + mRelIdleTime + " Q:" + mRelIrqTime); - } - - mBaseUserTime = usertime; - mBaseSystemTime = systemtime; - mBaseIoWaitTime = iowaittime; - mBaseIrqTime = irqtime; - mBaseSoftIrqTime = softirqtime; - mBaseIdleTime = idletime; - } - - mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats); - - final float[] loadAverages = mLoadAverageData; - if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT, - null, null, loadAverages)) { - float load1 = loadAverages[0]; - float load5 = loadAverages[1]; - float load15 = loadAverages[2]; - if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) { - mLoad1 = load1; - mLoad5 = load5; - mLoad15 = load15; - onLoadChanged(load1, load5, load15); - } - } - - if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: " - + (SystemClock.uptimeMillis()-mCurrentSampleTime)); - - mWorkingProcsSorted = false; - mFirst = false; - } - - private int[] collectStats(String statsFile, int parentPid, boolean first, - int[] curPids, ArrayList<Stats> allProcs) { - - int[] pids = Process.getPids(statsFile, curPids); - int NP = (pids == null) ? 0 : pids.length; - int NS = allProcs.size(); - int curStatsIndex = 0; - for (int i=0; i<NP; i++) { - int pid = pids[i]; - if (pid < 0) { - NP = pid; - break; - } - Stats st = curStatsIndex < NS ? allProcs.get(curStatsIndex) : null; - - if (st != null && st.pid == pid) { - // Update an existing process... - st.added = false; - st.working = false; - curStatsIndex++; - if (DEBUG) Slog.v(TAG, "Existing " - + (parentPid < 0 ? "process" : "thread") - + " pid " + pid + ": " + st); - - if (st.interesting) { - final long uptime = SystemClock.uptimeMillis(); - - final long[] procStats = mProcessStatsData; - if (!Process.readProcFile(st.statFile.toString(), - PROCESS_STATS_FORMAT, null, procStats, null)) { - continue; - } - - final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS]; - final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS]; - final long utime = procStats[PROCESS_STAT_UTIME]; - final long stime = procStats[PROCESS_STAT_STIME]; - - if (utime == st.base_utime && stime == st.base_stime) { - st.rel_utime = 0; - st.rel_stime = 0; - st.rel_minfaults = 0; - st.rel_majfaults = 0; - if (st.active) { - st.active = false; - } - continue; - } - - if (!st.active) { - st.active = true; - } - - if (parentPid < 0) { - getName(st, st.cmdlineFile); - if (st.threadStats != null) { - mCurThreadPids = collectStats(st.threadsDir, pid, false, - mCurThreadPids, st.threadStats); - } - } - - if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid - + " utime=" + utime + "-" + st.base_utime - + " stime=" + stime + "-" + st.base_stime - + " minfaults=" + minfaults + "-" + st.base_minfaults - + " majfaults=" + majfaults + "-" + st.base_majfaults); - - st.rel_uptime = uptime - st.base_uptime; - st.base_uptime = uptime; - st.rel_utime = (int)(utime - st.base_utime); - st.rel_stime = (int)(stime - st.base_stime); - st.base_utime = utime; - st.base_stime = stime; - st.rel_minfaults = (int)(minfaults - st.base_minfaults); - st.rel_majfaults = (int)(majfaults - st.base_majfaults); - st.base_minfaults = minfaults; - st.base_majfaults = majfaults; - st.working = true; - } - - continue; - } - - if (st == null || st.pid > pid) { - // We have a new process! - st = new Stats(pid, parentPid, mIncludeThreads); - allProcs.add(curStatsIndex, st); - curStatsIndex++; - NS++; - if (DEBUG) Slog.v(TAG, "New " - + (parentPid < 0 ? "process" : "thread") - + " pid " + pid + ": " + st); - - final String[] procStatsString = mProcessFullStatsStringData; - final long[] procStats = mProcessFullStatsData; - st.base_uptime = SystemClock.uptimeMillis(); - if (Process.readProcFile(st.statFile.toString(), - PROCESS_FULL_STATS_FORMAT, procStatsString, - procStats, null)) { - // This is a possible way to filter out processes that - // are actually kernel threads... do we want to? Some - // of them do use CPU, but there can be a *lot* that are - // not doing anything. - if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) { - st.interesting = true; - st.baseName = procStatsString[0]; - st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS]; - st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS]; - st.base_utime = procStats[PROCESS_FULL_STAT_UTIME]; - st.base_stime = procStats[PROCESS_FULL_STAT_STIME]; - } else { - Slog.i(TAG, "Skipping kernel process pid " + pid - + " name " + procStatsString[0]); - st.baseName = procStatsString[0]; - } - } else { - Slog.w(TAG, "Skipping unknown process pid " + pid); - st.baseName = "<unknown>"; - st.base_utime = st.base_stime = 0; - st.base_minfaults = st.base_majfaults = 0; - } - - if (parentPid < 0) { - getName(st, st.cmdlineFile); - if (st.threadStats != null) { - mCurThreadPids = collectStats(st.threadsDir, pid, true, - mCurThreadPids, st.threadStats); - } - } else if (st.interesting) { - st.name = st.baseName; - st.nameWidth = onMeasureProcessName(st.name); - } - - if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid - + " utime=" + st.base_utime + " stime=" + st.base_stime - + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults); - - st.rel_utime = 0; - st.rel_stime = 0; - st.rel_minfaults = 0; - st.rel_majfaults = 0; - st.added = true; - if (!first && st.interesting) { - st.working = true; - } - continue; - } - - // This process has gone away! - st.rel_utime = 0; - st.rel_stime = 0; - st.rel_minfaults = 0; - st.rel_majfaults = 0; - st.removed = true; - st.working = true; - allProcs.remove(curStatsIndex); - NS--; - if (DEBUG) Slog.v(TAG, "Removed " - + (parentPid < 0 ? "process" : "thread") - + " pid " + pid + ": " + st); - // Decrement the loop counter so that we process the current pid - // again the next time through the loop. - i--; - continue; - } - - while (curStatsIndex < NS) { - // This process has gone away! - final Stats st = allProcs.get(curStatsIndex); - st.rel_utime = 0; - st.rel_stime = 0; - st.rel_minfaults = 0; - st.rel_majfaults = 0; - st.removed = true; - st.working = true; - allProcs.remove(curStatsIndex); - NS--; - if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st); - } - - return pids; - } - - public long getCpuTimeForPid(int pid) { - final String statFile = "/proc/" + pid + "/stat"; - final long[] statsData = mSinglePidStatsData; - if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT, - null, statsData, null)) { - long time = statsData[PROCESS_STAT_UTIME] - + statsData[PROCESS_STAT_STIME]; - return time; - } - return 0; - } - - /** - * Returns the times spent at each CPU speed, since the last call to this method. If this - * is the first time, it will return 1 for each value. - * @return relative times spent at different speed steps. - */ - public long[] getLastCpuSpeedTimes() { - if (mCpuSpeedTimes == null) { - mCpuSpeedTimes = getCpuSpeedTimes(null); - mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length]; - for (int i = 0; i < mCpuSpeedTimes.length; i++) { - mRelCpuSpeedTimes[i] = 1; // Initialize - } - } else { - getCpuSpeedTimes(mRelCpuSpeedTimes); - for (int i = 0; i < mCpuSpeedTimes.length; i++) { - long temp = mRelCpuSpeedTimes[i]; - mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i]; - mCpuSpeedTimes[i] = temp; - } - } - return mRelCpuSpeedTimes; - } - - private long[] getCpuSpeedTimes(long[] out) { - long[] tempTimes = out; - long[] tempSpeeds = mCpuSpeeds; - final int MAX_SPEEDS = 20; - if (out == null) { - tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that - tempSpeeds = new long[MAX_SPEEDS]; - } - int speed = 0; - String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0'); - // Note: file may be null on kernels without cpufreq (i.e. the emulator's) - if (file != null) { - StringTokenizer st = new StringTokenizer(file, "\n "); - while (st.hasMoreElements()) { - String token = st.nextToken(); - try { - long val = Long.parseLong(token); - tempSpeeds[speed] = val; - token = st.nextToken(); - val = Long.parseLong(token); - tempTimes[speed] = val; - speed++; - if (speed == MAX_SPEEDS) break; // No more - if (localLOGV && out == null) { - Slog.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1] - + "\t" + tempTimes[speed - 1]); - } - } catch (NumberFormatException nfe) { - Slog.i(TAG, "Unable to parse time_in_state"); - } - } - } - if (out == null) { - out = new long[speed]; - mCpuSpeeds = new long[speed]; - System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed); - System.arraycopy(tempTimes, 0, out, 0, speed); - } - return out; - } - - final public int getLastUserTime() { - return mRelUserTime; - } - - final public int getLastSystemTime() { - return mRelSystemTime; - } - - final public int getLastIoWaitTime() { - return mRelIoWaitTime; - } - - final public int getLastIrqTime() { - return mRelIrqTime; - } - - final public int getLastSoftIrqTime() { - return mRelSoftIrqTime; - } - - final public int getLastIdleTime() { - return mRelIdleTime; - } - - final public float getTotalCpuPercent() { - return ((float)(mRelUserTime+mRelSystemTime+mRelIrqTime)*100) - / (mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime); - } - - final void buildWorkingProcs() { - if (!mWorkingProcsSorted) { - mWorkingProcs.clear(); - final int N = mProcStats.size(); - for (int i=0; i<N; i++) { - Stats stats = mProcStats.get(i); - if (stats.working) { - mWorkingProcs.add(stats); - if (stats.threadStats != null && stats.threadStats.size() > 1) { - stats.workingThreads.clear(); - final int M = stats.threadStats.size(); - for (int j=0; j<M; j++) { - Stats tstats = stats.threadStats.get(j); - if (tstats.working) { - stats.workingThreads.add(tstats); - } - } - Collections.sort(stats.workingThreads, sLoadComparator); - } - } - } - Collections.sort(mWorkingProcs, sLoadComparator); - mWorkingProcsSorted = true; - } - } - - final public int countStats() { - return mProcStats.size(); - } - - final public Stats getStats(int index) { - return mProcStats.get(index); - } - - final public int countWorkingStats() { - buildWorkingProcs(); - return mWorkingProcs.size(); - } - - final public Stats getWorkingStats(int index) { - return mWorkingProcs.get(index); - } - - final public String printCurrentLoad() { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.print("Load: "); - pw.print(mLoad1); - pw.print(" / "); - pw.print(mLoad5); - pw.print(" / "); - pw.println(mLoad15); - return sw.toString(); - } - - final public String printCurrentState(long now) { - buildWorkingProcs(); - - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - - pw.print("CPU usage from "); - if (now > mLastSampleTime) { - pw.print(now-mLastSampleTime); - pw.print("ms to "); - pw.print(now-mCurrentSampleTime); - pw.print("ms ago"); - } else { - pw.print(mLastSampleTime-now); - pw.print("ms to "); - pw.print(mCurrentSampleTime-now); - pw.print("ms later"); - } - - long sampleTime = mCurrentSampleTime - mLastSampleTime; - long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime; - long percAwake = (sampleTime*100) / sampleRealTime; - if (percAwake != 100) { - pw.print(" with "); - pw.print(percAwake); - pw.print("% awake"); - } - pw.println(":"); - - final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime - + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime; - - if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time " - + (mCurrentSampleTime-mLastSampleTime)); - - int N = mWorkingProcs.size(); - for (int i=0; i<N; i++) { - Stats st = mWorkingProcs.get(i); - printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": " "), - st.pid, st.name, (int)(st.rel_uptime+5)/10, - st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults); - if (!st.removed && st.workingThreads != null) { - int M = st.workingThreads.size(); - for (int j=0; j<M; j++) { - Stats tst = st.workingThreads.get(j); - printProcessCPU(pw, - tst.added ? " +" : (tst.removed ? " -": " "), - tst.pid, tst.name, (int)(st.rel_uptime+5)/10, - tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0); - } - } - } - - printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime, - mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0); - - return sw.toString(); - } - - private void printRatio(PrintWriter pw, long numerator, long denominator) { - long thousands = (numerator*1000)/denominator; - long hundreds = thousands/10; - pw.print(hundreds); - if (hundreds < 10) { - long remainder = thousands - (hundreds*10); - if (remainder != 0) { - pw.print('.'); - pw.print(remainder); - } - } - } - - private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label, - int totalTime, int user, int system, int iowait, int irq, int softIrq, - int minFaults, int majFaults) { - pw.print(prefix); - if (totalTime == 0) totalTime = 1; - printRatio(pw, user+system+iowait+irq+softIrq, totalTime); - pw.print("% "); - if (pid >= 0) { - pw.print(pid); - pw.print("/"); - } - pw.print(label); - pw.print(": "); - printRatio(pw, user, totalTime); - pw.print("% user + "); - printRatio(pw, system, totalTime); - pw.print("% kernel"); - if (iowait > 0) { - pw.print(" + "); - printRatio(pw, iowait, totalTime); - pw.print("% iowait"); - } - if (irq > 0) { - pw.print(" + "); - printRatio(pw, irq, totalTime); - pw.print("% irq"); - } - if (softIrq > 0) { - pw.print(" + "); - printRatio(pw, softIrq, totalTime); - pw.print("% softirq"); - } - if (minFaults > 0 || majFaults > 0) { - pw.print(" / faults:"); - if (minFaults > 0) { - pw.print(" "); - pw.print(minFaults); - pw.print(" minor"); - } - if (majFaults > 0) { - pw.print(" "); - pw.print(majFaults); - pw.print(" major"); - } - } - pw.println(); - } - - private String readFile(String file, char endChar) { - FileInputStream is = null; - try { - is = new FileInputStream(file); - int len = is.read(mBuffer); - is.close(); - - if (len > 0) { - int i; - for (i=0; i<len; i++) { - if (mBuffer[i] == endChar) { - break; - } - } - return new String(mBuffer, 0, i); - } - } catch (java.io.FileNotFoundException e) { - } catch (java.io.IOException e) { - } finally { - if (is != null) { - try { - is.close(); - } catch (java.io.IOException e) { - } - } - } - return null; - } - - private void getName(Stats st, String cmdlineFile) { - String newName = st.name; - if (st.name == null || st.name.equals("app_process") - || st.name.equals("<pre-initialized>")) { - String cmdName = readFile(cmdlineFile, '\0'); - if (cmdName != null && cmdName.length() > 1) { - newName = cmdName; - int i = newName.lastIndexOf("/"); - if (i > 0 && i < newName.length()-1) { - newName = newName.substring(i+1); - } - } - if (newName == null) { - newName = st.baseName; - } - } - if (st.name == null || !newName.equals(st.name)) { - st.name = newName; - st.nameWidth = onMeasureProcessName(st.name); - } - } -} diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index fd93bcf..f546cf1 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -18,10 +18,10 @@ package com.android.server.am; import com.android.internal.R; import com.android.internal.os.BatteryStatsImpl; +import com.android.internal.os.ProcessStats; import com.android.server.AttributeCache; import com.android.server.IntentResolver; import com.android.server.ProcessMap; -import com.android.server.ProcessStats; import com.android.server.SystemServer; import com.android.server.Watchdog; import com.android.server.am.ActivityStack.ActivityState; |