TestShellActivity.java revision ba87e3e6c985e7175152993b5efcc7dd2f0e1c93
1/* 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; 168 os.write(webkitData.getBytes()); 169 os.flush(); 170 os.close(); 171 } catch (IOException ex) { 172 Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage()); 173 } 174 175 finished(); 176 } 177 178 public void setCallback(TestShellCallback callback) { 179 mCallback = callback; 180 } 181 182 public void finished() { 183 if (mCallback != null) { 184 mCallback.finished(); 185 } 186 } 187 188 // ....................................... 189 // LayoutTestController Functions 190 public void dumpAsText() { 191 mDumpAsText = true; 192 if (mWebView != null) { 193 String url = mWebView.getUrl(); 194 Log.v(LOGTAG, "dumpAsText called: "+url); 195 } 196 } 197 198 public void waitUntilDone() { 199 mWaitUntilDone = true; 200 String url = mWebView.getUrl(); 201 Log.v(LOGTAG, "waitUntilDone called: " + url); 202 } 203 204 public void notifyDone() { 205 String url = mWebView.getUrl(); 206 Log.v(LOGTAG, "notifyDone called: " + url); 207 if (mWaitUntilDone) { 208 mWaitUntilDone = false; 209 mChromeClient.onProgressChanged(mWebView, 100); 210 } 211 } 212 213 public void display() { 214 mWebView.invalidate(); 215 } 216 217 public void clearBackForwardList() { 218 mWebView.clearHistory(); 219 220 } 221 222 public void dumpBackForwardList() { 223 //printf("\n============== Back Forward List ==============\n"); 224 // mWebHistory 225 //printf("===============================================\n"); 226 227 } 228 229 public void dumpChildFrameScrollPositions() { 230 // TODO Auto-generated method stub 231 232 } 233 234 public void dumpEditingCallbacks() { 235 // TODO Auto-generated method stub 236 237 } 238 239 public void dumpSelectionRect() { 240 // TODO Auto-generated method stub 241 242 } 243 244 public void dumpTitleChanges() { 245 if (!mDumpTitleChanges) { 246 mTitleChanges = new StringBuffer(); 247 } 248 mDumpTitleChanges = true; 249 } 250 251 public void keepWebHistory() { 252 if (!mKeepWebHistory) { 253 mWebHistory = new Vector(); 254 } 255 mKeepWebHistory = true; 256 } 257 258 public void queueBackNavigation(int howfar) { 259 // TODO Auto-generated method stub 260 261 } 262 263 public void queueForwardNavigation(int howfar) { 264 // TODO Auto-generated method stub 265 266 } 267 268 public void queueLoad(String Url, String frameTarget) { 269 // TODO Auto-generated method stub 270 271 } 272 273 public void queueReload() { 274 mWebView.reload(); 275 } 276 277 public void queueScript(String scriptToRunInCurrentContext) { 278 mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext); 279 } 280 281 public void repaintSweepHorizontally() { 282 // TODO Auto-generated method stub 283 284 } 285 286 public void setAcceptsEditing(boolean b) { 287 // TODO Auto-generated method stub 288 289 } 290 291 public void setMainFrameIsFirstResponder(boolean b) { 292 // TODO Auto-generated method stub 293 294 } 295 296 public void setWindowIsKey(boolean b) { 297 // This is meant to show/hide the window. The best I can find 298 // is setEnabled() 299 mWebView.setEnabled(b); 300 } 301 302 public void testRepaint() { 303 mWebView.invalidate(); 304 } 305 306 private final WebChromeClient mChromeClient = new WebChromeClient() { 307 @Override 308 public void onProgressChanged(WebView view, int newProgress) { 309 if (newProgress == 100) { 310 if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) { 311 String url = mWebView.getUrl(); 312 Log.v(LOGTAG, "Finished: "+ url); 313 mHandler.removeMessages(MSG_TIMEOUT); 314 requestWebKitData(); 315 } else { 316 String url = mWebView.getUrl(); 317 if (mTimedOut) { 318 Log.v(LOGTAG, "Timed out before finishing: " + url); 319 } else if (mWaitUntilDone) { 320 Log.v(LOGTAG, "Waiting for notifyDone: " + url); 321 } else if (mRequestedWebKitData) { 322 Log.v(LOGTAG, "Requested webkit data ready: " + url); 323 } 324 } 325 } 326 } 327 328 @Override 329 public void onReceivedTitle(WebView view, String title) { 330 if (title.length() > 30) 331 title = "..."+title.substring(title.length()-30); 332 setTitle(title); 333 if (mDumpTitleChanges) { 334 mTitleChanges.append("TITLE CHANGED: "); 335 mTitleChanges.append(title); 336 mTitleChanges.append("\n"); 337 } 338 } 339 340 @Override 341 public boolean onJsAlert(WebView view, String url, String message, 342 JsResult result) { 343 if (mDialogStrings == null) { 344 mDialogStrings = new StringBuffer(); 345 } 346 mDialogStrings.append("ALERT: "); 347 mDialogStrings.append(message); 348 mDialogStrings.append('\n'); 349 result.confirm(); 350 return true; 351 } 352 353 @Override 354 public boolean onJsConfirm(WebView view, String url, String message, 355 JsResult result) { 356 if (mDialogStrings == null) { 357 mDialogStrings = new StringBuffer(); 358 } 359 mDialogStrings.append("CONFIRM: "); 360 mDialogStrings.append(message); 361 mDialogStrings.append('\n'); 362 result.confirm(); 363 return true; 364 } 365 366 @Override 367 public boolean onJsPrompt(WebView view, String url, String message, 368 String defaultValue, JsPromptResult result) { 369 if (mDialogStrings == null) { 370 mDialogStrings = new StringBuffer(); 371 } 372 mDialogStrings.append("PROMPT: "); 373 mDialogStrings.append(message); 374 mDialogStrings.append(", default text: "); 375 mDialogStrings.append(defaultValue); 376 mDialogStrings.append('\n'); 377 result.confirm(); 378 return true; 379 } 380 }; 381 382 private void resetTestStatus() { 383 mWaitUntilDone = false; 384 mDumpAsText = false; 385 mTimedOut = false; 386 mDumpTitleChanges = false; 387 mRequestedWebKitData = false; 388 mEventSender.resetMouse(); 389 } 390 391 private WebView mWebView; 392 private WebViewEventSender mEventSender; 393 private AsyncHandler mHandler; 394 private TestShellCallback mCallback; 395 396 private CallbackProxy mCallbackProxy; 397 398 private String mTestUrl; 399 private String mResultFile; 400 private int mTimeoutInMillis; 401 402 // States 403 private boolean mTimedOut; 404 private boolean mRequestedWebKitData; 405 private boolean mFinishedRunning; 406 407 // Layout test controller variables. 408 private boolean mDumpAsText; 409 private boolean mWaitUntilDone; 410 private boolean mDumpTitleChanges; 411 private StringBuffer mTitleChanges; 412 private StringBuffer mDialogStrings; 413 private boolean mKeepWebHistory; 414 private Vector mWebHistory; 415 416 static final String TIMEOUT_STR = "**Test timeout"; 417 418 static final int MSG_TIMEOUT = 0; 419 static final int MSG_WEBKIT_DATA = 1; 420 421 static final String LOGTAG="TestShell"; 422 423 static final String TEST_URL = "TestUrl"; 424 static final String RESULT_FILE = "ResultFile"; 425 static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis"; 426} 427