blob: 404d1012c7dd7c767dcdd9d84da76bce7296b038 [file] [log] [blame]
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -07001/*
2 * Copyright (C) 2007 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
17package com.android.dumprendertree;
18
19import java.io.File;
20import java.io.FileOutputStream;
21import java.io.IOException;
22import java.util.Vector;
23
24import android.app.Activity;
25import android.content.Intent;
26import android.util.Log;
27import android.webkit.JsPromptResult;
28import android.webkit.JsResult;
29import android.view.ViewGroup;
30import android.webkit.WebChromeClient;
31import android.webkit.WebSettings;
32import android.webkit.WebView;
33import android.widget.LinearLayout;
34import android.os.*;
35
36public class TestShellActivity extends Activity implements LayoutTestController {
37 public class AsyncHandler extends Handler {
38 @Override
39 public void handleMessage(Message msg) {
40 if (msg.what == MSG_TIMEOUT) {
41 mTimedOut = true;
42 requestWebKitData();
43 return;
44 } else if (msg.what == MSG_WEBKIT_DATA) {
45 TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
46 return;
47 }
48
49 super.handleMessage(msg);
50 }
51 }
52
53 public void requestWebKitData() {
54 Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);
55
56 if (mRequestedWebKitData)
57 throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());
58
59 mRequestedWebKitData = true;
60 if (mDumpAsText) {
61 mWebView.documentAsText(callback);
62 } else {
63 mWebView.externalRepresentation(callback);
64 }
65 }
66
67 @Override
68 protected void onCreate(Bundle icicle) {
69 super.onCreate(icicle);
70
71 LinearLayout contentView = new LinearLayout(this);
72 contentView.setOrientation(LinearLayout.VERTICAL);
73 setContentView(contentView);
74
75 mWebView = new WebView(this);
76 mWebView.getSettings().setJavaScriptEnabled(true);
77 mWebView.setWebChromeClient(mChromeClient);
78 mEventSender = new WebViewEventSender(mWebView);
79 mCallbackProxy = new CallbackProxy(mEventSender, this);
80
81 mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController");
82 mWebView.addJavascriptInterface(mCallbackProxy, "eventSender");
83 contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
84
85 mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
86
87 mHandler = new AsyncHandler();
88
89 Intent intent = getIntent();
90 if (intent != null) {
91 executeIntent(intent);
92 }
93 }
94
95 @Override
96 protected void onNewIntent(Intent intent) {
97 super.onNewIntent(intent);
98 executeIntent(intent);
99 }
100
101 private void executeIntent(Intent intent) {
102 resetTestStatus();
103 if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
104 return;
105 }
106
107 mTestUrl = intent.getStringExtra(TEST_URL);
108 if (mTestUrl == null)
109 return;
110
111 mResultFile = intent.getStringExtra(RESULT_FILE);
112 mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
113
114 Log.v(LOGTAG, " Loading " + mTestUrl);
115 mWebView.loadUrl(mTestUrl);
116
117 if (mTimeoutInMillis > 0) {
118 // Create a timeout timer
119 Message m = mHandler.obtainMessage(MSG_TIMEOUT);
120 mHandler.sendMessageDelayed(m, mTimeoutInMillis);
121 }
122 }
123
124 @Override
125 protected void onStop() {
126 super.onStop();
127 mWebView.stopLoading();
128 }
129
130 @Override
131 protected void onDestroy() {
132 super.onDestroy();
133 mWebView.destroy();
134 mWebView = null;
135 }
136
137 @Override
138 public void onLowMemory() {
139 super.onLowMemory();
140 Log.e(LOGTAG, "Low memory, kill self");
141 System.exit(1);
142 }
143
144 // Dump the page
145 public void dump(boolean timeout, String webkitData) {
146 if (mResultFile == null || mResultFile.length() == 0) {
147 finished();
148 return;
149 }
150
151 try {
152 File parentDir = new File(mResultFile).getParentFile();
153 if (!parentDir.exists()) {
154 parentDir.mkdirs();
155 }
156
157 FileOutputStream os = new FileOutputStream(mResultFile);
158 if (timeout) {
159 Log.w("Layout test: Timeout", mResultFile);
160 os.write(TIMEOUT_STR.getBytes());
161 os.write('\n');
162 }
163 if (mDumpTitleChanges)
164 os.write(mTitleChanges.toString().getBytes());
165 if (mDialogStrings != null)
166 os.write(mDialogStrings.toString().getBytes());
167 mDialogStrings = null;
Feng Qianbe42388b2009-04-16 10:05:38 -0700168 if (webkitData != null)
169 os.write(webkitData.getBytes());
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700170 os.flush();
171 os.close();
172 } catch (IOException ex) {
173 Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage());
174 }
175
176 finished();
177 }
178
179 public void setCallback(TestShellCallback callback) {
180 mCallback = callback;
181 }
182
183 public void finished() {
184 if (mCallback != null) {
185 mCallback.finished();
186 }
187 }
188
189 // .......................................
190 // LayoutTestController Functions
191 public void dumpAsText() {
192 mDumpAsText = true;
193 if (mWebView != null) {
194 String url = mWebView.getUrl();
195 Log.v(LOGTAG, "dumpAsText called: "+url);
196 }
197 }
198
199 public void waitUntilDone() {
200 mWaitUntilDone = true;
201 String url = mWebView.getUrl();
202 Log.v(LOGTAG, "waitUntilDone called: " + url);
203 }
204
205 public void notifyDone() {
206 String url = mWebView.getUrl();
207 Log.v(LOGTAG, "notifyDone called: " + url);
208 if (mWaitUntilDone) {
209 mWaitUntilDone = false;
210 mChromeClient.onProgressChanged(mWebView, 100);
211 }
212 }
213
214 public void display() {
215 mWebView.invalidate();
216 }
217
218 public void clearBackForwardList() {
219 mWebView.clearHistory();
220
221 }
222
223 public void dumpBackForwardList() {
224 //printf("\n============== Back Forward List ==============\n");
225 // mWebHistory
226 //printf("===============================================\n");
227
228 }
229
230 public void dumpChildFrameScrollPositions() {
231 // TODO Auto-generated method stub
232
233 }
234
235 public void dumpEditingCallbacks() {
236 // TODO Auto-generated method stub
237
238 }
239
240 public void dumpSelectionRect() {
241 // TODO Auto-generated method stub
242
243 }
244
245 public void dumpTitleChanges() {
246 if (!mDumpTitleChanges) {
247 mTitleChanges = new StringBuffer();
248 }
249 mDumpTitleChanges = true;
250 }
251
252 public void keepWebHistory() {
253 if (!mKeepWebHistory) {
254 mWebHistory = new Vector();
255 }
256 mKeepWebHistory = true;
257 }
258
259 public void queueBackNavigation(int howfar) {
260 // TODO Auto-generated method stub
261
262 }
263
264 public void queueForwardNavigation(int howfar) {
265 // TODO Auto-generated method stub
266
267 }
268
269 public void queueLoad(String Url, String frameTarget) {
270 // TODO Auto-generated method stub
271
272 }
273
274 public void queueReload() {
275 mWebView.reload();
276 }
277
278 public void queueScript(String scriptToRunInCurrentContext) {
279 mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
280 }
281
282 public void repaintSweepHorizontally() {
283 // TODO Auto-generated method stub
284
285 }
286
287 public void setAcceptsEditing(boolean b) {
288 // TODO Auto-generated method stub
289
290 }
291
292 public void setMainFrameIsFirstResponder(boolean b) {
293 // TODO Auto-generated method stub
294
295 }
296
297 public void setWindowIsKey(boolean b) {
298 // This is meant to show/hide the window. The best I can find
299 // is setEnabled()
300 mWebView.setEnabled(b);
301 }
302
303 public void testRepaint() {
304 mWebView.invalidate();
305 }
306
307 private final WebChromeClient mChromeClient = new WebChromeClient() {
308 @Override
309 public void onProgressChanged(WebView view, int newProgress) {
310 if (newProgress == 100) {
311 if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) {
312 String url = mWebView.getUrl();
313 Log.v(LOGTAG, "Finished: "+ url);
314 mHandler.removeMessages(MSG_TIMEOUT);
315 requestWebKitData();
316 } else {
317 String url = mWebView.getUrl();
318 if (mTimedOut) {
319 Log.v(LOGTAG, "Timed out before finishing: " + url);
320 } else if (mWaitUntilDone) {
321 Log.v(LOGTAG, "Waiting for notifyDone: " + url);
322 } else if (mRequestedWebKitData) {
323 Log.v(LOGTAG, "Requested webkit data ready: " + url);
324 }
325 }
326 }
327 }
328
329 @Override
330 public void onReceivedTitle(WebView view, String title) {
331 if (title.length() > 30)
332 title = "..."+title.substring(title.length()-30);
333 setTitle(title);
334 if (mDumpTitleChanges) {
335 mTitleChanges.append("TITLE CHANGED: ");
336 mTitleChanges.append(title);
337 mTitleChanges.append("\n");
338 }
339 }
340
341 @Override
342 public boolean onJsAlert(WebView view, String url, String message,
343 JsResult result) {
344 if (mDialogStrings == null) {
345 mDialogStrings = new StringBuffer();
346 }
347 mDialogStrings.append("ALERT: ");
348 mDialogStrings.append(message);
349 mDialogStrings.append('\n');
350 result.confirm();
351 return true;
352 }
353
354 @Override
355 public boolean onJsConfirm(WebView view, String url, String message,
356 JsResult result) {
357 if (mDialogStrings == null) {
358 mDialogStrings = new StringBuffer();
359 }
360 mDialogStrings.append("CONFIRM: ");
361 mDialogStrings.append(message);
362 mDialogStrings.append('\n');
363 result.confirm();
364 return true;
365 }
366
367 @Override
368 public boolean onJsPrompt(WebView view, String url, String message,
369 String defaultValue, JsPromptResult result) {
370 if (mDialogStrings == null) {
371 mDialogStrings = new StringBuffer();
372 }
373 mDialogStrings.append("PROMPT: ");
374 mDialogStrings.append(message);
375 mDialogStrings.append(", default text: ");
376 mDialogStrings.append(defaultValue);
377 mDialogStrings.append('\n');
378 result.confirm();
379 return true;
380 }
381 };
382
383 private void resetTestStatus() {
384 mWaitUntilDone = false;
385 mDumpAsText = false;
386 mTimedOut = false;
387 mDumpTitleChanges = false;
388 mRequestedWebKitData = false;
389 mEventSender.resetMouse();
390 }
391
392 private WebView mWebView;
393 private WebViewEventSender mEventSender;
394 private AsyncHandler mHandler;
395 private TestShellCallback mCallback;
396
397 private CallbackProxy mCallbackProxy;
398
399 private String mTestUrl;
400 private String mResultFile;
401 private int mTimeoutInMillis;
402
403 // States
404 private boolean mTimedOut;
405 private boolean mRequestedWebKitData;
406 private boolean mFinishedRunning;
407
408 // Layout test controller variables.
409 private boolean mDumpAsText;
410 private boolean mWaitUntilDone;
411 private boolean mDumpTitleChanges;
412 private StringBuffer mTitleChanges;
413 private StringBuffer mDialogStrings;
414 private boolean mKeepWebHistory;
415 private Vector mWebHistory;
416
417 static final String TIMEOUT_STR = "**Test timeout";
418
419 static final int MSG_TIMEOUT = 0;
420 static final int MSG_WEBKIT_DATA = 1;
421
422 static final String LOGTAG="TestShell";
423
424 static final String TEST_URL = "TestUrl";
425 static final String RESULT_FILE = "ResultFile";
426 static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
427}