From 8fdb357fb1d416be314e5bb9312f97ce932fdeef Mon Sep 17 00:00:00 2001 From: hzhuangqingbin Date: Wed, 11 Sep 2013 15:51:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=80=A7=E8=83=BD=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=94=B6=E9=9B=86=E6=8E=A5=E5=8F=A3=E5=92=8Cant?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=89=93=E5=8C=85=E6=96=87=E4=BB=B6build.xml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 23 +- build.xml | 47 +++ gen/com/netease/qa/emmagee/R.java | 153 ++++---- .../netease/emmagee/performance/CpuInfo.java | 214 ++++++++++ .../emmagee/performance/MemoryInfo.java | 129 ++++++ .../performance/PerformanceMonitor.java | 369 ++++++++++++++++++ .../emmagee/performance/TrafficInfo.java | 78 ++++ src/com/netease/qa/emmagee/utils/CpuInfo.java | 54 ++- .../netease/qa/emmagee/utils/TrafficInfo.java | 48 +++ 9 files changed, 1030 insertions(+), 85 deletions(-) create mode 100644 build.xml create mode 100644 src/com/netease/emmagee/performance/CpuInfo.java create mode 100644 src/com/netease/emmagee/performance/MemoryInfo.java create mode 100644 src/com/netease/emmagee/performance/PerformanceMonitor.java create mode 100644 src/com/netease/emmagee/performance/TrafficInfo.java diff --git a/.classpath b/.classpath index 9e9d573..7f22a14 100644 --- a/.classpath +++ b/.classpath @@ -1,11 +1,12 @@ - - - - - - - - - - - + + + + + + + + + + + + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..c6539eb --- /dev/null +++ b/build.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gen/com/netease/qa/emmagee/R.java b/gen/com/netease/qa/emmagee/R.java index c006e99..fdfaad5 100644 --- a/gen/com/netease/qa/emmagee/R.java +++ b/gen/com/netease/qa/emmagee/R.java @@ -1,72 +1,81 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.netease.qa.emmagee; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static final int button_bg=0x7f020000; - public static final int close=0x7f020001; - public static final int ic_launcher=0x7f020002; - public static final int icon=0x7f020003; - public static final int meminfo=0x7f020004; - } - public static final class id { - public static final int Lin=0x7f050004; - public static final int b=0x7f050001; - public static final int cpu1=0x7f050013; - public static final int cpu2=0x7f050014; - public static final int cpu_info=0x7f050000; - public static final int floating=0x7f050011; - public static final int floating_Window=0x7f050010; - public static final int image=0x7f05000a; - public static final int img1=0x7f050002; - public static final int img2=0x7f050003; - public static final int memoryinfo=0x7f05000e; - public static final int memtotal=0x7f050006; - public static final int memunused=0x7f050005; - public static final int processList=0x7f05000c; - public static final int rb=0x7f050009; - public static final int save=0x7f050012; - public static final int test=0x7f05000d; - public static final int text=0x7f05000b; - public static final int time=0x7f05000f; - public static final int traffic=0x7f050007; - public static final int wifi=0x7f050008; - } - public static final class layout { - public static final int cpu=0x7f030000; - public static final int floating=0x7f030001; - public static final int list_item=0x7f030002; - public static final int mainpage=0x7f030003; - public static final int memory=0x7f030004; - public static final int settings=0x7f030005; - public static final int systemstat=0x7f030006; - } - public static final class string { - public static final int app_name=0x7f040001; - public static final int app_name1=0x7f040002; - public static final int app_name2=0x7f040003; - public static final int app_name3=0x7f040004; - public static final int app_name4=0x7f040005; - public static final int bg=0x7f040009; - public static final int closewifi=0x7f040011; - public static final int collect=0x7f04000c; - public static final int cpu=0x7f040008; - public static final int hello=0x7f040000; - public static final int memoryinfo=0x7f04000b; - public static final int ok=0x7f04000f; - public static final int openwifi=0x7f040010; - public static final int seconds=0x7f04000d; - public static final int start=0x7f040007; - public static final int system=0x7f040006; - public static final int testmemory=0x7f04000a; - public static final int window=0x7f04000e; - } -} +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.netease.qa.emmagee; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int button_bg=0x7f020000; + public static final int close=0x7f020001; + public static final int ic_launcher=0x7f020002; + public static final int icon=0x7f020003; + public static final int meminfo=0x7f020004; + } + public static final class id { + public static final int Lin=0x7f050004; + public static final int b=0x7f050001; + public static final int batt=0x7f050007; + public static final int cpu1=0x7f050018; + public static final int cpu2=0x7f050019; + public static final int cpu_info=0x7f050000; + public static final int floating=0x7f050016; + public static final int floating_Window=0x7f050015; + public static final int image=0x7f05000b; + public static final int img1=0x7f050002; + public static final int img2=0x7f050003; + public static final int memoryinfo=0x7f05000f; + public static final int memtotal=0x7f050006; + public static final int memunused=0x7f050005; + public static final int password=0x7f050012; + public static final int processList=0x7f05000d; + public static final int rb=0x7f05000a; + public static final int recipients=0x7f050014; + public static final int save=0x7f050017; + public static final int sender=0x7f050011; + public static final int smtp=0x7f050013; + public static final int test=0x7f05000e; + public static final int text=0x7f05000c; + public static final int time=0x7f050010; + public static final int traffic=0x7f050008; + public static final int wifi=0x7f050009; + } + public static final class layout { + public static final int cpu=0x7f030000; + public static final int floating=0x7f030001; + public static final int list_item=0x7f030002; + public static final int mainpage=0x7f030003; + public static final int memory=0x7f030004; + public static final int settings=0x7f030005; + public static final int systemstat=0x7f030006; + } + public static final class string { + public static final int app_name=0x7f040001; + public static final int app_name1=0x7f040002; + public static final int app_name2=0x7f040003; + public static final int app_name3=0x7f040004; + public static final int app_name4=0x7f040005; + public static final int bg=0x7f040009; + public static final int closewifi=0x7f040015; + public static final int collect=0x7f04000c; + public static final int cpu=0x7f040008; + public static final int hello=0x7f040000; + public static final int memoryinfo=0x7f04000b; + public static final int ok=0x7f040013; + public static final int openwifi=0x7f040014; + public static final int password=0x7f04000f; + public static final int receiver=0x7f04000d; + public static final int seconds=0x7f040011; + public static final int sender=0x7f04000e; + public static final int smtp=0x7f040010; + public static final int start=0x7f040007; + public static final int system=0x7f040006; + public static final int testmemory=0x7f04000a; + public static final int window=0x7f040012; + } +} diff --git a/src/com/netease/emmagee/performance/CpuInfo.java b/src/com/netease/emmagee/performance/CpuInfo.java new file mode 100644 index 0000000..0721b1a --- /dev/null +++ b/src/com/netease/emmagee/performance/CpuInfo.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2012-2013 NetEase, Inc. and other contributors + * + * 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.netease.emmagee.performance; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; + +import android.content.Context; +import android.os.Build; +import android.util.Log; + +/** + * operate CPU information + * @author hz_liuxiao + */ +public class CpuInfo { + + private static final String LOG_TAG = "Emmagee-" + + CpuInfo.class.getSimpleName(); + + private Context context; + private long processCpu; + private long idleCpu; + private long totalCpu; + private boolean isInitialStatics = true; + private SimpleDateFormat formatterFile; + private MemoryInfo mi; + private long totalMemorySize; + private long initialTraffic; + private long lastestTraffic; + private long traffic; + private TrafficInfo trafficInfo; + private ArrayList cpuUsedRatio; + private long totalCpu2; + private long processCpu2; + private long idleCpu2; + private String processCpuRatio = ""; + private String totalCpuRatio = ""; + + // public CpuInfo(Context context, int pid, String uid) { + // this.pid = pid; + // this.context = context; + // trafficInfo = new NetworkInfo(uid); + // formatterFile = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // mi = new MemoryInfo(); + // totalMemorySize = mi.getTotalMemory(); + // cpuUsedRatio = new ArrayList(); + // } + + /** + * read the status of CPU. 0:processCpu 1:idleCpu 2:totalCpu + * + * @throws FileNotFoundException + */ + public long[] readCpuStat(int pid) { + String processPid = Integer.toString(pid); + String cpuStatPath = "/proc/" + processPid + "/stat"; + try { + // monitor cpu stat of certain process + RandomAccessFile processCpuInfo = new RandomAccessFile(cpuStatPath, + "r"); + String line = ""; + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.setLength(0); + while ((line = processCpuInfo.readLine()) != null) { + stringBuffer.append(line + "\n"); + } + String[] tok = stringBuffer.toString().split(" "); + processCpu = Long.parseLong(tok[13]) + Long.parseLong(tok[14]); + processCpuInfo.close(); + } catch (FileNotFoundException e) { + Log.e(LOG_TAG, "FileNotFoundException: " + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + // monitor total and idle cpu stat of certain process + RandomAccessFile cpuInfo = new RandomAccessFile("/proc/stat", "r"); + String[] toks = cpuInfo.readLine().split("\\s+"); + idleCpu = Long.parseLong(toks[4]); + totalCpu = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + + Long.parseLong(toks[3]) + Long.parseLong(toks[4]) + + Long.parseLong(toks[6]) + Long.parseLong(toks[5]) + + Long.parseLong(toks[7]); + cpuInfo.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return new long[] { processCpu, idleCpu, totalCpu }; + } + + /** + * get CPU name. + * + * @return CPU name + */ + public String getCpuName() { + try { + RandomAccessFile cpuStat = new RandomAccessFile("/proc/cpuinfo", + "r"); + String[] cpu = cpuStat.readLine().split(":"); // cpu信息的前一段是含有processor字符串,此处替换为不显示 + cpuStat.close(); + return cpu[1]; + } catch (IOException e) { + Log.e(LOG_TAG, "IOException: " + e.getMessage()); + } + return ""; + } + + // /** + // * reserve used ratio of process CPU and total CPU, meanwhile collect + // * network traffic. + // * + // * @return network traffic ,used ratio of process CPU and total CPU in + // * certain interval + // */ + // public ArrayList getCpuRatioInfo(String currentBatt, String temp, + // String voltage) { + // + // DecimalFormat fomart = new DecimalFormat(); + // fomart.setMaximumFractionDigits(2); + // fomart.setMinimumFractionDigits(2); + // + // readCpuStat(); + // cpuUsedRatio.clear(); + // + // try { + // String mDateTime2; + // Calendar cal = Calendar.getInstance(); + // if ((Build.MODEL.equals("sdk")) + // || (Build.MODEL.equals("google_sdk"))) { + // mDateTime2 = formatterFile.format(cal.getTime().getTime() + 8 + // * 60 * 60 * 1000); + // } else + // mDateTime2 = formatterFile.format(cal.getTime().getTime()); + // + // if (isInitialStatics) { + // initialTraffic = trafficInfo.getTrafficInfo(); + // isInitialStatics = false; + // } else { + // lastestTraffic = trafficInfo.getTrafficInfo(); + // if (initialTraffic == -1) + // traffic = -1; + // else + // traffic = (lastestTraffic - initialTraffic + 1023) / 1024; + // processCpuRatio = fomart + // .format(100 * ((double) (processCpu - processCpu2) / ((double) (totalCpu + // - totalCpu2)))); + // totalCpuRatio = fomart + // .format(100 * ((double) ((totalCpu - idleCpu) - (totalCpu2 - idleCpu2)) / + // (double) (totalCpu - totalCpu2))); + // long pidMemory = mi.getPidMemorySize(pid, context); + // String pMemory = fomart.format((double) pidMemory / 1024); + // long freeMemory = mi.getFreeMemorySize(context); + // String fMemory = fomart.format((double) freeMemory / 1024); + // String percent = "统计出错"; + // if (totalMemorySize != 0) { + // percent = fomart + // .format(((double) pidMemory / (double) totalMemorySize) * 100); + // } + // + // // whether certain device supports traffic statics or not + // if (traffic == -1) { + // EmmageeService.bw.write(mDateTime2 + "," + pMemory + "," + // + percent + "," + fMemory + "," + processCpuRatio + // + "," + totalCpuRatio + "," + "本程序或本设备不支持流量统计" + // + "," + currentBatt + "," + temp + "," + voltage + // + "\r\n"); + // } else { + // EmmageeService.bw + // .write(mDateTime2 + "," + pMemory + "," + percent + // + "," + fMemory + "," + processCpuRatio + // + "," + totalCpuRatio + "," + traffic + "," + // + currentBatt + "," + temp + "," + voltage + // + "\r\n"); + // } + // } + // totalCpu2 = totalCpu; + // processCpu2 = processCpu; + // idleCpu2 = idleCpu; + // cpuUsedRatio.add(processCpuRatio); + // cpuUsedRatio.add(totalCpuRatio); + // cpuUsedRatio.add(String.valueOf(traffic)); + // } catch (IOException e) { + // e.printStackTrace(); + // // PttService.closeOpenedStream() + // } + // return cpuUsedRatio; + // + // } +} diff --git a/src/com/netease/emmagee/performance/MemoryInfo.java b/src/com/netease/emmagee/performance/MemoryInfo.java new file mode 100644 index 0000000..a493fb5 --- /dev/null +++ b/src/com/netease/emmagee/performance/MemoryInfo.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012-2013 NetEase, Inc. and other contributors + * + * 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.netease.emmagee.performance; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import android.app.ActivityManager; +import android.content.Context; +import android.os.Debug; +import android.util.Log; + +/** + * operate memory information + * @author hz_liuxiao + */ +public class MemoryInfo { + + private static final String LOG_TAG = "Grape-" + + MemoryInfo.class.getSimpleName(); + +// private int pid; +// private Context context; +// +// public void MemoryInfo(int pid , Context context){ +// this.pid = pid; +// this.context = context; +// } + /** + * get total memory of certain device. + * + * @return total memory of device + */ + public long getTotalMemory() { + String memInfoPath = "/proc/meminfo"; + String readTemp = ""; + String memTotal = ""; + long memory = 0; + try { + FileReader fr = new FileReader(memInfoPath); + BufferedReader localBufferedReader = new BufferedReader(fr, 8192); + while ((readTemp = localBufferedReader.readLine()) != null) { + if (readTemp.contains("MemTotal")) { + String[] total = readTemp.split(":"); + memTotal = total[1].trim(); + } + } + localBufferedReader.close(); + String[] memKb = memTotal.split(" "); + memTotal = memKb[0].trim(); + Log.d(LOG_TAG, "memTotal: " + memTotal); + memory = Long.parseLong(memTotal); + } catch (IOException e) { + Log.e(LOG_TAG, "IOException: " + e.getMessage()); + } + return memory; + } + + /** + * get free memory. + * + * @return free memory of device + * + */ + public long getFreeMemorySize(Context context) { + ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); + ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + am.getMemoryInfo(outInfo); + long avaliMem = outInfo.availMem; + return avaliMem / 1024; + } + + /** + * get the memory of process with certain pid. + * + * @param pid + * pid of process + * @param context + * context of certain activity + * @return memory usage of certain process + */ + public int getPidMemorySize(int pid, Context context) { + ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + int[] myMempid = new int[] { pid }; + Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(myMempid); + memoryInfo[0].getTotalSharedDirty(); + + // int memSize = memoryInfo[0].dalvikPrivateDirty; + // TODO PSS + int memSize = memoryInfo[0].getTotalPss(); + // int memSize = memoryInfo[0].getTotalPrivateDirty(); + return memSize; + } + + /** + * get the sdk version of phone. + * + * @return sdk version + */ + public String getSDKVersion() { + return android.os.Build.VERSION.RELEASE; + } + + /** + * get phone type. + * + * @return phone type + */ + public String getPhoneType() { + return android.os.Build.MODEL; + } +} diff --git a/src/com/netease/emmagee/performance/PerformanceMonitor.java b/src/com/netease/emmagee/performance/PerformanceMonitor.java new file mode 100644 index 0000000..bc4efcf --- /dev/null +++ b/src/com/netease/emmagee/performance/PerformanceMonitor.java @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2012-2013 NetEase, Inc. and other contributors + * + * 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.netease.emmagee.performance; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.List; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.BatteryManager; +import android.os.Build; +import android.os.Handler; +import android.util.Log; + +/** + * Service running in background + * @author hz_liuxiao + */ +public class PerformanceMonitor { + + private final static String LOG_TAG = "Emmagee-" + + PerformanceMonitor.class.getSimpleName(); + + private int delaytime = 1000; + private Handler handler = new Handler(); + + public BufferedWriter bw; + public FileOutputStream out; + public OutputStreamWriter osw; + public String resultFilePath; + + private int pid, uid; + private CpuInfo cpuInfo; + private MemoryInfo memoryInfo; + private TrafficInfo networkInfo; + private SimpleDateFormat formatterTime; + private DecimalFormat fomart; + private boolean isInitialStatic = true; + private long processCpu1, processCpu2, totalCpu1, totalCpu2, idleCpu1, + idleCpu2; + private long startTraff, endTraff, intervalTraff; + private String currentBatt, temperature, voltage; + private boolean isRunnableStop = false; + private BatteryInfoBroadcastReceiver receiver; + private Context context; + + private String toolName; + // private OrangeSolo orange; + + public PerformanceMonitor(Context context, String packageName, String toolName, + String mDateTime) { + this.context = context; + + fomart = new DecimalFormat(); + fomart.setMaximumFractionDigits(2); + fomart.setMinimumFractionDigits(2); + // 注册广播监听电量 + receiver = new BatteryInfoBroadcastReceiver(); + IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + context.registerReceiver(receiver, filter); + + // formatterTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // ObjectSerializable serializable = (ObjectSerializable) + // intent.getSerializableExtra("orange"); + // orange = serializable.getOrange(); + getAppInfo(packageName); + // 不在初始化的时候创建报告,而是在真正做记录的时候创建 +// creatReport(toolName, mDateTime); + this.toolName = toolName; + cpuInfo = new CpuInfo(); + memoryInfo = new MemoryInfo(); + networkInfo = new TrafficInfo(); + } + + /** + * get pid and uid + * + * @param packageName + */ + private void getAppInfo(String packageName) { + ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + List run = am.getRunningAppProcesses(); + // PackageManager pm = context.getPackageManager(); + for (RunningAppProcessInfo runningProcess : run) { + if (packageName.equals(runningProcess.processName)) { + uid = runningProcess.uid; + pid = runningProcess.pid; + Log.d(LOG_TAG, "pid = " + pid); + Log.d(LOG_TAG, "uid = " + uid); + break; + } + } + } + + /** + * write the test result to csv format report. + */ + private void creatReport(String toolName, String dateTime) { + Log.d(LOG_TAG, "start write report"); +// Calendar cal = Calendar.getInstance(); +// SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); +// String mDateTime; +// if ((Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk"))) +// mDateTime = formatter.format(cal.getTime().getTime() + 8 * 60 * 60 +// * 1000); +// else +// mDateTime = formatter.format(cal.getTime().getTime()); + + String dir = ""; + if (android.os.Environment.getExternalStorageState().equals( + android.os.Environment.MEDIA_MOUNTED)) { + dir = android.os.Environment + .getExternalStorageDirectory() + + File.separator + + toolName; + + } else { + dir = context.getFilesDir().getPath() + File.separator + toolName; + } +// resultFilePath = dir + File.separator + toolName + "-" + mDateTime + ".csv"; + resultFilePath = dir + File.separator + toolName + "-" + Build.VERSION.SDK_INT + "-" + + Build.MODEL.replace(" ", "-") + "-PerformanceMonitor" + ".csv"; + try { + // 创建目录 + File fileDir = new File(dir); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + // 创建文件 + File resultFile = new File(resultFilePath); + // 只有在性能结果文件不存在的情况下才创建文件,并生成头文件,让文件只保持一份就好 + if (!resultFile.exists()) { + resultFile.createNewFile(); + out = new FileOutputStream(resultFile, true); // 在文件内容后继续加内容 + osw = new OutputStreamWriter(out, "GBK"); + bw = new BufferedWriter(osw); + // 生成头文件 + bw.write("测试用例信息" + "," + "时间" + "," + "应用占用内存PSS(MB)" + "," + "应用占用内存比(%)" + "," + + " 机器剩余内存(MB)" + "," + "应用占用CPU率(%)" + "," + "CPU总使用率(%)" + + "," + "流量(KB)" + "," + "当前电量" + "," + "电池温度(C)" + "," + + "电压(V)" + "\r\n"); + bw.flush(); + } else { + out = new FileOutputStream(resultFile, true); // 在文件内容后继续加内容 + osw = new OutputStreamWriter(out, "GBK"); + bw = new BufferedWriter(osw); + } + } catch (IOException e) { + Log.e(LOG_TAG, e.getMessage()); + } + + Log.d(LOG_TAG, "end write report"); + } + + /** + * write data into certain file + */ + public void writePerformanceData(String mDateTime) { + if (isInitialStatic) { + // 创建相应的性能数据报告 + creatReport(toolName, mDateTime); + startTraff = networkInfo.getTrafficInfo(uid); + isInitialStatic = false; + } + + // Network + endTraff = networkInfo.getTrafficInfo(uid); + if (startTraff == -1) + intervalTraff = -1; + else + intervalTraff = (endTraff - startTraff + 1023) / 1024; + + // CPU + processCpu1 = cpuInfo.readCpuStat(pid)[0]; + idleCpu1 = cpuInfo.readCpuStat(pid)[1]; + totalCpu1 = cpuInfo.readCpuStat(pid)[2]; + String processCpuRatio = fomart + .format(100 * ((double) (processCpu1 - processCpu2) / ((double) (totalCpu1 - totalCpu2)))); + String totalCpuRatio = fomart + .format(100 * ((double) ((totalCpu1 - idleCpu1) - (totalCpu2 - idleCpu2)) / (double) (totalCpu1 - totalCpu2))); + + // Memory + long pidMemory = memoryInfo.getPidMemorySize(pid, context); + String pss = fomart.format((double) pidMemory / 1024); + long freeMemory = memoryInfo.getFreeMemorySize(context); + String freeMem = fomart.format((double) freeMemory / 1024); + long totalMemorySize = memoryInfo.getTotalMemory(); + String percent = "统计出错"; + if (totalMemorySize != 0) { + percent = fomart + .format(((double) pidMemory / (double) totalMemorySize) * 100); + } + + try { + if (intervalTraff == -1) { + bw.write(this.getTestCaseInfo() + "-" + this.getActionInfo() + "," + mDateTime + "," + pss + "," + percent + "," + + freeMem + "," + processCpuRatio + "," + + totalCpuRatio + "," + "本程序或本设备不支持流量统计" + "," + + currentBatt + "," + temperature + "," + voltage + + "\r\n"); + } else { + bw.write(this.getTestCaseInfo() + "-" + this.getActionInfo() + "," + mDateTime + "," + pss + "," + percent + "," + + freeMem + "," + processCpuRatio + "," + + totalCpuRatio + "," + intervalTraff + "," + + currentBatt + "," + temperature + "," + voltage + + "\r\n"); + } + bw.flush(); + Log.i(LOG_TAG, "*** writePerformanceData on " + mDateTime + " *** "); + } catch (Exception e) { + e.printStackTrace(); + } + + processCpu2 = processCpu1; + idleCpu2 = idleCpu1; + totalCpu2 = totalCpu1; + } + + private Runnable task = new Runnable() { + + public void run() { + if (!isRunnableStop) { + handler.postDelayed(this, delaytime); + // writePerformanceData(); + } + }; + }; + + /** + * 电量广播类 + * @author hz_liuxiao@corp.netease.com + * + */ + public class BatteryInfoBroadcastReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + + if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { + int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); + + int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + currentBatt = String.valueOf(level * 100 / scale) + "%"; + + voltage = String.valueOf(intent.getIntExtra( + BatteryManager.EXTRA_VOLTAGE, -1) * 1.0 / 1000); + + temperature = String.valueOf(intent.getIntExtra( + BatteryManager.EXTRA_TEMPERATURE, -1) * 1.0 / 10); + + int status = intent + .getIntExtra(BatteryManager.EXTRA_STATUS, -1); + } + + } + + } + + /** + * close all opened stream. + */ + public void closeOpenedStream() { + try { + if (bw != null) + bw.close(); + if (osw != null) + osw.close(); + if (out != null) + out.close(); + } catch (Exception e) { + Log.d(LOG_TAG, e.getMessage()); + } + } + + public void onDestroy() { + context.unregisterReceiver(receiver); + isRunnableStop = true; + closeOpenedStream(); + } + + /** + * 从栈中获取类名和测试方法名 + * + * @return 类名+测试方法名 + */ + private String getTestCaseInfo() { + String testCaseInfo = ""; + String testName, className; + StackTraceElement[] stack = (new Throwable()).getStackTrace(); + int i = 0; + while (i < stack.length) { + // 在setUp和testXXX中会有orange的操作方法 + if (stack[i].getMethodName().toString().startsWith("test") + ||stack[i].getMethodName().toString().startsWith("setUp")) { + break; + } + i ++; + } + + if (i >= stack.length) { + testCaseInfo = "No TestCase Info"; + } else { + // “.”在正则中代码任意字符,不能用来分割,如需使用则通过“//.”转义 + String[] packageName = stack[i].getClassName().toString().split("\\."); + className = packageName[packageName.length - 1]; +// className = stack[i].getClassName().toString(); + testName = stack[i].getMethodName().toString(); + testCaseInfo = className + "." + testName; + } +// Log.i(LOG_TAG, "*** getTestCaseInfo =" + testCaseInfo + " *** "); + return testCaseInfo; + } + + /** + * 从栈中获取相应操作方法名,有clickXXX,enterXXX,scrollXXX,typeXXX + * + * @return 类名+测试方法名 + */ + private String getActionInfo() { + String actionInfo = ""; + String testName, className; + StackTraceElement[] stack = (new Throwable()).getStackTrace(); + int i = 0; + while (i < stack.length) { + // 类对应的是OrangeSolo, + if (stack[i].getMethodName().toString().startsWith("click") + ||stack[i].getMethodName().toString().startsWith("enter") + ||stack[i].getMethodName().toString().startsWith("scroll") + ||stack[i].getMethodName().toString().startsWith("type")) { + break; + } + i ++; + } + + if (i >= stack.length) { + actionInfo = "No Action Info"; + } else { + //className暂时不用展现 + testName = stack[i].getMethodName().toString(); + actionInfo = testName; + } + return actionInfo; + } +} \ No newline at end of file diff --git a/src/com/netease/emmagee/performance/TrafficInfo.java b/src/com/netease/emmagee/performance/TrafficInfo.java new file mode 100644 index 0000000..229a8a4 --- /dev/null +++ b/src/com/netease/emmagee/performance/TrafficInfo.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012-2013 NetEase, Inc. and other contributors + * + * 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.netease.emmagee.performance; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import android.util.Log; + +/** + * information of network traffic + * @author hz_liuxiao + */ +public class TrafficInfo { + + private static final String LOG_TAG = "Grape-" + + TrafficInfo.class.getSimpleName(); + + /** + * get total network traffic, which is the sum of upload and download + * traffic. + * + * @return total traffic include received and send traffic + */ + public long getTrafficInfo(int uid) { + Log.i(LOG_TAG, "get traffic information"); + RandomAccessFile rafRcv = null, rafSnd = null; + String rcvPath = "/proc/uid_stat/" + uid + "/tcp_rcv"; + String sndPath = "/proc/uid_stat/" + uid + "/tcp_snd"; + long rcvTraffic = -1; + long sndTraffic = -1; + try { + rafRcv = new RandomAccessFile(rcvPath, "r"); + rafSnd = new RandomAccessFile(sndPath, "r"); + rcvTraffic = Long.parseLong(rafRcv.readLine()); + sndTraffic = Long.parseLong(rafSnd.readLine()); + } catch (FileNotFoundException e) { + rcvTraffic = -1; + sndTraffic = -1; + } catch (NumberFormatException e) { + Log.e(LOG_TAG, "NumberFormatException: " + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + Log.e(LOG_TAG, "IOException: " + e.getMessage()); + e.printStackTrace(); + } finally { + try { + if (rafRcv != null) { + rafRcv.close(); + } + if (rafSnd != null) + rafSnd.close(); + } catch (IOException e) { + Log.i(LOG_TAG, + "close randomAccessFile exception: " + e.getMessage()); + } + } + if (rcvTraffic == -1 || sndTraffic == -1) { + return -1; + } else + return rcvTraffic + sndTraffic; + } +} diff --git a/src/com/netease/qa/emmagee/utils/CpuInfo.java b/src/com/netease/qa/emmagee/utils/CpuInfo.java index f2019cd..a0ba5d1 100644 --- a/src/com/netease/qa/emmagee/utils/CpuInfo.java +++ b/src/com/netease/qa/emmagee/utils/CpuInfo.java @@ -24,12 +24,12 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import com.netease.qa.emmagee.service.EmmageeService; - import android.content.Context; import android.os.Build; import android.util.Log; +import com.netease.qa.emmagee.service.EmmageeService; + /** * operate CPU information * @@ -60,6 +60,10 @@ public class CpuInfo { private String totalCpuRatio = ""; private int pid; + public CpuInfo() { + + } + public CpuInfo(Context context, int pid, String uid) { this.pid = pid; this.context = context; @@ -115,6 +119,52 @@ public class CpuInfo { } } + /** + * read the status of CPU. 0:processCpu 1:idleCpu 2:totalCpu + * + * @throws FileNotFoundException + */ + public long[] readCpuStat(int pid) { + String processPid = Integer.toString(pid); + String cpuStatPath = "/proc/" + processPid + "/stat"; + try { + // monitor cpu stat of certain process + RandomAccessFile processCpuInfo = new RandomAccessFile(cpuStatPath, + "r"); + String line = ""; + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.setLength(0); + while ((line = processCpuInfo.readLine()) != null) { + stringBuffer.append(line + "\n"); + } + String[] tok = stringBuffer.toString().split(" "); + processCpu = Long.parseLong(tok[13]) + Long.parseLong(tok[14]); + processCpuInfo.close(); + } catch (FileNotFoundException e) { + Log.e(LOG_TAG, "FileNotFoundException: " + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + // monitor total and idle cpu stat of certain process + RandomAccessFile cpuInfo = new RandomAccessFile("/proc/stat", "r"); + String[] toks = cpuInfo.readLine().split("\\s+"); + idleCpu = Long.parseLong(toks[4]); + totalCpu = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + + Long.parseLong(toks[3]) + Long.parseLong(toks[4]) + + Long.parseLong(toks[6]) + Long.parseLong(toks[5]) + + Long.parseLong(toks[7]); + cpuInfo.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return new long[] { processCpu, idleCpu, totalCpu }; + } + /** * get CPU name. * diff --git a/src/com/netease/qa/emmagee/utils/TrafficInfo.java b/src/com/netease/qa/emmagee/utils/TrafficInfo.java index be692a7..3c2d6ec 100644 --- a/src/com/netease/qa/emmagee/utils/TrafficInfo.java +++ b/src/com/netease/qa/emmagee/utils/TrafficInfo.java @@ -38,6 +38,9 @@ public class TrafficInfo { this.uid = uid; } + public TrafficInfo() { + } + /** * get total network traffic, which is the sum of upload and download * traffic. @@ -82,4 +85,49 @@ public class TrafficInfo { } else return rcvTraffic + sndTraffic; } + + /** + * get total network traffic, which is the sum of upload and download + * traffic. + * + * @return total traffic include received and send traffic + */ + public long getTrafficInfo(int uid) { + Log.i(LOG_TAG, "get traffic information"); + RandomAccessFile rafRcv = null, rafSnd = null; + String rcvPath = "/proc/uid_stat/" + uid + "/tcp_rcv"; + String sndPath = "/proc/uid_stat/" + uid + "/tcp_snd"; + long rcvTraffic = -1; + long sndTraffic = -1; + try { + rafRcv = new RandomAccessFile(rcvPath, "r"); + rafSnd = new RandomAccessFile(sndPath, "r"); + rcvTraffic = Long.parseLong(rafRcv.readLine()); + sndTraffic = Long.parseLong(rafSnd.readLine()); + } catch (FileNotFoundException e) { + rcvTraffic = -1; + sndTraffic = -1; + } catch (NumberFormatException e) { + Log.e(LOG_TAG, "NumberFormatException: " + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + Log.e(LOG_TAG, "IOException: " + e.getMessage()); + e.printStackTrace(); + } finally { + try { + if (rafRcv != null) { + rafRcv.close(); + } + if (rafSnd != null) + rafSnd.close(); + } catch (IOException e) { + Log.i(LOG_TAG, + "close randomAccessFile exception: " + e.getMessage()); + } + } + if (rcvTraffic == -1 || sndTraffic == -1) { + return -1; + } else + return rcvTraffic + sndTraffic; + } } -- GitLab