• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
17 package com.test.tilebenchmark;
18 
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.util.Pair;
26 import android.view.KeyEvent;
27 import android.view.View;
28 import android.view.View.OnClickListener;
29 import android.webkit.WebSettings;
30 import android.webkit.WebView;
31 import android.webkit.WebViewClient;
32 import android.widget.AdapterView;
33 import android.widget.AdapterView.OnItemSelectedListener;
34 import android.widget.ArrayAdapter;
35 import android.widget.Button;
36 import android.widget.EditText;
37 import android.widget.Spinner;
38 import android.widget.TextView;
39 import android.widget.TextView.OnEditorActionListener;
40 import android.widget.ToggleButton;
41 
42 import java.io.FileOutputStream;
43 import java.io.IOException;
44 import java.io.ObjectOutputStream;
45 
46 /**
47  * Interface for profiling the webview's scrolling, with simple controls on how
48  * to scroll, and what content to load.
49  */
50 public class ProfileActivity extends Activity {
51 
52     public interface ProfileCallback {
profileCallback(RunData data)53         public void profileCallback(RunData data);
54     }
55 
56     public static final String TEMP_FILENAME = "profile.tiles";
57 
58     Button mInspectButton;
59     ToggleButton mCaptureButton;
60     Spinner mVelocitySpinner;
61     Spinner mMovementSpinner;
62     EditText mUrl;
63     ProfiledWebView mWeb;
64     ProfileCallback mCallback;
65 
66     LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
67     AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
68 
69     private enum TestingState {
70         NOT_TESTING,
71         PRE_TESTING,
72         START_TESTING,
73         STOP_TESTING,
74         SAVED_TESTING
75     };
76 
77     private class VelocitySelectedListener implements OnItemSelectedListener {
78         @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)79         public void onItemSelected(AdapterView<?> parent, View view,
80                 int position, long id) {
81             String speedStr = parent.getItemAtPosition(position).toString();
82             int speedInt = Integer.parseInt(speedStr);
83             mWeb.setAutoScrollSpeed(speedInt);
84         }
85 
86         @Override
onNothingSelected(AdapterView<?> parent)87         public void onNothingSelected(AdapterView<?> parent) {
88         }
89     }
90 
91     private class MovementSelectedListener implements OnItemSelectedListener {
92         @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)93         public void onItemSelected(AdapterView<?> parent, View view,
94                 int position, long id) {
95             String movementStr = parent.getItemAtPosition(position).toString();
96             if (movementStr == getResources().getString(
97                     R.string.movement_auto_scroll)
98                     || movementStr == getResources().getString(
99                             R.string.movement_auto_fling)) {
100                 mWeb.setWebViewClient(mAutoLoggingWebViewClient);
101                 mCaptureButton.setEnabled(false);
102                 mVelocitySpinner.setEnabled(true);
103             } else if (movementStr == getResources().getString(
104                     R.string.movement_manual)) {
105                 mWeb.setWebViewClient(mLoggingWebViewClient);
106                 mCaptureButton.setEnabled(true);
107                 mVelocitySpinner.setEnabled(false);
108             }
109         }
110 
111         @Override
onNothingSelected(AdapterView<?> parent)112         public void onNothingSelected(AdapterView<?> parent) {
113         }
114     }
115 
116     private class LoggingWebViewClient extends WebViewClient {
117         @Override
shouldOverrideUrlLoading(WebView view, String url)118         public boolean shouldOverrideUrlLoading(WebView view, String url) {
119             return false;
120         }
121 
122         @Override
onPageStarted(WebView view, String url, Bitmap favicon)123         public void onPageStarted(WebView view, String url, Bitmap favicon) {
124             super.onPageStarted(view, url, favicon);
125             mUrl.setText(url);
126         }
127     }
128 
129     private class AutoLoggingWebViewClient extends LoggingWebViewClient {
130 
131         @Override
onPageFinished(WebView view, String url)132         public void onPageFinished(WebView view, String url) {
133             super.onPageFinished(view, url);
134             view.requestFocus();
135 
136             startViewProfiling(true);
137         }
138 
139         @Override
onPageStarted(WebView view, String url, Bitmap favicon)140         public void onPageStarted(WebView view, String url, Bitmap favicon) {
141             super.onPageStarted(view, url, favicon);
142             setTestingState(TestingState.PRE_TESTING);
143         }
144     }
145 
146     private class StoreFileTask extends
147             AsyncTask<Pair<String, RunData>, Void, Void> {
148 
149         @Override
doInBackground(Pair<String, RunData>.... params)150         protected Void doInBackground(Pair<String, RunData>... params) {
151             try {
152                 FileOutputStream fos = openFileOutput(params[0].first,
153                         Context.MODE_PRIVATE);
154                 ObjectOutputStream out = new ObjectOutputStream(fos);
155                 out.writeObject(params[0].second);
156                 out.close();
157             } catch (IOException ex) {
158                 ex.printStackTrace();
159             }
160             return null;
161         }
162 
163         @Override
onPostExecute(Void v)164         protected void onPostExecute(Void v) {
165             setTestingState(TestingState.SAVED_TESTING);
166         }
167     }
168 
setTestingState(TestingState state)169     public void setTestingState(TestingState state) {
170         switch (state) {
171             case NOT_TESTING:
172                 mUrl.setBackgroundResource(R.color.background_not_testing);
173                 mInspectButton.setEnabled(true);
174                 mMovementSpinner.setEnabled(true);
175                 break;
176             case PRE_TESTING:
177                 mInspectButton.setEnabled(false);
178                 mMovementSpinner.setEnabled(false);
179                 break;
180             case START_TESTING:
181                 mUrl.setBackgroundResource(R.color.background_start_testing);
182                 mInspectButton.setEnabled(false);
183                 mMovementSpinner.setEnabled(false);
184                 break;
185             case STOP_TESTING:
186                 mUrl.setBackgroundResource(R.color.background_stop_testing);
187                 break;
188             case SAVED_TESTING:
189                 mInspectButton.setEnabled(true);
190                 mMovementSpinner.setEnabled(true);
191                 break;
192         }
193     }
194 
195     /** auto - automatically scroll. */
startViewProfiling(boolean auto)196     private void startViewProfiling(boolean auto) {
197         // toggle capture button to indicate capture state to user
198         mCaptureButton.setChecked(true);
199         mWeb.startScrollTest(mCallback, auto);
200         setTestingState(TestingState.START_TESTING);
201     }
202 
203     /** Called when the activity is first created. */
204     @Override
onCreate(Bundle savedInstanceState)205     public void onCreate(Bundle savedInstanceState) {
206         super.onCreate(savedInstanceState);
207         setContentView(R.layout.main);
208         mInspectButton = (Button) findViewById(R.id.inspect);
209         mCaptureButton = (ToggleButton) findViewById(R.id.capture);
210         mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
211         mMovementSpinner = (Spinner) findViewById(R.id.movement);
212         mUrl = (EditText) findViewById(R.id.url);
213         mWeb = (ProfiledWebView) findViewById(R.id.web);
214         setCallback(new ProfileCallback() {
215             @SuppressWarnings("unchecked")
216             @Override
217             public void profileCallback(RunData data) {
218                 new StoreFileTask().execute(new Pair<String, RunData>(
219                         TEMP_FILENAME, data));
220                 mCaptureButton.setChecked(false);
221                 setTestingState(TestingState.STOP_TESTING);
222             }
223         });
224 
225         // Inspect button (opens PlaybackActivity)
226         mInspectButton.setOnClickListener(new OnClickListener() {
227             @Override
228             public void onClick(View v) {
229                 startActivity(new Intent(ProfileActivity.this,
230                         PlaybackActivity.class));
231             }
232         });
233 
234         // Velocity spinner
235         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
236                 this, R.array.velocity_array,
237                 android.R.layout.simple_spinner_item);
238         adapter.setDropDownViewResource(
239                 android.R.layout.simple_spinner_dropdown_item);
240         mVelocitySpinner.setAdapter(adapter);
241         mVelocitySpinner.setOnItemSelectedListener(
242                 new VelocitySelectedListener());
243         mVelocitySpinner.setSelection(3);
244 
245         // Movement spinner
246         String content[] = {
247                 getResources().getString(R.string.movement_auto_scroll),
248                 getResources().getString(R.string.movement_auto_fling),
249                 getResources().getString(R.string.movement_manual)
250         };
251         adapter = new ArrayAdapter<CharSequence>(this,
252                 android.R.layout.simple_spinner_item, content);
253         adapter.setDropDownViewResource(
254                 android.R.layout.simple_spinner_dropdown_item);
255         mMovementSpinner.setAdapter(adapter);
256         mMovementSpinner.setOnItemSelectedListener(
257                 new MovementSelectedListener());
258         mMovementSpinner.setSelection(0);
259 
260         // Capture toggle button
261         mCaptureButton.setOnClickListener(new OnClickListener() {
262             @Override
263             public void onClick(View v) {
264                 if (mCaptureButton.isChecked()) {
265                     startViewProfiling(false);
266                 } else {
267                     mWeb.stopScrollTest();
268                 }
269             }
270         });
271 
272         // Custom profiling WebView
273         WebSettings settings = mWeb.getSettings();
274         settings.setJavaScriptEnabled(true);
275         settings.setSupportZoom(true);
276         settings.setEnableSmoothTransition(true);
277         settings.setBuiltInZoomControls(true);
278         settings.setLoadWithOverviewMode(true);
279         mWeb.setWebViewClient(new LoggingWebViewClient());
280 
281         // URL text entry
282         mUrl.setOnEditorActionListener(new OnEditorActionListener() {
283             public boolean onEditorAction(TextView v, int actionId,
284                     KeyEvent event) {
285                 String url = mUrl.getText().toString();
286                 mWeb.loadUrl(url);
287                 mWeb.requestFocus();
288                 return true;
289             }
290         });
291 
292         setTestingState(TestingState.NOT_TESTING);
293     }
294 
setCallback(ProfileCallback callback)295     public void setCallback(ProfileCallback callback) {
296         mCallback = callback;
297     }
298 
299     @Override
onKeyDown(int keyCode, KeyEvent event)300     public boolean onKeyDown(int keyCode, KeyEvent event) {
301         if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
302             mWeb.goBack();
303             return true;
304         }
305         return super.onKeyDown(keyCode, event);
306     }
307 }
308