15888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik/*
25888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Copyright (C) 2011 The Android Open Source Project
35888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
45888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
55888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * you may not use this file except in compliance with the License.
65888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * You may obtain a copy of the License at
75888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
85888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
95888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik *
105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Unless required by applicable law or agreed to in writing, software
115888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * See the License for the specific language governing permissions and
145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * limitations under the License.
155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik */
165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpackage com.test.tilebenchmark;
185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.app.Activity;
205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.content.Intent;
215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.content.Context;
225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.Bitmap;
235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.os.AsyncTask;
245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.os.Bundle;
25702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craikimport android.os.CountDownTimer;
26702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craikimport android.util.Log;
275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.util.Pair;
285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.KeyEvent;
295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.View;
305888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.view.View.OnClickListener;
315888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.webkit.WebView;
325888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.webkit.WebViewClient;
335888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.AdapterView;
345888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.AdapterView.OnItemSelectedListener;
355888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.ArrayAdapter;
365888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.Button;
375888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.EditText;
385888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.Spinner;
395888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.TextView;
405888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.widget.TextView.OnEditorActionListener;
4121555abad7ba5f5377052e2644974d3ce8c37869Chris Craikimport android.widget.ToggleButton;
425888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
435888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.FileOutputStream;
445888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.IOException;
455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.io.ObjectOutputStream;
465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik/**
485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Interface for profiling the webview's scrolling, with simple controls on how
495888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * to scroll, and what content to load.
505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik */
515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpublic class ProfileActivity extends Activity {
525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
53702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik    private static final int TIMED_RECORD_MILLIS = 2000;
54702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik
555888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public interface ProfileCallback {
56555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik        public void profileCallback(RunData data);
575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public static final String TEMP_FILENAME = "profile.tiles";
605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    Button mInspectButton;
6221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    ToggleButton mCaptureButton;
635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    Spinner mVelocitySpinner;
6421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    Spinner mMovementSpinner;
655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    EditText mUrl;
665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    ProfiledWebView mWeb;
675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    ProfileCallback mCallback;
685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
6921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
7021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
71702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik    TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient();
7221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
7321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    private enum TestingState {
7421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        NOT_TESTING,
7521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        PRE_TESTING,
7621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        START_TESTING,
7721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        STOP_TESTING,
7821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        SAVED_TESTING
7921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    };
8021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
815888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private class VelocitySelectedListener implements OnItemSelectedListener {
825888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
835888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onItemSelected(AdapterView<?> parent, View view,
845888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                int position, long id) {
855888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            String speedStr = parent.getItemAtPosition(position).toString();
865888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            int speedInt = Integer.parseInt(speedStr);
875888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mWeb.setAutoScrollSpeed(speedInt);
885888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
895888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
905888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
915888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onNothingSelected(AdapterView<?> parent) {
925888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
935888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
945888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
9521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    private class MovementSelectedListener implements OnItemSelectedListener {
9621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        @Override
9721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        public void onItemSelected(AdapterView<?> parent, View view,
9821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                int position, long id) {
9921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            String movementStr = parent.getItemAtPosition(position).toString();
100702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            if (movementStr == getResources().getString(R.string.movement_auto_scroll)) {
10121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mWeb.setWebViewClient(mAutoLoggingWebViewClient);
10221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mCaptureButton.setEnabled(false);
10321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mVelocitySpinner.setEnabled(true);
104702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            } else if (movementStr == getResources().getString(R.string.movement_manual)) {
10521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mWeb.setWebViewClient(mLoggingWebViewClient);
10621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mCaptureButton.setEnabled(true);
10721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mVelocitySpinner.setEnabled(false);
108702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            } else if (movementStr == getResources().getString(R.string.movement_timed)) {
109702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                mWeb.setWebViewClient(mTimedLoggingWebViewClient);
110702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                mCaptureButton.setEnabled(false);
111702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                mVelocitySpinner.setEnabled(false);
11221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            }
11321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        }
11421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
11521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        @Override
11621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        public void onNothingSelected(AdapterView<?> parent) {
11721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        }
11821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    }
11921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
1205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private class LoggingWebViewClient extends WebViewClient {
1215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
1225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public boolean shouldOverrideUrlLoading(WebView view, String url) {
1235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return false;
1245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1255888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1265888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
1275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onPageStarted(WebView view, String url, Bitmap favicon) {
1285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            super.onPageStarted(view, url, favicon);
1295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mUrl.setText(url);
1305888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
131702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik
132702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        @Override
133702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        public void onPageFinished(WebView view, String url) {
134702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            super.onPageFinished(view, url);
135702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            view.requestFocus();
136702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            ((ProfiledWebView)view).onPageFinished();
137702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        }
13821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    }
13921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
14021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    private class AutoLoggingWebViewClient extends LoggingWebViewClient {
141702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        @Override
142702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        public void onPageFinished(WebView view, String url) {
143702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            super.onPageFinished(view, url);
144702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            startViewProfiling(true);
145702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        }
1465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
148702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        public void onPageStarted(WebView view, String url, Bitmap favicon) {
149702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            super.onPageStarted(view, url, favicon);
150702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            setTestingState(TestingState.PRE_TESTING);
151702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        }
152702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik    }
153702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik
154702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik    private class TimedLoggingWebViewClient extends LoggingWebViewClient {
155702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        @Override
1565888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        public void onPageFinished(WebView view, String url) {
1575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            super.onPageFinished(view, url);
158702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            startViewProfiling(false);
159555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik
160702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            // after a fixed time after page finished, stop testing
161702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) {
162702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                @Override
163702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                public void onTick(long millisUntilFinished) {
164702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                }
165702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik
166702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                @Override
167702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                public void onFinish() {
168702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                    mWeb.stopScrollTest();
169702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                }
170702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik            }.start();
1715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
17221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
17321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        @Override
17421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        public void onPageStarted(WebView view, String url, Bitmap favicon) {
17521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            super.onPageStarted(view, url, favicon);
17621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            setTestingState(TestingState.PRE_TESTING);
17721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        }
1785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
1795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1805888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    private class StoreFileTask extends
181555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik            AsyncTask<Pair<String, RunData>, Void, Void> {
1825888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1835888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
184555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik        protected Void doInBackground(Pair<String, RunData>... params) {
1855888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            try {
1865888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                FileOutputStream fos = openFileOutput(params[0].first,
1875888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                        Context.MODE_PRIVATE);
1885888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                ObjectOutputStream out = new ObjectOutputStream(fos);
1895888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                out.writeObject(params[0].second);
1905888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                out.close();
1915888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            } catch (IOException ex) {
1925888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                ex.printStackTrace();
1935888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
1945888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return null;
1955888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
1965888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
1975888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        @Override
1985888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        protected void onPostExecute(Void v) {
19921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            setTestingState(TestingState.SAVED_TESTING);
2005888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
2015888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
2025888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
20321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    public void setTestingState(TestingState state) {
20421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        switch (state) {
20521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            case NOT_TESTING:
20621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mUrl.setBackgroundResource(R.color.background_not_testing);
20721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mInspectButton.setEnabled(true);
20821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mMovementSpinner.setEnabled(true);
20921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                break;
21021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            case PRE_TESTING:
21121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mInspectButton.setEnabled(false);
21221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mMovementSpinner.setEnabled(false);
21321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                break;
21421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            case START_TESTING:
215702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                mCaptureButton.setChecked(true);
21621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mUrl.setBackgroundResource(R.color.background_start_testing);
21721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mInspectButton.setEnabled(false);
21821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mMovementSpinner.setEnabled(false);
21921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                break;
22021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            case STOP_TESTING:
221702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                mCaptureButton.setChecked(false);
22221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mUrl.setBackgroundResource(R.color.background_stop_testing);
22321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                break;
22421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            case SAVED_TESTING:
22521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mInspectButton.setEnabled(true);
22621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                mMovementSpinner.setEnabled(true);
22721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                break;
22821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        }
22921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    }
23021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
23121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    /** auto - automatically scroll. */
23221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    private void startViewProfiling(boolean auto) {
233555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik        // toggle capture button to indicate capture state to user
23421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mWeb.startScrollTest(mCallback, auto);
23521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        setTestingState(TestingState.START_TESTING);
23621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik    }
23721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
2385888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    /** Called when the activity is first created. */
2395888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    @Override
2405888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public void onCreate(Bundle savedInstanceState) {
2415888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        super.onCreate(savedInstanceState);
2425888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        setContentView(R.layout.main);
2435888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mInspectButton = (Button) findViewById(R.id.inspect);
24421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mCaptureButton = (ToggleButton) findViewById(R.id.capture);
2455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
24621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mMovementSpinner = (Spinner) findViewById(R.id.movement);
2475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mUrl = (EditText) findViewById(R.id.url);
2485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mWeb = (ProfiledWebView) findViewById(R.id.web);
2491d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik        setCallback(new ProfileCallback() {
2505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            @SuppressWarnings("unchecked")
2515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            @Override
252555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik            public void profileCallback(RunData data) {
253555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik                new StoreFileTask().execute(new Pair<String, RunData>(
25421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                        TEMP_FILENAME, data));
255702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file");
25621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                setTestingState(TestingState.STOP_TESTING);
2575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
2581d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik        });
2595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
2605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        // Inspect button (opens PlaybackActivity)
2615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mInspectButton.setOnClickListener(new OnClickListener() {
2625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            @Override
2635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            public void onClick(View v) {
2645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                startActivity(new Intent(ProfileActivity.this,
2655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                        PlaybackActivity.class));
2665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
2675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        });
2685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
2695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        // Velocity spinner
2705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
2715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                this, R.array.velocity_array,
2725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                android.R.layout.simple_spinner_item);
2735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        adapter.setDropDownViewResource(
2745888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                android.R.layout.simple_spinner_dropdown_item);
2755888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mVelocitySpinner.setAdapter(adapter);
2765888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mVelocitySpinner.setOnItemSelectedListener(
2775888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                new VelocitySelectedListener());
2785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mVelocitySpinner.setSelection(3);
2795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
28021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        // Movement spinner
28121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        String content[] = {
28221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                getResources().getString(R.string.movement_auto_scroll),
283702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                getResources().getString(R.string.movement_manual),
284702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik                getResources().getString(R.string.movement_timed)
28521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        };
28621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        adapter = new ArrayAdapter<CharSequence>(this,
28721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                android.R.layout.simple_spinner_item, content);
28821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        adapter.setDropDownViewResource(
28921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                android.R.layout.simple_spinner_dropdown_item);
29021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mMovementSpinner.setAdapter(adapter);
29121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mMovementSpinner.setOnItemSelectedListener(
29221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                new MovementSelectedListener());
29321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mMovementSpinner.setSelection(0);
29421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
29521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        // Capture toggle button
29621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        mCaptureButton.setOnClickListener(new OnClickListener() {
29721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            @Override
29821555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            public void onClick(View v) {
29921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                if (mCaptureButton.isChecked()) {
30021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                    startViewProfiling(false);
30121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                } else {
30221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                    mWeb.stopScrollTest();
30321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik                }
30421555abad7ba5f5377052e2644974d3ce8c37869Chris Craik            }
30521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        });
30621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
3075888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        // Custom profiling WebView
308702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik        mWeb.init(this);
3095888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mWeb.setWebViewClient(new LoggingWebViewClient());
3105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
3115888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        // URL text entry
3125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mUrl.setOnEditorActionListener(new OnEditorActionListener() {
3135888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            public boolean onEditorAction(TextView v, int actionId,
3145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                    KeyEvent event) {
3155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                String url = mUrl.getText().toString();
3165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                mWeb.loadUrl(url);
3175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                mWeb.requestFocus();
3185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik                return true;
3195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            }
3205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        });
32121555abad7ba5f5377052e2644974d3ce8c37869Chris Craik
32221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik        setTestingState(TestingState.NOT_TESTING);
3235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
3245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
3255888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public void setCallback(ProfileCallback callback) {
3265888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        mCallback = callback;
3275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
3285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik
3295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    @Override
3305888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    public boolean onKeyDown(int keyCode, KeyEvent event) {
3315888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
3325888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            mWeb.goBack();
3335888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik            return true;
3345888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        }
3355888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik        return super.onKeyDown(keyCode, event);
3365888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik    }
3375888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik}
338