/packages/SystemUI/src/com/android/systemui/LoadAverageService.java

https://github.com/aizuzi/platform_frameworks_base · Java · 314 lines · 250 code · 42 blank · 22 comment · 22 complexity · ebf07ff4ace5f058ea54b938864abbfd MD5 · raw file

  1. /*
  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. package com.android.systemui;
  17. import android.app.Service;
  18. import android.content.Context;
  19. import android.content.Intent;
  20. import android.graphics.Canvas;
  21. import android.graphics.Paint;
  22. import android.graphics.PixelFormat;
  23. import android.os.Handler;
  24. import android.os.IBinder;
  25. import android.os.Message;
  26. import android.view.Gravity;
  27. import android.view.View;
  28. import android.view.WindowManager;
  29. import com.android.internal.os.ProcessCpuTracker;
  30. public class LoadAverageService extends Service {
  31. private View mView;
  32. private static final class CpuTracker extends ProcessCpuTracker {
  33. String mLoadText;
  34. int mLoadWidth;
  35. private final Paint mPaint;
  36. CpuTracker(Paint paint) {
  37. super(false);
  38. mPaint = paint;
  39. }
  40. @Override
  41. public void onLoadChanged(float load1, float load5, float load15) {
  42. mLoadText = load1 + " / " + load5 + " / " + load15;
  43. mLoadWidth = (int)mPaint.measureText(mLoadText);
  44. }
  45. @Override
  46. public int onMeasureProcessName(String name) {
  47. return (int)mPaint.measureText(name);
  48. }
  49. }
  50. private class LoadView extends View {
  51. private Handler mHandler = new Handler() {
  52. @Override
  53. public void handleMessage(Message msg) {
  54. if (msg.what == 1) {
  55. mStats.update();
  56. updateDisplay();
  57. Message m = obtainMessage(1);
  58. sendMessageDelayed(m, 2000);
  59. }
  60. }
  61. };
  62. private final CpuTracker mStats;
  63. private Paint mLoadPaint;
  64. private Paint mAddedPaint;
  65. private Paint mRemovedPaint;
  66. private Paint mShadowPaint;
  67. private Paint mShadow2Paint;
  68. private Paint mIrqPaint;
  69. private Paint mSystemPaint;
  70. private Paint mUserPaint;
  71. private float mAscent;
  72. private int mFH;
  73. private int mNeededWidth;
  74. private int mNeededHeight;
  75. LoadView(Context c) {
  76. super(c);
  77. setPadding(4, 4, 4, 4);
  78. //setBackgroundResource(com.android.internal.R.drawable.load_average_background);
  79. // Need to scale text size by density... but we won't do it
  80. // linearly, because with higher dps it is nice to squeeze the
  81. // text a bit to fit more of it. And with lower dps, trying to
  82. // go much smaller will result in unreadable text.
  83. int textSize = 10;
  84. float density = c.getResources().getDisplayMetrics().density;
  85. if (density < 1) {
  86. textSize = 9;
  87. } else {
  88. textSize = (int)(10*density);
  89. if (textSize < 10) {
  90. textSize = 10;
  91. }
  92. }
  93. mLoadPaint = new Paint();
  94. mLoadPaint.setAntiAlias(true);
  95. mLoadPaint.setTextSize(textSize);
  96. mLoadPaint.setARGB(255, 255, 255, 255);
  97. mAddedPaint = new Paint();
  98. mAddedPaint.setAntiAlias(true);
  99. mAddedPaint.setTextSize(textSize);
  100. mAddedPaint.setARGB(255, 128, 255, 128);
  101. mRemovedPaint = new Paint();
  102. mRemovedPaint.setAntiAlias(true);
  103. mRemovedPaint.setStrikeThruText(true);
  104. mRemovedPaint.setTextSize(textSize);
  105. mRemovedPaint.setARGB(255, 255, 128, 128);
  106. mShadowPaint = new Paint();
  107. mShadowPaint.setAntiAlias(true);
  108. mShadowPaint.setTextSize(textSize);
  109. //mShadowPaint.setFakeBoldText(true);
  110. mShadowPaint.setARGB(192, 0, 0, 0);
  111. mLoadPaint.setShadowLayer(4, 0, 0, 0xff000000);
  112. mShadow2Paint = new Paint();
  113. mShadow2Paint.setAntiAlias(true);
  114. mShadow2Paint.setTextSize(textSize);
  115. //mShadow2Paint.setFakeBoldText(true);
  116. mShadow2Paint.setARGB(192, 0, 0, 0);
  117. mLoadPaint.setShadowLayer(2, 0, 0, 0xff000000);
  118. mIrqPaint = new Paint();
  119. mIrqPaint.setARGB(0x80, 0, 0, 0xff);
  120. mIrqPaint.setShadowLayer(2, 0, 0, 0xff000000);
  121. mSystemPaint = new Paint();
  122. mSystemPaint.setARGB(0x80, 0xff, 0, 0);
  123. mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000);
  124. mUserPaint = new Paint();
  125. mUserPaint.setARGB(0x80, 0, 0xff, 0);
  126. mSystemPaint.setShadowLayer(2, 0, 0, 0xff000000);
  127. mAscent = mLoadPaint.ascent();
  128. float descent = mLoadPaint.descent();
  129. mFH = (int)(descent - mAscent + .5f);
  130. mStats = new CpuTracker(mLoadPaint);
  131. mStats.init();
  132. updateDisplay();
  133. }
  134. @Override
  135. protected void onAttachedToWindow() {
  136. super.onAttachedToWindow();
  137. mHandler.sendEmptyMessage(1);
  138. }
  139. @Override
  140. protected void onDetachedFromWindow() {
  141. super.onDetachedFromWindow();
  142. mHandler.removeMessages(1);
  143. }
  144. @Override
  145. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  146. setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
  147. resolveSize(mNeededHeight, heightMeasureSpec));
  148. }
  149. @Override
  150. public void onDraw(Canvas canvas) {
  151. super.onDraw(canvas);
  152. final int W = mNeededWidth;
  153. final int RIGHT = getWidth()-1;
  154. final CpuTracker stats = mStats;
  155. final int userTime = stats.getLastUserTime();
  156. final int systemTime = stats.getLastSystemTime();
  157. final int iowaitTime = stats.getLastIoWaitTime();
  158. final int irqTime = stats.getLastIrqTime();
  159. final int softIrqTime = stats.getLastSoftIrqTime();
  160. final int idleTime = stats.getLastIdleTime();
  161. final int totalTime = userTime+systemTime+iowaitTime+irqTime+softIrqTime+idleTime;
  162. if (totalTime == 0) {
  163. return;
  164. }
  165. int userW = (userTime*W)/totalTime;
  166. int systemW = (systemTime*W)/totalTime;
  167. int irqW = ((iowaitTime+irqTime+softIrqTime)*W)/totalTime;
  168. int x = RIGHT - mPaddingRight;
  169. int top = mPaddingTop + 2;
  170. int bottom = mPaddingTop + mFH - 2;
  171. if (irqW > 0) {
  172. canvas.drawRect(x-irqW, top, x, bottom, mIrqPaint);
  173. x -= irqW;
  174. }
  175. if (systemW > 0) {
  176. canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
  177. x -= systemW;
  178. }
  179. if (userW > 0) {
  180. canvas.drawRect(x-userW, top, x, bottom, mUserPaint);
  181. x -= userW;
  182. }
  183. int y = mPaddingTop - (int)mAscent;
  184. canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
  185. y-1, mShadowPaint);
  186. canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
  187. y+1, mShadowPaint);
  188. canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
  189. y-1, mShadow2Paint);
  190. canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
  191. y+1, mShadow2Paint);
  192. canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth,
  193. y, mLoadPaint);
  194. int N = stats.countWorkingStats();
  195. for (int i=0; i<N; i++) {
  196. CpuTracker.Stats st = stats.getWorkingStats(i);
  197. y += mFH;
  198. top += mFH;
  199. bottom += mFH;
  200. userW = (st.rel_utime*W)/totalTime;
  201. systemW = (st.rel_stime*W)/totalTime;
  202. x = RIGHT - mPaddingRight;
  203. if (systemW > 0) {
  204. canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
  205. x -= systemW;
  206. }
  207. if (userW > 0) {
  208. canvas.drawRect(x-userW, top, x, bottom, mUserPaint);
  209. x -= userW;
  210. }
  211. canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
  212. y-1, mShadowPaint);
  213. canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
  214. y+1, mShadowPaint);
  215. canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
  216. y-1, mShadow2Paint);
  217. canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
  218. y+1, mShadow2Paint);
  219. Paint p = mLoadPaint;
  220. if (st.added) p = mAddedPaint;
  221. if (st.removed) p = mRemovedPaint;
  222. canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth, y, p);
  223. }
  224. }
  225. void updateDisplay() {
  226. final CpuTracker stats = mStats;
  227. final int NW = stats.countWorkingStats();
  228. int maxWidth = stats.mLoadWidth;
  229. for (int i=0; i<NW; i++) {
  230. CpuTracker.Stats st = stats.getWorkingStats(i);
  231. if (st.nameWidth > maxWidth) {
  232. maxWidth = st.nameWidth;
  233. }
  234. }
  235. int neededWidth = mPaddingLeft + mPaddingRight + maxWidth;
  236. int neededHeight = mPaddingTop + mPaddingBottom + (mFH*(1+NW));
  237. if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
  238. mNeededWidth = neededWidth;
  239. mNeededHeight = neededHeight;
  240. requestLayout();
  241. } else {
  242. invalidate();
  243. }
  244. }
  245. }
  246. @Override
  247. public void onCreate() {
  248. super.onCreate();
  249. mView = new LoadView(this);
  250. WindowManager.LayoutParams params = new WindowManager.LayoutParams(
  251. WindowManager.LayoutParams.MATCH_PARENT,
  252. WindowManager.LayoutParams.WRAP_CONTENT,
  253. WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
  254. WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
  255. WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
  256. PixelFormat.TRANSLUCENT);
  257. params.gravity = Gravity.END | Gravity.TOP;
  258. params.setTitle("Load Average");
  259. WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
  260. wm.addView(mView, params);
  261. }
  262. @Override
  263. public void onDestroy() {
  264. super.onDestroy();
  265. ((WindowManager)getSystemService(WINDOW_SERVICE)).removeView(mView);
  266. mView = null;
  267. }
  268. @Override
  269. public IBinder onBind(Intent intent) {
  270. return null;
  271. }
  272. }