1 /* 2 * Copyright (C) 2010 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 17 package vogar.android; 18 19 import java.io.File; 20 import java.io.FileOutputStream; 21 import java.io.OutputStream; 22 import java.lang.reflect.Constructor; 23 import java.lang.reflect.Method; 24 import vogar.target.Profiler; 25 26 public class AndroidProfiler extends Profiler { 27 // SamplingProfiler methods 28 private final Method newArrayThreadSet; 29 private final Method newThreadGroupThreadSet; 30 private final Constructor newThreadSet; 31 private final Method start; 32 private final Method stop; 33 private final Method shutdown; 34 private final Method write; 35 private final Method getHprofData; 36 AndroidProfiler()37 public AndroidProfiler() throws Exception { 38 String packageName = "dalvik.system.profiler"; 39 Class<?> ThreadSet = Class.forName(packageName + ".SamplingProfiler$ThreadSet"); 40 Class<?> SamplingProfiler = Class.forName(packageName + ".SamplingProfiler"); 41 Class<?> HprofData = Class.forName(packageName + ".HprofData"); 42 Class<?> Writer = Class.forName(packageName + ".AsciiHprofWriter"); 43 newArrayThreadSet = SamplingProfiler.getMethod("newArrayThreadSet", Thread[].class); 44 newThreadGroupThreadSet = SamplingProfiler.getMethod("newThreadGroupThreadSet", 45 ThreadGroup.class); 46 newThreadSet = SamplingProfiler.getConstructor(Integer.TYPE, ThreadSet); 47 start = SamplingProfiler.getMethod("start", Integer.TYPE); 48 stop = SamplingProfiler.getMethod("stop"); 49 shutdown = SamplingProfiler.getMethod("shutdown"); 50 getHprofData = SamplingProfiler.getMethod("getHprofData"); 51 write = Writer.getMethod("write", HprofData, OutputStream.class); 52 } 53 54 private Thread[] thread = new Thread[1]; 55 private Object profiler; 56 private int interval; 57 setup(boolean profileThreadGroup, int depth, int interval)58 @Override public void setup(boolean profileThreadGroup, int depth, int interval) { 59 try { 60 Thread t = Thread.currentThread(); 61 thread[0] = t; 62 Object threadSet; 63 if (profileThreadGroup) { 64 threadSet = newThreadGroupThreadSet.invoke(null, t.getThreadGroup()); 65 } else { 66 threadSet = newArrayThreadSet.invoke(null, (Object)thread); 67 } 68 this.profiler = newThreadSet.newInstance(depth, threadSet); 69 this.interval = interval; 70 } catch (Exception e) { 71 throw new AssertionError(e); 72 } 73 74 } 75 start()76 @Override public void start() { 77 try { 78 // If using the array thread set, switch to the current 79 // thread. Sometimes for timeout reasons Runners use 80 // separate threads for test execution. 81 this.thread[0] = Thread.currentThread(); 82 start.invoke(profiler, interval); 83 } catch (Exception e) { 84 throw new AssertionError(e); 85 } 86 } 87 stop()88 @Override public void stop() { 89 try { 90 stop.invoke(profiler); 91 } catch (Exception e) { 92 throw new AssertionError(e); 93 } 94 } 95 shutdown(File file)96 @Override public void shutdown(File file) { 97 try { 98 shutdown.invoke(profiler); 99 100 FileOutputStream out = new FileOutputStream(file); 101 write.invoke(null, getHprofData.invoke(profiler), out); 102 out.close(); 103 } catch (Exception e) { 104 throw new AssertionError(e); 105 } 106 } 107 } 108