1ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project/*
2ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project *
4ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * you may not use this file except in compliance with the License.
6ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * You may obtain a copy of the License at
7ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project *
8ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project *
10ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * See the License for the specific language governing permissions and
14ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * limitations under the License.
15ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project */
16ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
17ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectpackage com.android.dumprendertree;
18ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
19f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhuimport com.android.dumprendertree.forwarder.AdbUtils;
20f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhuimport com.android.dumprendertree.forwarder.ForwardServer;
21f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu
223ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhuimport android.app.Activity;
23ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport android.app.Instrumentation;
240006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhuimport android.content.Context;
25ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport android.content.Intent;
26ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport android.os.Bundle;
27b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhuimport android.os.Debug;
288b85dceadf281705a94d7546556fa5969364a658Christian Mehlmauerimport android.os.Environment;
2940656be65870932592daf070c7cbbc382dda67b5Guang Zhuimport android.os.Process;
30ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport android.test.ActivityInstrumentationTestCase2;
3140656be65870932592daf070c7cbbc382dda67b5Guang Zhuimport android.util.Log;
32ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
330006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhuimport java.io.File;
34ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport java.io.FileOutputStream;
35ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectimport java.io.IOException;
36b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhuimport java.io.InputStream;
37b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhuimport java.io.OutputStream;
38b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhuimport java.io.PrintStream;
395794f2302209981c64425ea2b661b17f00b8f808Guang Zhuimport java.util.concurrent.CountDownLatch;
405794f2302209981c64425ea2b661b17f00b8f808Guang Zhuimport java.util.concurrent.TimeUnit;
41f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhuimport java.util.regex.Matcher;
42f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhuimport java.util.regex.Pattern;
43ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
44ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectpublic class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
45ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
46ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    private final static String LOGTAG = "LoadTest";
478b85dceadf281705a94d7546556fa5969364a658Christian Mehlmauer    private final static String LOAD_TEST_RESULT =
488b85dceadf281705a94d7546556fa5969364a658Christian Mehlmauer        Environment.getExternalStorageDirectory() + "/load_test_result.txt";
495794f2302209981c64425ea2b661b17f00b8f808Guang Zhu    private final static int MAX_GC_WAIT_SEC = 10;
50f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu    private final static int LOCAL_PORT = 17171;
51b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    private boolean mFinished;
52b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    static final String LOAD_TEST_RUNNER_FILES[] = {
53b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        "run_page_cycler.py"
544010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    };
55f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu    private ForwardServer mForwardServer;
56b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
57ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    public LoadTestsAutoTest() {
58f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        super(TestShellActivity.class);
59ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
60ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
61ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // This function writes the result of the layout test to
62ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // Am status so that it can be picked up from a script.
63ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    public void passOrFailCallback(String file, boolean result) {
64ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        Instrumentation inst = getInstrumentation();
65ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        Bundle bundle = new Bundle();
66ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        bundle.putBoolean(file, result);
67ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        inst.sendStatus(0, bundle);
68ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
69b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
70f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu    private String setUpForwarding(String forwardInfo, String suite, String iteration) throws IOException {
71f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        // read forwarding information first
72f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        Pattern forwardPattern = Pattern.compile("(.*):(\\d+)/(.*)/");
73f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        Matcher matcher = forwardPattern.matcher(forwardInfo);
74f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        if (!matcher.matches()) {
75f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            throw new RuntimeException("Invalid forward information");
76f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        }
77f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        String host = matcher.group(1);
78f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        int port = Integer.parseInt(matcher.group(2));
79f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        mForwardServer = new ForwardServer(LOCAL_PORT, AdbUtils.resolve(host), port);
80f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        mForwardServer.start();
81f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        return String.format("http://127.0.0.1:%d/%s/%s/start.html?auto=1&iterations=%s",
82f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu                LOCAL_PORT, matcher.group(3), suite, iteration);
83f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu    }
84f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu
85ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // Invokes running of layout tests
86ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // and waits till it has finished running.
87f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu    public void runPageCyclerTest() throws IOException {
88ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
89ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
90f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        if (runner.mPageCyclerSuite != null) {
91f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            // start forwarder to use page cycler suites hosted on external web server
92f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            if (runner.mPageCyclerForwardHost == null) {
93f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu                throw new RuntimeException("no forwarder information provided");
94f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            }
95f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            runner.mTestPath = setUpForwarding(runner.mPageCyclerForwardHost,
96f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu                    runner.mPageCyclerSuite, runner.mPageCyclerIteration);
97f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            Log.d(LOGTAG, "using path: " + runner.mTestPath);
98f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        }
99f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu
100ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        if (runner.mTestPath == null) {
101f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            throw new RuntimeException("No test specified");
102ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
103b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
104c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu        final TestShellActivity activity = (TestShellActivity) getActivity();
105ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
1062a197b128a2317eec6efaa0a21e529cdf534c6f2Guang Zhu        Log.v(LOGTAG, "About to run tests, calling gc first...");
10740656be65870932592daf070c7cbbc382dda67b5Guang Zhu        freeMem();
1082a197b128a2317eec6efaa0a21e529cdf534c6f2Guang Zhu
109ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        // Run tests
1103ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu        runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
111ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
112c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu        getInstrumentation().runOnMainSync(new Runnable() {
113c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu
114c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu            @Override
115c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu            public void run() {
116c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu                activity.clearCache();
117c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu            }
118c1635bf14ea1e7b388959b263bc21c0d8d77cda3Guang Zhu        });
119f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        if (mForwardServer != null) {
120f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            mForwardServer.stop();
121f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            mForwardServer = null;
122f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        }
1231f6c72bff6fa875a08f2d5510b5a61ce766643d2Guang Zhu        try {
1241f6c72bff6fa875a08f2d5510b5a61ce766643d2Guang Zhu            Thread.sleep(5000);
1251f6c72bff6fa875a08f2d5510b5a61ce766643d2Guang Zhu        } catch (InterruptedException e) {
1261f6c72bff6fa875a08f2d5510b5a61ce766643d2Guang Zhu        }
127b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        dumpMemoryInfo();
128b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
129ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        // Kill activity
130ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        activity.finish();
131ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
132ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
13340656be65870932592daf070c7cbbc382dda67b5Guang Zhu    private void freeMem() {
1343974be616399c144485e218ab6ed24dd922665f1Guang Zhu        Log.v(LOGTAG, "freeMem: calling gc...");
1355794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        final CountDownLatch latch = new CountDownLatch(1);
136f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu        @SuppressWarnings("unused")
1375794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        Object dummy = new Object() {
138f6d1b3f125b06fcc4847be3cfb35e8ce21905676Guang Zhu            // this object instance is used to track gc
1395794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            @Override
1405794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            protected void finalize() throws Throwable {
1415794f2302209981c64425ea2b661b17f00b8f808Guang Zhu                latch.countDown();
1425794f2302209981c64425ea2b661b17f00b8f808Guang Zhu                super.finalize();
1435794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            }
1445794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        };
1455794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        dummy = null;
1465794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        System.gc();
1475794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        try {
1485794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            if (!latch.await(MAX_GC_WAIT_SEC, TimeUnit.SECONDS)) {
1495794f2302209981c64425ea2b661b17f00b8f808Guang Zhu                Log.w(LOGTAG, "gc did not happen in 10s");
1505794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            }
1515794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        } catch (InterruptedException e) {
1525794f2302209981c64425ea2b661b17f00b8f808Guang Zhu            //ignore
1535794f2302209981c64425ea2b661b17f00b8f808Guang Zhu        }
15440656be65870932592daf070c7cbbc382dda67b5Guang Zhu    }
15540656be65870932592daf070c7cbbc382dda67b5Guang Zhu
15640656be65870932592daf070c7cbbc382dda67b5Guang Zhu    private void printRow(PrintStream ps, String format, Object...objs) {
15740656be65870932592daf070c7cbbc382dda67b5Guang Zhu        ps.println(String.format(format, objs));
15840656be65870932592daf070c7cbbc382dda67b5Guang Zhu    }
15940656be65870932592daf070c7cbbc382dda67b5Guang Zhu
160b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    private void dumpMemoryInfo() {
161ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        try {
16240656be65870932592daf070c7cbbc382dda67b5Guang Zhu            freeMem();
163b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            Log.v(LOGTAG, "Dumping memory information.");
164b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
165ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            FileOutputStream out = new FileOutputStream(LOAD_TEST_RESULT, true);
166b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            PrintStream ps = new PrintStream(out);
167b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
168b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            ps.print("\n\n\n");
16940656be65870932592daf070c7cbbc382dda67b5Guang Zhu            ps.println("** MEMINFO in pid " + Process.myPid()
17040656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    + " [com.android.dumprendertree] **");
17140656be65870932592daf070c7cbbc382dda67b5Guang Zhu            String formatString = "%17s %8s %8s %8s %8s";
17240656be65870932592daf070c7cbbc382dda67b5Guang Zhu
17340656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long nativeMax = Debug.getNativeHeapSize() / 1024;
17440656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
17540656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
17640656be65870932592daf070c7cbbc382dda67b5Guang Zhu            Runtime runtime = Runtime.getRuntime();
17740656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long dalvikMax = runtime.totalMemory() / 1024;
17840656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long dalvikFree = runtime.freeMemory() / 1024;
17940656be65870932592daf070c7cbbc382dda67b5Guang Zhu            long dalvikAllocated = dalvikMax - dalvikFree;
18040656be65870932592daf070c7cbbc382dda67b5Guang Zhu
18140656be65870932592daf070c7cbbc382dda67b5Guang Zhu
18240656be65870932592daf070c7cbbc382dda67b5Guang Zhu            Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
18340656be65870932592daf070c7cbbc382dda67b5Guang Zhu            Debug.getMemoryInfo(memInfo);
18440656be65870932592daf070c7cbbc382dda67b5Guang Zhu
18540656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int nativeShared = memInfo.nativeSharedDirty;
18640656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int dalvikShared = memInfo.dalvikSharedDirty;
18740656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int otherShared = memInfo.otherSharedDirty;
18840656be65870932592daf070c7cbbc382dda67b5Guang Zhu
18940656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int nativePrivate = memInfo.nativePrivateDirty;
19040656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int dalvikPrivate = memInfo.dalvikPrivateDirty;
19140656be65870932592daf070c7cbbc382dda67b5Guang Zhu            final int otherPrivate = memInfo.otherPrivateDirty;
19240656be65870932592daf070c7cbbc382dda67b5Guang Zhu
19340656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "", "native", "dalvik", "other", "total");
19440656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
19540656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
19640656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    nativeAllocated + dalvikAllocated);
19740656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "free:", nativeFree, dalvikFree, "N/A",
19840656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    nativeFree + dalvikFree);
19940656be65870932592daf070c7cbbc382dda67b5Guang Zhu
20040656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
20140656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
20240656be65870932592daf070c7cbbc382dda67b5Guang Zhu
20340656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "(shared dirty):", nativeShared, dalvikShared, otherShared,
20440656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    nativeShared + dalvikShared + otherShared);
20540656be65870932592daf070c7cbbc382dda67b5Guang Zhu            printRow(ps, formatString, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
20640656be65870932592daf070c7cbbc382dda67b5Guang Zhu                    nativePrivate + dalvikPrivate + otherPrivate);
207b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            ps.print("\n\n\n");
208b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            ps.flush();
209b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            ps.close();
210b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            out.flush();
211b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            out.close();
212ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        } catch (IOException e) {
213ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            Log.e(LOGTAG, e.getMessage());
214b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        }
215ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
216b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
217ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // A convenient method to be called by another activity.
2183ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu    private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) {
219ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        activity.setCallback(new TestShellCallback() {
2203ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu            @Override
221ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            public void finished() {
222ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                synchronized (LoadTestsAutoTest.this) {
223b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                    mFinished = true;
224ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                    LoadTestsAutoTest.this.notifyAll();
225ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                }
226b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            }
22740656be65870932592daf070c7cbbc382dda67b5Guang Zhu
2283ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu            @Override
2294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu            public void timedOut(String url) {
2304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu            }
2313ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu
2323ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu            @Override
2333ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu            public void dumpResult(String webViewDump) {
2343ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                String lines[] = webViewDump.split("\\r?\\n");
2353ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                for (String line : lines) {
2363ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    line = line.trim();
2373ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    // parse for a line like this:
2383ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    // totals:   9620.00 11947.00    10099.75    380.38
2393ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    // and return the 3rd number, which is mean
2403ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    if (line.startsWith("totals:")) {
2413ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                        line = line.substring(7).trim(); // strip "totals:"
2423ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                        String[] numbers = line.split("\\s+");
2433ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                        if (numbers.length == 4) {
2443ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                            Bundle b = new Bundle();
2453ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                            b.putString("mean", numbers[2]);
2463ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                            getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, b);
2473ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                        }
2483ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                    }
2493ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu                }
2503ae8c42152d890ab771053fa6b16b038ee44326dGuang Zhu            }
251ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        });
252b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
253b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        mFinished = false;
254ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
255ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        intent.setClass(activity, TestShellActivity.class);
256ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
257ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        intent.putExtra(TestShellActivity.TEST_URL, url);
258ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
259ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT);
260ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        activity.startActivity(intent);
261b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
262ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        // Wait until done.
263ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        synchronized (this) {
264b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            while(!mFinished) {
265b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                try {
266b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                    this.wait();
267b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                } catch (InterruptedException e) { }
268b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            }
269ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
270b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    }
271b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
272b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    public void copyRunnerAssetsToCache() {
273b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        try {
2740006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhu            Context targetContext = getInstrumentation().getTargetContext();
2750006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhu            File cacheDir = targetContext.getCacheDir();
276b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
277b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            for( int i=0; i< LOAD_TEST_RUNNER_FILES.length; i++) {
2780006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhu                InputStream in = targetContext.getAssets().open(
279b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                        LOAD_TEST_RUNNER_FILES[i]);
280b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                OutputStream out = new FileOutputStream(
2810006952a8dc5a115cceb597ac53ec5bce703fd4fGuang Zhu                        new File(cacheDir, LOAD_TEST_RUNNER_FILES[i]));
282b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
283b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                byte[] buf = new byte[2048];
284b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                int len;
285b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
286b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                while ((len = in.read(buf)) >= 0 ) {
287b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                    out.write(buf, 0, len);
288b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                }
289b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                out.close();
290b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu                in.close();
291b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu            }
292b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        }catch (IOException e) {
293b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu          e.printStackTrace();
294b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu        }
295b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
296b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu    }
297b933f669e26afad8a2466edcae8c1ffda6c15721Guang Zhu
298ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project}
299