blob: 59ffe03b842f6de71ffc1fe02c9428060abe7814 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborn45ce8642011-07-14 16:10:16 -070017package com.android.systemui;
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.app.Service;
20import android.content.Context;
21import android.content.Intent;
22import android.graphics.Canvas;
23import android.graphics.Paint;
24import android.graphics.PixelFormat;
25import android.os.Handler;
26import android.os.IBinder;
27import android.os.Message;
28import android.view.Gravity;
29import android.view.View;
30import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Dianne Hackbornd2932242013-08-05 18:18:42 -070032import com.android.internal.os.ProcessCpuTracker;
John Spurlockde84f0e2013-06-12 12:41:00 -040033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034public class LoadAverageService extends Service {
35 private View mView;
John Spurlock209bede2013-07-17 12:23:27 -040036
Dianne Hackbornd2932242013-08-05 18:18:42 -070037 private static final class CpuTracker extends ProcessCpuTracker {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 String mLoadText;
39 int mLoadWidth;
John Spurlock209bede2013-07-17 12:23:27 -040040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 private final Paint mPaint;
John Spurlock209bede2013-07-17 12:23:27 -040042
Dianne Hackbornd2932242013-08-05 18:18:42 -070043 CpuTracker(Paint paint) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 super(false);
45 mPaint = paint;
46 }
John Spurlock209bede2013-07-17 12:23:27 -040047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 @Override
49 public void onLoadChanged(float load1, float load5, float load15) {
50 mLoadText = load1 + " / " + load5 + " / " + load15;
51 mLoadWidth = (int)mPaint.measureText(mLoadText);
52 }
53
54 @Override
55 public int onMeasureProcessName(String name) {
56 return (int)mPaint.measureText(name);
57 }
58 }
John Spurlock209bede2013-07-17 12:23:27 -040059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 private class LoadView extends View {
61 private Handler mHandler = new Handler() {
62 @Override
63 public void handleMessage(Message msg) {
64 if (msg.what == 1) {
65 mStats.update();
66 updateDisplay();
67 Message m = obtainMessage(1);
68 sendMessageDelayed(m, 2000);
69 }
70 }
71 };
72
Dianne Hackbornd2932242013-08-05 18:18:42 -070073 private final CpuTracker mStats;
John Spurlock209bede2013-07-17 12:23:27 -040074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 private Paint mLoadPaint;
76 private Paint mAddedPaint;
77 private Paint mRemovedPaint;
78 private Paint mShadowPaint;
79 private Paint mShadow2Paint;
80 private Paint mIrqPaint;
81 private Paint mSystemPaint;
82 private Paint mUserPaint;
83 private float mAscent;
84 private int mFH;
85
86 private int mNeededWidth;
87 private int mNeededHeight;
88
89 LoadView(Context c) {
90 super(c);
91
92 setPadding(4, 4, 4, 4);
93 //setBackgroundResource(com.android.internal.R.drawable.load_average_background);
94
Dianne Hackbornce86ba82011-07-13 19:33:41 -070095 // Need to scale text size by density... but we won't do it
96 // linearly, because with higher dps it is nice to squeeze the
97 // text a bit to fit more of it. And with lower dps, trying to
98 // go much smaller will result in unreadable text.
99 int textSize = 10;
100 float density = c.getResources().getDisplayMetrics().density;
101 if (density < 1) {
102 textSize = 9;
103 } else {
104 textSize = (int)(10*density);
105 if (textSize < 10) {
106 textSize = 10;
107 }
108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 mLoadPaint = new Paint();
110 mLoadPaint.setAntiAlias(true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700111 mLoadPaint.setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 mLoadPaint.setARGB(255, 255, 255, 255);
113
114 mAddedPaint = new Paint();
115 mAddedPaint.setAntiAlias(true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700116 mAddedPaint.setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 mAddedPaint.setARGB(255, 128, 255, 128);
118
119 mRemovedPaint = new Paint();
120 mRemovedPaint.setAntiAlias(true);
121 mRemovedPaint.setStrikeThruText(true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700122 mRemovedPaint.setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 mRemovedPaint.setARGB(255, 255, 128, 128);
124
125 mShadowPaint = new Paint();
126 mShadowPaint.setAntiAlias(true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700127 mShadowPaint.setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 //mShadowPaint.setFakeBoldText(true);
129 mShadowPaint.setARGB(192, 0, 0, 0);
130 mLoadPaint.setShadowLayer(4, 0, 0, 0xff000000);
131
132 mShadow2Paint = new Paint();
133 mShadow2Paint.setAntiAlias(true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700134 mShadow2Paint.setTextSize(textSize);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 //mShadow2Paint.setFakeBoldText(true);
136 mShadow2Paint.setARGB(192, 0, 0, 0);
137 mLoadPaint.setShadowLayer(2, 0, 0, 0xff000000);
138
139 mIrqPaint = new Paint();
140 mIrqPaint.setARGB(0x80, 0, 0, 0xff);
141 mIrqPaint.setShadowLayer(2, 0, 0, 0xff000000);
142 mSystemPaint = new Paint();
143 mSystemPaint.setARGB(0x80, 0xff, 0, 0);
144 mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000);
145 mUserPaint = new Paint();
146 mUserPaint.setARGB(0x80, 0, 0xff, 0);
147 mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000);
148
149 mAscent = mLoadPaint.ascent();
150 float descent = mLoadPaint.descent();
151 mFH = (int)(descent - mAscent + .5f);
152
Dianne Hackbornd2932242013-08-05 18:18:42 -0700153 mStats = new CpuTracker(mLoadPaint);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 mStats.init();
155 updateDisplay();
156 }
157
158 @Override
159 protected void onAttachedToWindow() {
160 super.onAttachedToWindow();
161 mHandler.sendEmptyMessage(1);
162 }
163
164 @Override
165 protected void onDetachedFromWindow() {
166 super.onDetachedFromWindow();
167 mHandler.removeMessages(1);
168 }
169
170 @Override
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700171 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
172 setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
173 resolveSize(mNeededHeight, heightMeasureSpec));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 }
175
176 @Override
177 public void onDraw(Canvas canvas) {
178 super.onDraw(canvas);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700179 final int W = mNeededWidth;
180 final int RIGHT = getWidth()-1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181
Dianne Hackbornd2932242013-08-05 18:18:42 -0700182 final CpuTracker stats = mStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 final int userTime = stats.getLastUserTime();
184 final int systemTime = stats.getLastSystemTime();
185 final int iowaitTime = stats.getLastIoWaitTime();
186 final int irqTime = stats.getLastIrqTime();
187 final int softIrqTime = stats.getLastSoftIrqTime();
188 final int idleTime = stats.getLastIdleTime();
John Spurlock209bede2013-07-17 12:23:27 -0400189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 final int totalTime = userTime+systemTime+iowaitTime+irqTime+softIrqTime+idleTime;
191 if (totalTime == 0) {
192 return;
193 }
194 int userW = (userTime*W)/totalTime;
195 int systemW = (systemTime*W)/totalTime;
196 int irqW = ((iowaitTime+irqTime+softIrqTime)*W)/totalTime;
197
John Spurlock01534782014-01-13 11:59:22 -0500198 int paddingRight = getPaddingRight();
199 int x = RIGHT - paddingRight;
200 int top = getPaddingTop() + 2;
201 int bottom = getPaddingTop() + mFH - 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
203 if (irqW > 0) {
204 canvas.drawRect(x-irqW, top, x, bottom, mIrqPaint);
205 x -= irqW;
206 }
207 if (systemW > 0) {
208 canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
209 x -= systemW;
210 }
211 if (userW > 0) {
212 canvas.drawRect(x-userW, top, x, bottom, mUserPaint);
213 x -= userW;
214 }
215
John Spurlock01534782014-01-13 11:59:22 -0500216 int y = getPaddingTop() - (int)mAscent;
217 canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth-1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 y-1, mShadowPaint);
John Spurlock01534782014-01-13 11:59:22 -0500219 canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth-1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 y+1, mShadowPaint);
John Spurlock01534782014-01-13 11:59:22 -0500221 canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth+1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 y-1, mShadow2Paint);
John Spurlock01534782014-01-13 11:59:22 -0500223 canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth+1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 y+1, mShadow2Paint);
John Spurlock01534782014-01-13 11:59:22 -0500225 canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 y, mLoadPaint);
227
228 int N = stats.countWorkingStats();
229 for (int i=0; i<N; i++) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700230 CpuTracker.Stats st = stats.getWorkingStats(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 y += mFH;
232 top += mFH;
233 bottom += mFH;
234
235 userW = (st.rel_utime*W)/totalTime;
236 systemW = (st.rel_stime*W)/totalTime;
John Spurlock01534782014-01-13 11:59:22 -0500237 x = RIGHT - paddingRight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 if (systemW > 0) {
239 canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
240 x -= systemW;
241 }
242 if (userW > 0) {
243 canvas.drawRect(x-userW, top, x, bottom, mUserPaint);
244 x -= userW;
245 }
246
John Spurlock01534782014-01-13 11:59:22 -0500247 canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth-1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 y-1, mShadowPaint);
John Spurlock01534782014-01-13 11:59:22 -0500249 canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth-1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 y+1, mShadowPaint);
John Spurlock01534782014-01-13 11:59:22 -0500251 canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth+1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 y-1, mShadow2Paint);
John Spurlock01534782014-01-13 11:59:22 -0500253 canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth+1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 y+1, mShadow2Paint);
255 Paint p = mLoadPaint;
256 if (st.added) p = mAddedPaint;
257 if (st.removed) p = mRemovedPaint;
John Spurlock01534782014-01-13 11:59:22 -0500258 canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth, y, p);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 }
260 }
261
262 void updateDisplay() {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700263 final CpuTracker stats = mStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 final int NW = stats.countWorkingStats();
265
266 int maxWidth = stats.mLoadWidth;
267 for (int i=0; i<NW; i++) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700268 CpuTracker.Stats st = stats.getWorkingStats(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 if (st.nameWidth > maxWidth) {
270 maxWidth = st.nameWidth;
271 }
272 }
John Spurlock209bede2013-07-17 12:23:27 -0400273
John Spurlock01534782014-01-13 11:59:22 -0500274 int neededWidth = getPaddingLeft() + getPaddingRight() + maxWidth;
275 int neededHeight = getPaddingTop() + getPaddingBottom() + (mFH*(1+NW));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
277 mNeededWidth = neededWidth;
278 mNeededHeight = neededHeight;
279 requestLayout();
280 } else {
281 invalidate();
282 }
283 }
284 }
285
286 @Override
287 public void onCreate() {
288 super.onCreate();
289 mView = new LoadView(this);
290 WindowManager.LayoutParams params = new WindowManager.LayoutParams(
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700291 WindowManager.LayoutParams.MATCH_PARENT,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 WindowManager.LayoutParams.WRAP_CONTENT,
Jeff Brown3b2b3542010-10-15 00:54:27 -0700293 WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
295 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
296 PixelFormat.TRANSLUCENT);
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700297 params.gravity = Gravity.END | Gravity.TOP;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 params.setTitle("Load Average");
Dianne Hackborn2ed99462011-07-01 19:02:52 -0700299 WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 wm.addView(mView, params);
301 }
302
303 @Override
304 public void onDestroy() {
305 super.onDestroy();
Dianne Hackborn2ed99462011-07-01 19:02:52 -0700306 ((WindowManager)getSystemService(WINDOW_SERVICE)).removeView(mView);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 mView = null;
308 }
309
310 @Override
311 public IBinder onBind(Intent intent) {
312 return null;
313 }
314
315}