2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.test.tilebenchmark;
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.content.Context;
22 import android.graphics.Bitmap;
23 import android.os.AsyncTask;
24 import android.os.Bundle;
25 import android.os.CountDownTimer;
26 import android.util.Log;
27 import android.util.Pair;
28 import android.view.KeyEvent;
29 import android.view.View;
30 import android.view.View.OnClickListener;
31 import android.webkit.WebView;
32 import android.webkit.WebViewClient;
33 import android.widget.AdapterView;
34 import android.widget.AdapterView.OnItemSelectedListener;
35 import android.widget.ArrayAdapter;
36 import android.widget.Button;
37 import android.widget.EditText;
38 import android.widget.Spinner;
39 import android.widget.TextView;
40 import android.widget.TextView.OnEditorActionListener;
41 import android.widget.ToggleButton;
43 import java.io.FileOutputStream;
44 import java.io.IOException;
45 import java.io.ObjectOutputStream;
48 * Interface for profiling the webview's scrolling, with simple controls on how
49 * to scroll, and what content to load.
51 public class ProfileActivity extends Activity {
53 private static final int TIMED_RECORD_MILLIS = 2000;
55 public interface ProfileCallback {
56 public void profileCallback(RunData data);
59 public static final String TEMP_FILENAME = "profile.tiles";
61 Button mInspectButton;
62 ToggleButton mCaptureButton;
63 Spinner mVelocitySpinner;
64 Spinner mMovementSpinner;
67 ProfileCallback mCallback;
69 LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
70 AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
71 TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient();
73 private enum TestingState {
81 private class VelocitySelectedListener implements OnItemSelectedListener {
83 public void onItemSelected(AdapterView<?> parent, View view,
84 int position, long id) {
85 String speedStr = parent.getItemAtPosition(position).toString();
86 int speedInt = Integer.parseInt(speedStr);
87 mWeb.setAutoScrollSpeed(speedInt);
91 public void onNothingSelected(AdapterView<?> parent) {
95 private class MovementSelectedListener implements OnItemSelectedListener {
97 public void onItemSelected(AdapterView<?> parent, View view,
98 int position, long id) {
99 String movementStr = parent.getItemAtPosition(position).toString();
100 if (movementStr == getResources().getString(R.string.movement_auto_scroll)) {
101 mWeb.setWebViewClient(mAutoLoggingWebViewClient);
102 mCaptureButton.setEnabled(false);
103 mVelocitySpinner.setEnabled(true);
104 } else if (movementStr == getResources().getString(R.string.movement_manual)) {
105 mWeb.setWebViewClient(mLoggingWebViewClient);
106 mCaptureButton.setEnabled(true);
107 mVelocitySpinner.setEnabled(false);
108 } else if (movementStr == getResources().getString(R.string.movement_timed)) {
109 mWeb.setWebViewClient(mTimedLoggingWebViewClient);
110 mCaptureButton.setEnabled(false);
111 mVelocitySpinner.setEnabled(false);
116 public void onNothingSelected(AdapterView<?> parent) {
120 private class LoggingWebViewClient extends WebViewClient {
122 public boolean shouldOverrideUrlLoading(WebView view, String url) {
127 public void onPageStarted(WebView view, String url, Bitmap favicon) {
128 super.onPageStarted(view, url, favicon);
133 public void onPageFinished(WebView view, String url) {
134 super.onPageFinished(view, url);
136 ((ProfiledWebView)view).onPageFinished();
140 private class AutoLoggingWebViewClient extends LoggingWebViewClient {
142 public void onPageFinished(WebView view, String url) {
143 super.onPageFinished(view, url);
144 startViewProfiling(true);
148 public void onPageStarted(WebView view, String url, Bitmap favicon) {
149 super.onPageStarted(view, url, favicon);
150 setTestingState(TestingState.PRE_TESTING);
154 private class TimedLoggingWebViewClient extends LoggingWebViewClient {
156 public void onPageFinished(WebView view, String url) {
157 super.onPageFinished(view, url);
158 startViewProfiling(false);
160 // after a fixed time after page finished, stop testing
161 new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) {
163 public void onTick(long millisUntilFinished) {
167 public void onFinish() {
168 mWeb.stopScrollTest();
174 public void onPageStarted(WebView view, String url, Bitmap favicon) {
175 super.onPageStarted(view, url, favicon);
176 setTestingState(TestingState.PRE_TESTING);
180 private class StoreFileTask extends
181 AsyncTask<Pair<String, RunData>, Void, Void> {
184 protected Void doInBackground(Pair<String, RunData>... params) {
186 FileOutputStream fos = openFileOutput(params[0].first,
187 Context.MODE_PRIVATE);
188 ObjectOutputStream out = new ObjectOutputStream(fos);
189 out.writeObject(params[0].second);
191 } catch (IOException ex) {
192 ex.printStackTrace();
198 protected void onPostExecute(Void v) {
199 setTestingState(TestingState.SAVED_TESTING);
203 public void setTestingState(TestingState state) {
206 mUrl.setBackgroundResource(R.color.background_not_testing);
207 mInspectButton.setEnabled(true);
208 mMovementSpinner.setEnabled(true);
211 mInspectButton.setEnabled(false);
212 mMovementSpinner.setEnabled(false);
215 mCaptureButton.setChecked(true);
216 mUrl.setBackgroundResource(R.color.background_start_testing);
217 mInspectButton.setEnabled(false);
218 mMovementSpinner.setEnabled(false);
221 mCaptureButton.setChecked(false);
222 mUrl.setBackgroundResource(R.color.background_stop_testing);
225 mInspectButton.setEnabled(true);
226 mMovementSpinner.setEnabled(true);
231 /** auto - automatically scroll. */
232 private void startViewProfiling(boolean auto) {
233 // toggle capture button to indicate capture state to user
234 mWeb.startScrollTest(mCallback, auto);
235 setTestingState(TestingState.START_TESTING);
238 /** Called when the activity is first created. */
240 public void onCreate(Bundle savedInstanceState) {
241 super.onCreate(savedInstanceState);
242 setContentView(R.layout.main);
243 mInspectButton = (Button) findViewById(R.id.inspect);
244 mCaptureButton = (ToggleButton) findViewById(R.id.capture);
245 mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
246 mMovementSpinner = (Spinner) findViewById(R.id.movement);
247 mUrl = (EditText) findViewById(R.id.url);
248 mWeb = (ProfiledWebView) findViewById(R.id.web);
249 setCallback(new ProfileCallback() {
250 @SuppressWarnings("unchecked")
252 public void profileCallback(RunData data) {
253 new StoreFileTask().execute(new Pair<String, RunData>(
254 TEMP_FILENAME, data));
255 Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file");
256 setTestingState(TestingState.STOP_TESTING);
260 // Inspect button (opens PlaybackActivity)
261 mInspectButton.setOnClickListener(new OnClickListener() {
263 public void onClick(View v) {
264 startActivity(new Intent(ProfileActivity.this,
265 PlaybackActivity.class));
270 ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
271 this, R.array.velocity_array,
272 android.R.layout.simple_spinner_item);
273 adapter.setDropDownViewResource(
274 android.R.layout.simple_spinner_dropdown_item);
275 mVelocitySpinner.setAdapter(adapter);
276 mVelocitySpinner.setOnItemSelectedListener(
277 new VelocitySelectedListener());
278 mVelocitySpinner.setSelection(3);
282 getResources().getString(R.string.movement_auto_scroll),
283 getResources().getString(R.string.movement_manual),
284 getResources().getString(R.string.movement_timed)
286 adapter = new ArrayAdapter<CharSequence>(this,
287 android.R.layout.simple_spinner_item, content);
288 adapter.setDropDownViewResource(
289 android.R.layout.simple_spinner_dropdown_item);
290 mMovementSpinner.setAdapter(adapter);
291 mMovementSpinner.setOnItemSelectedListener(
292 new MovementSelectedListener());
293 mMovementSpinner.setSelection(0);
295 // Capture toggle button
296 mCaptureButton.setOnClickListener(new OnClickListener() {
298 public void onClick(View v) {
299 if (mCaptureButton.isChecked()) {
300 startViewProfiling(false);
302 mWeb.stopScrollTest();
307 // Custom profiling WebView
309 mWeb.setWebViewClient(new LoggingWebViewClient());
312 mUrl.setOnEditorActionListener(new OnEditorActionListener() {
313 public boolean onEditorAction(TextView v, int actionId,
315 String url = mUrl.getText().toString();
322 setTestingState(TestingState.NOT_TESTING);
325 public void setCallback(ProfileCallback callback) {
326 mCallback = callback;
330 public boolean onKeyDown(int keyCode, KeyEvent event) {
331 if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
335 return super.onKeyDown(keyCode, event);