blob: 2e771577a0436399a144aba8f6525d8a0d9621fc [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.test.tilebenchmark;
import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.ToggleButton;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* Interface for profiling the webview's scrolling, with simple controls on how
* to scroll, and what content to load.
*/
public class ProfileActivity extends Activity {
private static final int TIMED_RECORD_MILLIS = 2000;
public interface ProfileCallback {
public void profileCallback(RunData data);
}
public static final String TEMP_FILENAME = "profile.tiles";
Button mInspectButton;
ToggleButton mCaptureButton;
Spinner mVelocitySpinner;
Spinner mMovementSpinner;
EditText mUrl;
ProfiledWebView mWeb;
ProfileCallback mCallback;
LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient();
private enum TestingState {
NOT_TESTING,
PRE_TESTING,
START_TESTING,
STOP_TESTING,
SAVED_TESTING
};
private class VelocitySelectedListener implements OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
String speedStr = parent.getItemAtPosition(position).toString();
int speedInt = Integer.parseInt(speedStr);
mWeb.setAutoScrollSpeed(speedInt);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
private class MovementSelectedListener implements OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
String movementStr = parent.getItemAtPosition(position).toString();
if (movementStr == getResources().getString(R.string.movement_auto_scroll)) {
mWeb.setWebViewClient(mAutoLoggingWebViewClient);
mCaptureButton.setEnabled(false);
mVelocitySpinner.setEnabled(true);
} else if (movementStr == getResources().getString(R.string.movement_manual)) {
mWeb.setWebViewClient(mLoggingWebViewClient);
mCaptureButton.setEnabled(true);
mVelocitySpinner.setEnabled(false);
} else if (movementStr == getResources().getString(R.string.movement_timed)) {
mWeb.setWebViewClient(mTimedLoggingWebViewClient);
mCaptureButton.setEnabled(false);
mVelocitySpinner.setEnabled(false);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
private class LoggingWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
mUrl.setText(url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.requestFocus();
((ProfiledWebView)view).onPageFinished();
}
}
private class AutoLoggingWebViewClient extends LoggingWebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
startViewProfiling(true);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
setTestingState(TestingState.PRE_TESTING);
}
}
private class TimedLoggingWebViewClient extends LoggingWebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
startViewProfiling(false);
// after a fixed time after page finished, stop testing
new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) {
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
mWeb.stopScrollTest();
}
}.start();
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
setTestingState(TestingState.PRE_TESTING);
}
}
private class StoreFileTask extends
AsyncTask<Pair<String, RunData>, Void, Void> {
@Override
protected Void doInBackground(Pair<String, RunData>... params) {
try {
FileOutputStream fos = openFileOutput(params[0].first,
Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(params[0].second);
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void v) {
setTestingState(TestingState.SAVED_TESTING);
}
}
public void setTestingState(TestingState state) {
switch (state) {
case NOT_TESTING:
mUrl.setBackgroundResource(R.color.background_not_testing);
mInspectButton.setEnabled(true);
mMovementSpinner.setEnabled(true);
break;
case PRE_TESTING:
mInspectButton.setEnabled(false);
mMovementSpinner.setEnabled(false);
break;
case START_TESTING:
mCaptureButton.setChecked(true);
mUrl.setBackgroundResource(R.color.background_start_testing);
mInspectButton.setEnabled(false);
mMovementSpinner.setEnabled(false);
break;
case STOP_TESTING:
mCaptureButton.setChecked(false);
mUrl.setBackgroundResource(R.color.background_stop_testing);
break;
case SAVED_TESTING:
mInspectButton.setEnabled(true);
mMovementSpinner.setEnabled(true);
break;
}
}
/** auto - automatically scroll. */
private void startViewProfiling(boolean auto) {
// toggle capture button to indicate capture state to user
mWeb.startScrollTest(mCallback, auto);
setTestingState(TestingState.START_TESTING);
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mInspectButton = (Button) findViewById(R.id.inspect);
mCaptureButton = (ToggleButton) findViewById(R.id.capture);
mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
mMovementSpinner = (Spinner) findViewById(R.id.movement);
mUrl = (EditText) findViewById(R.id.url);
mWeb = (ProfiledWebView) findViewById(R.id.web);
setCallback(new ProfileCallback() {
@SuppressWarnings("unchecked")
@Override
public void profileCallback(RunData data) {
new StoreFileTask().execute(new Pair<String, RunData>(
TEMP_FILENAME, data));
Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file");
setTestingState(TestingState.STOP_TESTING);
}
});
// Inspect button (opens PlaybackActivity)
mInspectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ProfileActivity.this,
PlaybackActivity.class));
}
});
// Velocity spinner
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.velocity_array,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mVelocitySpinner.setAdapter(adapter);
mVelocitySpinner.setOnItemSelectedListener(
new VelocitySelectedListener());
mVelocitySpinner.setSelection(3);
// Movement spinner
String content[] = {
getResources().getString(R.string.movement_auto_scroll),
getResources().getString(R.string.movement_manual),
getResources().getString(R.string.movement_timed)
};
adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item, content);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mMovementSpinner.setAdapter(adapter);
mMovementSpinner.setOnItemSelectedListener(
new MovementSelectedListener());
mMovementSpinner.setSelection(0);
// Capture toggle button
mCaptureButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCaptureButton.isChecked()) {
startViewProfiling(false);
} else {
mWeb.stopScrollTest();
}
}
});
// Custom profiling WebView
mWeb.init(this);
mWeb.setWebViewClient(new LoggingWebViewClient());
// URL text entry
mUrl.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
String url = mUrl.getText().toString();
mWeb.loadUrl(url);
mWeb.requestFocus();
return true;
}
});
setTestingState(TestingState.NOT_TESTING);
}
public void setCallback(ProfileCallback callback) {
mCallback = callback;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
mWeb.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}