diff options
author | Xia Wang <xiaw@google.com> | 2009-09-02 17:52:24 -0700 |
---|---|---|
committer | Xia Wang <xiaw@google.com> | 2009-09-02 20:59:37 -0700 |
commit | 7c6efa13f129dbae5319f0981a430d4662f43354 (patch) | |
tree | c0353eedab622c39251cb2b29d6195fb09cf9771 /tests/BrowserPowerTest/src | |
parent | 04e1faf0f030ddb360180289fb798adbb3348dd4 (diff) | |
download | frameworks_base-7c6efa13f129dbae5319f0981a430d4662f43354.zip frameworks_base-7c6efa13f129dbae5319f0981a430d4662f43354.tar.gz frameworks_base-7c6efa13f129dbae5319f0981a430d4662f43354.tar.bz2 |
Add a test case to measure the power usage of loading a web page
Diffstat (limited to 'tests/BrowserPowerTest/src')
3 files changed, 335 insertions, 0 deletions
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java new file mode 100644 index 0000000..74ac865 --- /dev/null +++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java @@ -0,0 +1,51 @@ +package com.android.browserpowertest; + +import android.content.Intent; +import android.app.Instrumentation; +import android.os.Handler; +import android.os.Message; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; +import junit.framework.*; + +public class PowerMeasurement extends ActivityInstrumentationTestCase2<PowerTestActivity> { + + private static final String LOGTAG = "PowerMeasurement"; + private static final String PKG_NAME = "com.android.browserpowertest"; + private static final String TESTING_URL = "http://www.espn.com"; + private static final int TIME_OUT = 2 * 60 * 1000; + private static final int DELAY = 0; + + public PowerMeasurement() { + super(PKG_NAME, PowerTestActivity.class); + } + + public void testPageLoad() throws Throwable { + Instrumentation mInst = getInstrumentation(); + PowerTestActivity act = getActivity(); + + Intent intent = new Intent(mInst.getContext(), PowerTestActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + long start = System.currentTimeMillis(); + PowerTestActivity activity = (PowerTestActivity)mInst.startActivitySync( + intent); + activity.reset(); + //send a message with the new URL + Handler handler = activity.getHandler(); + Message msg = handler.obtainMessage( + PowerTestActivity.MSG_NAVIGATE, TIME_OUT, DELAY); + msg.getData().putString(PowerTestActivity.MSG_NAV_URL, TESTING_URL); + msg.getData().putBoolean(PowerTestActivity.MSG_NAV_LOGTIME, true); + + handler.sendMessage(msg); + boolean timeoutFlag = activity.waitUntilDone(); + long end = System.currentTimeMillis(); + assertFalse(TESTING_URL + " failed to load", timeoutFlag); + boolean pageErrorFlag = activity.getPageError(); + assertFalse(TESTING_URL + " is not available, either network is down or the server is down", + pageErrorFlag); + Log.v(LOGTAG, "Page is loaded in " + activity.getPageLoadTime() + " ms."); + + activity.finish(); + } +} diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java new file mode 100644 index 0000000..77e390b --- /dev/null +++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java @@ -0,0 +1,253 @@ +package com.android.browserpowertest; + +import android.app.Activity; +import android.app.ActivityThread; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.ViewGroup; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.webkit.WebSettings.LayoutAlgorithm; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; + +public class PowerTestActivity extends Activity { + + public static final String LOGTAG = "PowerTestActivity"; + public static final String PARAM_URL = "URL"; + public static final String PARAM_TIMEOUT = "Timeout"; + public static final int RESULT_TIMEOUT = 0xDEAD; + public static final int MSG_TIMEOUT = 0xC001; + public static final int MSG_NAVIGATE = 0xC002; + public static final String MSG_NAV_URL = "url"; + public static final String MSG_NAV_LOGTIME = "logtime"; + + private WebView webView; + private SimpleWebViewClient webViewClient; + private SimpleChromeClient chromeClient; + private Handler handler; + private boolean timeoutFlag; + private boolean logTime; + private boolean pageDone; + private Object pageDoneLock; + private int pageStartCount; + private int manualDelay; + private long startTime; + private long pageLoadTime; + private PageDoneRunner pageDoneRunner = new PageDoneRunner(); + + public PowerTestActivity() { + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode())); + + LinearLayout contentView = new LinearLayout(this); + contentView.setOrientation(LinearLayout.VERTICAL); + setContentView(contentView); + setTitle("Idle"); + + webView = new WebView(this); + webView.getSettings().setJavaScriptEnabled(true); + webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false); + webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL); + + webViewClient = new SimpleWebViewClient(); + chromeClient = new SimpleChromeClient(); + webView.setWebViewClient(webViewClient); + webView.setWebChromeClient(chromeClient); + + contentView.addView(webView, new LayoutParams( + ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT, 0.0f)); + + handler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_TIMEOUT: + handleTimeout(); + return; + case MSG_NAVIGATE: + manualDelay = msg.arg2; + navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1); + logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME); + return; + } + } + }; + + pageDoneLock = new Object(); + } + + public void reset() { + synchronized (pageDoneLock) { + pageDone = false; + } + timeoutFlag = false; + pageStartCount = 0; + chromeClient.resetJsTimeout(); + } + + private void navigate(String url, int timeout) { + if(url == null) { + Log.v(LOGTAG, "URL is null, cancelling..."); + finish(); + } + webView.stopLoading(); + if(logTime) { + webView.clearCache(true); + } + startTime = System.currentTimeMillis(); + Log.v(LOGTAG, "Navigating to URL: " + url); + webView.loadUrl(url); + + if(timeout != 0) { + //set a timer with specified timeout (in ms) + handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT), + timeout); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); + webView.clearCache(true); + webView.destroy(); + } + + private boolean isPageDone() { + synchronized (pageDoneLock) { + return pageDone; + } + } + + private void setPageDone(boolean pageDone) { + synchronized (pageDoneLock) { + this.pageDone = pageDone; + pageDoneLock.notifyAll(); + } + } + + private void handleTimeout() { + int progress = webView.getProgress(); + webView.stopLoading(); + Log.v(LOGTAG, "Page timeout triggered, progress = " + progress); + timeoutFlag = true; + handler.postDelayed(pageDoneRunner, manualDelay); + } + + public boolean waitUntilDone() { + validateNotAppThread(); + synchronized (pageDoneLock) { + while(!isPageDone()) { + try { + pageDoneLock.wait(); + } catch (InterruptedException ie) { + //no-op + } + } + } + return timeoutFlag; + } + + public Handler getHandler() { + return handler; + } + + private final void validateNotAppThread() { + if (ActivityThread.currentActivityThread() != null) { + throw new RuntimeException( + "This method can not be called from the main application thread"); + } + } + + public long getPageLoadTime() { + return pageLoadTime; + } + + public boolean getPageError() { + return webViewClient.getPageErrorFlag(); + } + + class SimpleWebViewClient extends WebViewClient { + + private boolean pageErrorFlag = false; + + @Override + public void onReceivedError(WebView view, int errorCode, String description, + String failingUrl) { + pageErrorFlag = true; + Log.v(LOGTAG, "WebCore error: code=" + errorCode + + ", description=" + description + + ", url=" + failingUrl); + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + pageStartCount++; + Log.v(LOGTAG, "onPageStarted: " + url); + } + + @Override + public void onPageFinished(WebView view, String url) { + Log.v(LOGTAG, "onPageFinished: " + url); + // let handleTimeout take care of finishing the page + if(!timeoutFlag) + handler.postDelayed(new WebViewStatusChecker(), 500); + } + + // return true if the URL is not available or the page is down + public boolean getPageErrorFlag() { + return pageErrorFlag; + } + } + + class SimpleChromeClient extends WebChromeClient { + + private int timeoutCounter = 0; + + public void resetJsTimeout() { + timeoutCounter = 0; + } + + @Override + public void onReceivedTitle(WebView view, String title) { + PowerTestActivity.this.setTitle(title); + } + } + + class WebViewStatusChecker implements Runnable { + + private int initialStartCount; + + public WebViewStatusChecker() { + initialStartCount = pageStartCount; + } + + public void run() { + if (initialStartCount == pageStartCount && !isPageDone()) { + handler.removeMessages(MSG_TIMEOUT); + webView.stopLoading(); + handler.postDelayed(pageDoneRunner, manualDelay); + } + } + } + + class PageDoneRunner implements Runnable { + + public void run() { + Log.v(LOGTAG, "Finishing URL: " + webView.getUrl()); + pageLoadTime = System.currentTimeMillis() - startTime; + setPageDone(true); + } + } +} diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java new file mode 100644 index 0000000..4857209 --- /dev/null +++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java @@ -0,0 +1,31 @@ +package com.android.browserpowertest; + +import android.test.InstrumentationTestRunner; +import android.test.InstrumentationTestSuite; + +import junit.framework.TestSuite; + + +/** + * Instrumentation Test Runner for all browser power tests. + * + * Running power tests: + * + * adb shell am instrument \ + * -w com.android.browserpowertest/.PowerTestRunner + */ + +public class PowerTestRunner extends InstrumentationTestRunner { + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(PowerMeasurement.class); + return suite; + } + + @Override + public ClassLoader getLoader() { + return PowerTestRunner.class.getClassLoader(); + } + +} |