1/*
2 * Copyright (C) 2006 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
17package android.os;
18
19import android.os.Debug;
20import android.test.AndroidTestCase;
21import android.test.suitebuilder.annotation.LargeTest;
22import android.test.suitebuilder.annotation.SmallTest;
23import android.test.suitebuilder.annotation.Suppress;
24import android.util.Log;
25
26/**
27 * This class is used to test the native tracing support.  Run this test
28 * while tracing on the emulator and then run traceview to view the trace.
29 */
30public class TraceTest extends AndroidTestCase
31{
32    private static final String TAG = "TraceTest";
33    private int eMethodCalls = 0;
34    private int fMethodCalls = 0;
35    private int gMethodCalls = 0;
36
37    @SmallTest
38    public void testNativeTracingFromJava()
39    {
40        long start = System.currentTimeMillis();
41        Debug.startNativeTracing();
42        //nativeMethod();
43        int count = 0;
44        for (int ii = 0; ii < 20; ii++) {
45            count = eMethod();
46        }
47        Debug.stopNativeTracing();
48        long end = System.currentTimeMillis();
49        long elapsed = end - start;
50        Log.i(TAG, "elapsed millis: " + elapsed);
51        Log.i(TAG, "eMethod calls: " + eMethodCalls
52                + " fMethod calls: " + fMethodCalls
53                + " gMethod calls: " + gMethodCalls);
54    }
55
56    // This should not run in the automated suite.
57    @Suppress
58    public void disableTestNativeTracingFromC()
59    {
60        long start = System.currentTimeMillis();
61        nativeMethodAndStartTracing();
62        long end = System.currentTimeMillis();
63        long elapsed = end - start;
64        Log.i(TAG, "elapsed millis: " + elapsed);
65    }
66
67    native void nativeMethod();
68    native void nativeMethodAndStartTracing();
69
70    @LargeTest
71    public void testMethodTracing()
72    {
73        long start = System.currentTimeMillis();
74        Debug.startMethodTracing("traceTest");
75        topMethod();
76        Debug.stopMethodTracing();
77        long end = System.currentTimeMillis();
78        long elapsed = end - start;
79        Log.i(TAG, "elapsed millis: " + elapsed);
80    }
81
82    private void topMethod() {
83        aMethod();
84        bMethod();
85        cMethod();
86        dMethod(5);
87
88        Thread t1 = new aThread();
89        t1.start();
90        Thread t2 = new aThread();
91        t2.start();
92        Thread t3 = new aThread();
93        t3.start();
94        try {
95            t1.join();
96            t2.join();
97            t3.join();
98        } catch (InterruptedException e) {
99        }
100    }
101
102    private class aThread extends Thread {
103        @Override
104        public void run() {
105            aMethod();
106            bMethod();
107            cMethod();
108        }
109    }
110
111    /** Calls other methods to make some interesting trace data.
112     *
113     * @return a meaningless value
114     */
115    private int aMethod() {
116        int count = 0;
117        for (int ii = 0; ii < 6; ii++) {
118            count += bMethod();
119        }
120        for (int ii = 0; ii < 5; ii++) {
121            count += cMethod();
122        }
123        for (int ii = 0; ii < 4; ii++) {
124            count += dMethod(ii);
125        }
126        return count;
127    }
128
129    /** Calls another method to make some interesting trace data.
130     *
131     * @return a meaningless value
132     */
133    private int bMethod() {
134        int count = 0;
135        for (int ii = 0; ii < 4; ii++) {
136            count += cMethod();
137        }
138        return count;
139    }
140
141    /** Executes a simple loop to make some interesting trace data.
142     *
143     * @return a meaningless value
144     */
145    private int cMethod() {
146        int count = 0;
147        for (int ii = 0; ii < 1000; ii++) {
148            count += ii;
149        }
150        return count;
151    }
152
153    /** Calls itself recursively to make some interesting trace data.
154     *
155     * @return a meaningless value
156     */
157    private int dMethod(int level) {
158        int count = 0;
159        if (level > 0) {
160            count = dMethod(level - 1);
161        }
162        for (int ii = 0; ii < 100; ii++) {
163            count += ii;
164        }
165        if (level == 0) {
166            return count;
167        }
168        return dMethod(level - 1);
169    }
170
171    public int eMethod() {
172        eMethodCalls += 1;
173        int count = fMethod();
174        count += gMethod(3);
175        return count;
176    }
177
178    public int fMethod() {
179        fMethodCalls += 1;
180        int count = 0;
181        for (int ii = 0; ii < 10; ii++) {
182            count += ii;
183        }
184        return count;
185    }
186
187    public int gMethod(int level) {
188        gMethodCalls += 1;
189        int count = level;
190        if (level > 1)
191            count += gMethod(level - 1);
192        return count;
193    }
194
195    /*
196     * This causes the native shared library to be loaded when the
197     * class is first used.  The library is only loaded once, even if
198     * multiple classes include this line.
199     *
200     * The library must be in java.library.path, which is derived from
201     * LD_LIBRARY_PATH.  The actual library name searched for will be
202     * "libtrace_test.so" under Linux, but may be different on other
203     * platforms.
204     */
205    static {
206        Log.i(TAG, "Loading trace_test native library...");
207        try {
208            System.loadLibrary("trace_test");
209            Log.i(TAG, "Successfully loaded trace_test native library");
210        }
211        catch (UnsatisfiedLinkError ule) {
212            Log.w(TAG, "Could not load trace_test native library");
213        }
214    }
215}
216