diff options
author | Maksymilian Osowski <maxosowski@google.com> | 2010-08-03 07:57:43 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-08-03 07:57:43 -0700 |
commit | fb60226a03d1d4c65b7e26268611b97371b25507 (patch) | |
tree | 61d1f410a547b05bdde3ffb641900f2e6fd13acd /tests | |
parent | 7768e02973f65d347f4457583e05c82810bd5cb8 (diff) | |
parent | dd4bff62b54033bedc254f517397ae8f954d0dc9 (diff) | |
download | frameworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.zip frameworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.tar.gz frameworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.tar.bz2 |
Merge "First batch of layoutTestController functions + some fixes and tweaks."
Diffstat (limited to 'tests')
6 files changed, 380 insertions, 15 deletions
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java index a8c1f4c..d68930c 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java @@ -26,6 +26,8 @@ import android.webkit.WebView; */ public abstract class AbstractResult implements Comparable<AbstractResult> { + private static final String LOG_TAG = "AbstractResult"; + public enum TestType { TEXT { @Override @@ -63,10 +65,20 @@ public abstract class AbstractResult implements Comparable<AbstractResult> { } } + String mAdditionalTextOutputString; + public int compareTo(AbstractResult another) { return getRelativePath().compareTo(another.getRelativePath()); } + public void setAdditionalTextOutputString(String additionalTextOutputString) { + mAdditionalTextOutputString = additionalTextOutputString; + } + + public String getAdditionalTextOutputString() { + return mAdditionalTextOutputString; + } + /** * Makes the result object obtain the results of the test from the webview * and store them in the format that suits itself bests. This method is asynchronous. diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java new file mode 100644 index 0000000..4e4d824 --- /dev/null +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dumprendertree2; + +import android.util.Log; +import android.webkit.ConsoleMessage; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * A class that stores consoles messages, database callbacks, alert messages, etc. + */ +public class AdditionalTextOutput { + private static final String LOG_TAG = "AdditionalTextOutput"; + + private enum OutputType { + EXCEEDED_DB_QUOTA_MESSAGE, + CONSOLE_MESSAGE; + } + + StringBuilder[] mOutputs = new StringBuilder[OutputType.values().length]; + + public void appendExceededDbQuotaMessage(String urlString, String databaseIdentifier) { + int index = OutputType.EXCEEDED_DB_QUOTA_MESSAGE.ordinal(); + if (mOutputs[index] == null) { + mOutputs[index] = new StringBuilder(); + } + + String protocol = ""; + String host = ""; + int port = 0; + + try { + URL url = new URL(urlString); + protocol = url.getProtocol(); + host = url.getHost(); + if (url.getPort() > -1) { + port = url.getPort(); + } + } catch (MalformedURLException e) { + Log.e(LOG_TAG + "::appendDatabaseCallback", e.getMessage()); + } + + mOutputs[index].append("UI DELEGATE DATABASE CALLBACK: "); + mOutputs[index].append("exceededDatabaseQuotaForSecurityOrigin:{"); + mOutputs[index].append(protocol + ", " + host + ", " + port + "} "); + mOutputs[index].append("database:" + databaseIdentifier + "\n"); + } + + public void appendConsoleMessage(ConsoleMessage consoleMessage) { + int index = OutputType.CONSOLE_MESSAGE.ordinal(); + if (mOutputs[index] == null) { + mOutputs[index] = new StringBuilder(); + } + + mOutputs[index].append("CONSOLE MESSAGE: line " + consoleMessage.lineNumber()); + mOutputs[index].append(": " + consoleMessage.message() + "\n"); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < mOutputs.length; i++) { + if (mOutputs[i] != null) { + result.append(mOutputs[i].toString()); + } + } + return result.toString(); + } +}
\ No newline at end of file diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java new file mode 100644 index 0000000..35f9d0a --- /dev/null +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dumprendertree2; + +import android.net.Uri; +import android.util.Log; +import android.webkit.WebStorage; + +import java.io.File; + +/** + * A class that is registered as JS interface for webview in LayoutTestExecutor + */ +public class LayoutTestController { + private static final String LOG_TAG = "LayoutTestController"; + + LayoutTestsExecutor mLayoutTestsExecutor; + + public LayoutTestController(LayoutTestsExecutor layoutTestsExecutor) { + mLayoutTestsExecutor = layoutTestsExecutor; + } + + public void waitUntilDone() { + mLayoutTestsExecutor.waitUntilDone(); + } + + public void notifyDone() { + mLayoutTestsExecutor.notifyDone(); + } + + public void dumpAsText() { + dumpAsText(false); + } + + public void dumpAsText(boolean enablePixelTest) { + mLayoutTestsExecutor.dumpAsText(enablePixelTest); + } + + public void dumpChildFramesAsText() { + mLayoutTestsExecutor.dumpChildFramesAsText(); + } + + public void clearAllDatabases() { + Log.w(LOG_TAG + "::clearAllDatabases", "called"); + WebStorage.getInstance().deleteAllData(); + } + + public void setCanOpenWindows() { + mLayoutTestsExecutor.setCanOpenWindows(); + } + + public void dumpDatabaseCallbacks() { + mLayoutTestsExecutor.dumpDatabaseCallbacks(); + } + + public void setDatabaseQuota(long quota) { + /** TODO: Reset this before every test! */ + Log.w(LOG_TAG + "::setDatabaseQuota", "called with: " + quota); + WebStorage.getInstance().setQuotaForOrigin(Uri.fromFile(new File("")).toString(), + quota); + } +}
\ No newline at end of file diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java index e0d3e37..73026bc 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java @@ -31,6 +31,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.view.Window; +import android.webkit.ConsoleMessage; import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.WebChromeClient; @@ -96,6 +97,11 @@ public class LayoutTestsExecutor extends Activity { private boolean mCurrentTestTimedOut; private AbstractResult mCurrentResult; + private AdditionalTextOutput mCurrentAdditionalTextOutput; + + private LayoutTestController mLayoutTestController = new LayoutTestController(this); + private boolean mCanOpenWindows; + private boolean mDumpDatabaseCallbacks; /** COMMUNICATION WITH ManagerService */ @@ -143,8 +149,9 @@ public class LayoutTestsExecutor extends Activity { return; } - /** TODO: Implement waitUntilDone */ - onTestFinished(); + if (mCurrentState == CurrentState.RENDERING_PAGE) { + onTestFinished(); + } } }; @@ -154,6 +161,14 @@ public class LayoutTestsExecutor extends Activity { long currentQuota, long estimatedSize, long totalUsedQuota, QuotaUpdater quotaUpdater) { /** TODO: This should be recorded as part of the text result */ + /** TODO: The quota should also probably be reset somehow for every test? */ + if (mDumpDatabaseCallbacks) { + if (mCurrentAdditionalTextOutput == null) { + mCurrentAdditionalTextOutput = new AdditionalTextOutput(); + } + + mCurrentAdditionalTextOutput.appendExceededDbQuotaMessage(url, databaseIdentifier); + } quotaUpdater.updateQuota(currentQuota + 5 * 1024 * 1024); } @@ -179,6 +194,36 @@ public class LayoutTestsExecutor extends Activity { return true; } + @Override + public boolean onConsoleMessage(ConsoleMessage consoleMessage) { + if (mCurrentAdditionalTextOutput == null) { + mCurrentAdditionalTextOutput = new AdditionalTextOutput(); + } + + mCurrentAdditionalTextOutput.appendConsoleMessage(consoleMessage); + return true; + } + + @Override + public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, + Message resultMsg) { + WebView.WebViewTransport transport = (WebView.WebViewTransport)resultMsg.obj; + /** By default windows cannot be opened, so just send null back. */ + WebView newWindowWebView = null; + + if (mCanOpenWindows) { + /** + * We never display the new window, just create the view and allow it's content to + * execute and be recorded by the executor. + */ + newWindowWebView = new WebView(LayoutTestsExecutor.this); + setupWebView(newWindowWebView); + } + + transport.setWebView(newWindowWebView); + resultMsg.sendToTarget(); + return true; + } }; /** IMPLEMENTATION */ @@ -201,14 +246,37 @@ public class LayoutTestsExecutor extends Activity { private void reset() { WebView previousWebView = mCurrentWebView; + resetLayoutTestController(); + mCurrentTestTimedOut = false; mCurrentResult = null; + mCurrentAdditionalTextOutput = null; mCurrentWebView = new WebView(this); - mCurrentWebView.setWebViewClient(mWebViewClient); - mCurrentWebView.setWebChromeClient(mWebChromeClient); + setupWebView(mCurrentWebView); - WebSettings webViewSettings = mCurrentWebView.getSettings(); + setContentView(mCurrentWebView); + if (previousWebView != null) { + Log.d(LOG_TAG + "::reset", "previousWebView != null"); + previousWebView.destroy(); + } + } + + private void setupWebView(WebView webView) { + webView.setWebViewClient(mWebViewClient); + webView.setWebChromeClient(mWebChromeClient); + webView.addJavascriptInterface(mLayoutTestController, "layoutTestController"); + + /** + * Setting a touch interval of -1 effectively disables the optimisation in WebView + * that stops repeated touch events flooding WebCore. The Event Sender only sends a + * single event rather than a stream of events (like what would generally happen in + * a real use of touch events in a WebView) and so if the WebView drops the event, + * the test will fail as the test expects one callback for every touch it synthesizes. + */ + webView.setTouchInterval(-1); + + WebSettings webViewSettings = webView.getSettings(); webViewSettings.setAppCacheEnabled(true); webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); webViewSettings.setAppCacheMaxSize(Long.MAX_VALUE); @@ -221,11 +289,6 @@ public class LayoutTestsExecutor extends Activity { webViewSettings.setDomStorageEnabled(true); webViewSettings.setWorkersEnabled(false); webViewSettings.setXSSAuditorEnabled(false); - - setContentView(mCurrentWebView); - if (previousWebView != null) { - previousWebView.destroy(); - } } private void runNextTest() { @@ -279,6 +342,7 @@ public class LayoutTestsExecutor extends Activity { } mCurrentState = CurrentState.OBTAINING_RESULT; + mCurrentResult.obtainActualResults(mCurrentWebView, mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED)); } @@ -297,6 +361,10 @@ public class LayoutTestsExecutor extends Activity { } private void reportResultToService() { + if (mCurrentAdditionalTextOutput != null) { + mCurrentResult.setAdditionalTextOutputString(mCurrentAdditionalTextOutput.toString()); + } + try { Message serviceMsg = Message.obtain(null, ManagerService.MSG_PROCESS_ACTUAL_RESULTS); @@ -329,5 +397,109 @@ public class LayoutTestsExecutor extends Activity { } catch (RemoteException e) { Log.e(LOG_TAG + "::onAllTestsFinished", e.getMessage()); } + + unbindService(mServiceConnection); + } + + /** LAYOUT TEST CONTROLLER */ + + private static final int MSG_WAIT_UNTIL_DONE = 0; + private static final int MSG_NOTIFY_DONE = 1; + private static final int MSG_DUMP_AS_TEXT = 2; + private static final int MSG_DUMP_CHILD_FRAMES_AS_TEXT = 3; + private static final int MSG_SET_CAN_OPEN_WINDOWS = 4; + private static final int MSG_DUMP_DATABASE_CALLBACKS = 5; + + Handler mLayoutTestControllerHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + assert mCurrentState.isRunningState() + : "mCurrentState = " + mCurrentState.name(); + + switch (msg.what) { + case MSG_WAIT_UNTIL_DONE: + mCurrentState = CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST; + break; + + case MSG_NOTIFY_DONE: + if (mCurrentState == CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST) { + onTestFinished(); + } + break; + + case MSG_DUMP_AS_TEXT: + if (mCurrentResult == null) { + mCurrentResult = new TextResult(mCurrentTestRelativePath); + } + + assert mCurrentResult instanceof TextResult + : "mCurrentResult instanceof" + mCurrentResult.getClass().getName(); + + break; + + case MSG_DUMP_CHILD_FRAMES_AS_TEXT: + /** If dumpAsText was not called we assume that the result should be text */ + if (mCurrentResult == null) { + mCurrentResult = new TextResult(mCurrentTestRelativePath); + } + + assert mCurrentResult instanceof TextResult + : "mCurrentResult instanceof" + mCurrentResult.getClass().getName(); + + ((TextResult)mCurrentResult).setDumpChildFramesAsText(true); + break; + + case MSG_SET_CAN_OPEN_WINDOWS: + mCanOpenWindows = true; + break; + + case MSG_DUMP_DATABASE_CALLBACKS: + mDumpDatabaseCallbacks = true; + break; + + default: + Log.w(LOG_TAG + "::handleMessage", "Message code does not exist: " + msg.what); + break; + } + } + }; + + private void resetLayoutTestController() { + mCanOpenWindows = false; + mDumpDatabaseCallbacks = false; + } + + public void waitUntilDone() { + Log.w(LOG_TAG + "::waitUntilDone", "called"); + mLayoutTestControllerHandler.sendEmptyMessage(MSG_WAIT_UNTIL_DONE); + } + + public void notifyDone() { + Log.w(LOG_TAG + "::notifyDone", "called"); + mLayoutTestControllerHandler.sendEmptyMessage(MSG_NOTIFY_DONE); + } + + public void dumpAsText(boolean enablePixelTest) { + Log.w(LOG_TAG + "::dumpAsText(" + enablePixelTest + ")", "called"); + /** TODO: Implement */ + if (enablePixelTest) { + Log.w(LOG_TAG + "::dumpAsText", "enablePixelTest not implemented, switching to false"); + } + mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_AS_TEXT); + } + + public void dumpChildFramesAsText() { + Log.w(LOG_TAG + "::dumpChildFramesAsText", "called"); + mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_CHILD_FRAMES_AS_TEXT); + } + + public void setCanOpenWindows() { + Log.w(LOG_TAG + "::setCanOpenWindows", "called"); + mLayoutTestControllerHandler.sendEmptyMessage(MSG_SET_CAN_OPEN_WINDOWS); + } + + public void dumpDatabaseCallbacks() { + Log.w(LOG_TAG + "::dumpDatabaseCallbacks:", "called"); + mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_DATABASE_CALLBACKS); } }
\ No newline at end of file diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java index e32247c..cdc9995 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java @@ -132,7 +132,11 @@ public class ManagerService extends Service { } public static String getExpectedTextResult(String relativePath) { - return new String(getExpectedResult(relativePath, TEXT_RESULT_EXTENSION)); + byte[] result = getExpectedResult(relativePath, TEXT_RESULT_EXTENSION); + if (result != null) { + return new String(result); + } + return null; } public static byte[] getExpectedImageResult(String relativePath) { diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java index 4278d54..0f864e5 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java @@ -41,11 +41,13 @@ public class TextResult extends AbstractResult { private ResultCode mResultCode; private Message mResultObtainedMsg; + private boolean mDumpChildFramesAsText; + private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == MSG_DOCUMENT_AS_TEXT) { - mActualResult = (String) msg.obj; + mActualResult = (String)msg.obj; mResultObtainedMsg.sendToTarget(); } } @@ -55,6 +57,10 @@ public class TextResult extends AbstractResult { mRelativePath = relativePath; } + public void setDumpChildFramesAsText(boolean dumpChildFramesAsText) { + mDumpChildFramesAsText = dumpChildFramesAsText; + } + /** * Used to recreate the Result when received by the service. * @@ -64,6 +70,7 @@ public class TextResult extends AbstractResult { public TextResult(Bundle bundle) { mExpectedResult = bundle.getString("expectedTextualResult"); mActualResult = bundle.getString("actualTextualResult"); + setAdditionalTextOutputString(bundle.getString("additionalTextOutputString")); mRelativePath = bundle.getString("relativePath"); String resultCode = bundle.getString("resultCode"); if (resultCode != null) { @@ -95,6 +102,11 @@ public class TextResult extends AbstractResult { @Override public String getActualTextResult() { + String additionalTextResultString = getAdditionalTextOutputString(); + if (additionalTextResultString != null) { + return additionalTextResultString+ mActualResult; + } + return mActualResult; } @@ -187,9 +199,12 @@ public class TextResult extends AbstractResult { mResultObtainedMsg = resultObtainedMsg; Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT); - /** TODO: mDumpTopFrameAsText and mDumpChildFramesAsText */ + /** + * arg1 - should dump top frame as text + * arg2 - should dump child frames as text + */ msg.arg1 = 1; - msg.arg2 = 0; + msg.arg2 = mDumpChildFramesAsText ? 1 : 0; webview.documentAsText(msg); } @@ -197,7 +212,8 @@ public class TextResult extends AbstractResult { public Bundle getBundle() { Bundle bundle = new Bundle(); bundle.putString("expectedTextualResult", mExpectedResult); - bundle.putString("actualTextualResult", mActualResult); + bundle.putString("actualTextualResult", getActualTextResult()); + bundle.putString("additionalTextOutputString", getAdditionalTextOutputString()); bundle.putString("relativePath", mRelativePath); if (mResultCode != null) { bundle.putString("resultCode", mResultCode.name()); |