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    @Suppress  // Failing.
72    public void testMethodTracing()
73    {
74        long start = System.currentTimeMillis();
75        Debug.startMethodTracing("traceTest");
76        topMethod();
77        Debug.stopMethodTracing();
78        long end = System.currentTimeMillis();
79        long elapsed = end - start;
80        Log.i(TAG, "elapsed millis: " + elapsed);
81    }
82
83    private void topMethod() {
84        aMethod();
85        bMethod();
86        cMethod();
87        dMethod(5);
88
89        Thread t1 = new aThread();
90        t1.start();
91        Thread t2 = new aThread();
92        t2.start();
93        Thread t3 = new aThread();
94        t3.start();
95        try {
96            t1.join();
97            t2.join();
98            t3.join();
99        } catch (InterruptedException e) {
100        }
101    }
102
103    private class aThread extends Thread {
104        @Override
105        public void run() {
106            aMethod();
107            bMethod();
108            cMethod();
109        }
110    }
111
112    /** Calls other methods to make some interesting trace data.
113     *
114     * @return a meaningless value
115     */
116    private int aMethod() {
117        int count = 0;
118        for (int ii = 0; ii < 6; ii++) {
119            count += bMethod();
120        }
121        for (int ii = 0; ii < 5; ii++) {
122            count += cMethod();
123        }
124        for (int ii = 0; ii < 4; ii++) {
125            count += dMethod(ii);
126        }
127        return count;
128    }
129
130    /** Calls another method to make some interesting trace data.
131     *
132     * @return a meaningless value
133     */
134    private int bMethod() {
135        int count = 0;
136        for (int ii = 0; ii < 4; ii++) {
137            count += cMethod();
138        }
139        return count;
140    }
141
142    /** Executes a simple loop to make some interesting trace data.
143     *
144     * @return a meaningless value
145     */
146    private int cMethod() {
147        int count = 0;
148        for (int ii = 0; ii < 1000; ii++) {
149            count += ii;
150        }
151        return count;
152    }
153
154    /** Calls itself recursively to make some interesting trace data.
155     *
156     * @return a meaningless value
157     */
158    private int dMethod(int level) {
159        int count = 0;
160        if (level > 0) {
161            count = dMethod(level - 1);
162        }
163        for (int ii = 0; ii < 100; ii++) {
164            count += ii;
165        }
166        if (level == 0) {
167            return count;
168        }
169        return dMethod(level - 1);
170    }
171
172    public int eMethod() {
173        eMethodCalls += 1;
174        int count = fMethod();
175        count += gMethod(3);
176        return count;
177    }
178
179    public int fMethod() {
180        fMethodCalls += 1;
181        int count = 0;
182        for (int ii = 0; ii < 10; ii++) {
183            count += ii;
184        }
185        return count;
186    }
187
188    public int gMethod(int level) {
189        gMethodCalls += 1;
190        int count = level;
191        if (level > 1)
192            count += gMethod(level - 1);
193        return count;
194    }
195
196    /*
197     * This causes the native shared library to be loaded when the
198     * class is first used.  The library is only loaded once, even if
199     * multiple classes include this line.
200     *
201     * The library must be in java.library.path, which is derived from
202     * LD_LIBRARY_PATH.  The actual library name searched for will be
203     * "libtrace_test.so" under Linux, but may be different on other
204     * platforms.
205     */
206    static {
207        Log.i(TAG, "Loading trace_test native library...");
208        try {
209            System.loadLibrary("trace_test");
210            Log.i(TAG, "Successfully loaded trace_test native library");
211        }
212        catch (UnsatisfiedLinkError ule) {
213            Log.w(TAG, "Could not load trace_test native library");
214        }
215    }
216}
217