ReliabilityTestActivity.java revision 65455a1a46e3bec020befd27ff5ad6bfdab61a7d
1package com.android.dumprendertree; 2 3import android.app.Activity; 4import android.app.ActivityThread; 5import android.graphics.Bitmap; 6import android.net.http.SslError; 7import android.os.Bundle; 8import android.os.Handler; 9import android.os.Message; 10import android.util.Log; 11import android.view.ViewGroup; 12import android.webkit.HttpAuthHandler; 13import android.webkit.JsPromptResult; 14import android.webkit.JsResult; 15import android.webkit.SslErrorHandler; 16import android.webkit.WebChromeClient; 17import android.webkit.WebView; 18import android.webkit.WebViewClient; 19import android.webkit.WebSettings.LayoutAlgorithm; 20import android.widget.LinearLayout; 21import android.widget.LinearLayout.LayoutParams; 22 23public class ReliabilityTestActivity extends Activity { 24 25 public static final String TEST_URL_ACTION = "com.andrdoid.dumprendertree.TestUrlAction"; 26 public static final String PARAM_URL = "URL"; 27 public static final String PARAM_TIMEOUT = "Timeout"; 28 public static final int RESULT_TIMEOUT = 0xDEAD; 29 public static final int MSG_TIMEOUT = 0xC001; 30 public static final int MSG_NAVIGATE = 0xC002; 31 32 private static final String LOGTAG = "ReliabilityTestActivity"; 33 34 private WebView webView; 35 private SimpleWebViewClient webViewClient; 36 private SimpleChromeClient chromeClient; 37 private Handler handler; 38 private boolean timeoutFlag; 39 private boolean pageDone; 40 private Object pageDoneLock; 41 private int pageStartCount; 42 43 @Override 44 protected void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 47 Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode())); 48 49 LinearLayout contentView = new LinearLayout(this); 50 contentView.setOrientation(LinearLayout.VERTICAL); 51 setContentView(contentView); 52 setTitle("Idle"); 53 54 webView = new WebView(this); 55 webView.getSettings().setJavaScriptEnabled(true); 56 webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false); 57 webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL); 58 59 webViewClient = new SimpleWebViewClient(); 60 chromeClient = new SimpleChromeClient(); 61 webView.setWebViewClient(webViewClient); 62 webView.setWebChromeClient(chromeClient); 63 64 contentView.addView(webView, new LayoutParams( 65 ViewGroup.LayoutParams.FILL_PARENT, 66 ViewGroup.LayoutParams.FILL_PARENT, 0.0f)); 67 68 handler = new Handler() { 69 @Override 70 public void handleMessage(Message msg) { 71 switch (msg.what) { 72 case MSG_TIMEOUT: 73 handleTimeout(); 74 return; 75 case MSG_NAVIGATE: 76 navigate((String)msg.obj, msg.arg1); 77 return; 78 } 79 } 80 }; 81 82 pageDoneLock = new Object(); 83 } 84 85 public void reset() { 86 synchronized (pageDoneLock) { 87 pageDone = false; 88 } 89 timeoutFlag = false; 90 pageStartCount = 0; 91 chromeClient.resetJsTimeout(); 92 } 93 94 private void navigate(String url, int timeout) { 95 if(url == null) { 96 Log.v(LOGTAG, "URL is null, cancelling..."); 97 finish(); 98 } 99 webView.stopLoading(); 100 Log.v(LOGTAG, "Navigating to URL: " + url); 101 webView.loadUrl(url); 102 103 if(timeout != 0) { 104 //set a timer with specified timeout (in ms) 105 handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT), 106 timeout); 107 } 108 } 109 110 @Override 111 protected void onDestroy() { 112 Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); 113 super.onDestroy(); 114 } 115 116 private boolean isPageDone() { 117 synchronized (pageDoneLock) { 118 return pageDone; 119 } 120 } 121 122 private void setPageDone(boolean pageDone) { 123 synchronized (pageDoneLock) { 124 this.pageDone = pageDone; 125 pageDoneLock.notifyAll(); 126 } 127 } 128 129 private void handleTimeout() { 130 int progress = webView.getProgress(); 131 webView.stopLoading(); 132 Log.v(LOGTAG, "Page timeout triggered, progress = " + progress); 133 timeoutFlag = true; 134 } 135 136 public boolean waitUntilDone() { 137 validateNotAppThread(); 138 synchronized (pageDoneLock) { 139 while(!isPageDone()) { 140 try { 141 pageDoneLock.wait(); 142 } catch (InterruptedException ie) { 143 //no-op 144 } 145 } 146 } 147 return timeoutFlag; 148 } 149 150 public Handler getHandler() { 151 return handler; 152 } 153 154 private final void validateNotAppThread() { 155 if (ActivityThread.currentActivityThread() != null) { 156 throw new RuntimeException( 157 "This method can not be called from the main application thread"); 158 } 159 } 160 161 class SimpleWebViewClient extends WebViewClient { 162 163 @Override 164 public void onReceivedError(WebView view, int errorCode, String description, 165 String failingUrl) { 166 Log.v(LOGTAG, "Received WebCore error: code=" + errorCode 167 + ", description=" + description 168 + ", url=" + failingUrl); 169 } 170 171 @Override 172 public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { 173 //ignore certificate error 174 Log.v(LOGTAG, "Received SSL error: " + error.toString()); 175 handler.proceed(); 176 } 177 178 @Override 179 public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, 180 String realm) { 181 //cancel http auth request 182 handler.cancel(); 183 } 184 185 @Override 186 public void onPageStarted(WebView view, String url, Bitmap favicon) { 187 pageStartCount++; 188 Log.v(LOGTAG, "onPageStarted: " + url); 189 } 190 191 @Override 192 public void onPageFinished(WebView view, String url) { 193 Log.v(LOGTAG, "onPageFinished: " + url); 194 handler.postDelayed(new WebViewStatusChecker(), 500); 195 } 196 } 197 198 class SimpleChromeClient extends WebChromeClient { 199 200 private int timeoutCounter = 0; 201 202 @Override 203 public boolean onJsAlert(WebView view, String url, String message, JsResult result) { 204 result.confirm(); 205 return true; 206 } 207 208 @Override 209 public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) { 210 result.confirm(); 211 return true; 212 } 213 214 @Override 215 public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, 216 JsPromptResult result) { 217 result.confirm(); 218 return true; 219 } 220 221 @Override 222 public boolean onJsTimeout() { 223 timeoutCounter++; 224 Log.v(LOGTAG, "JavaScript timeout, count=" + timeoutCounter); 225 return timeoutCounter > 2; 226 } 227 228 public void resetJsTimeout() { 229 timeoutCounter = 0; 230 } 231 232 @Override 233 public void onReceivedTitle(WebView view, String title) { 234 ReliabilityTestActivity.this.setTitle(title); 235 } 236 } 237 238 class WebViewStatusChecker implements Runnable { 239 240 private int initialStartCount; 241 242 public WebViewStatusChecker() { 243 initialStartCount = pageStartCount; 244 } 245 246 @Override 247 public void run() { 248 if (initialStartCount == pageStartCount) { 249 //perform cleanup 250 webView.stopLoading(); 251 Log.v(LOGTAG, "Finishing URL: " + webView.getUrl()); 252 handler.removeMessages(MSG_TIMEOUT); 253 setPageDone(true); 254 } 255 } 256 } 257} 258