/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_TAG "webcore_test"
#include "config.h"
#include "BackForwardList.h"
#include "ChromeClientAndroid.h"
#include "ContextMenuClientAndroid.h"
#include "CookieClient.h"
#include "DragClientAndroid.h"
#include "EditorClientAndroid.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClientAndroid.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HistoryItem.h"
#include "InitializeThreading.h"
#include "InspectorClientAndroid.h"
#include "Intercept.h"
#include "IntRect.h"
#include "JavaSharedClient.h"
#include "jni_utility.h"
#include "MyJavaVM.h"
#include "Page.h"
#include "PlatformGraphicsContext.h"
#include "ResourceRequest.h"
#include "SelectionController.h"
#include "Settings.h"
#include "SharedBuffer.h"
#include "SubstituteData.h"
#include "TimerClient.h"
#include "TextEncoding.h"
#include "WebCoreViewBridge.h"
#include "WebFrameView.h"
#include "WebViewCore.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkImageEncoder.h"
#include <getopt.h>
#include <utils/Log.h>
using namespace android;
using namespace WebCore;
class MyJavaSharedClient : public TimerClient, public CookieClient {
public:
MyJavaSharedClient() : m_hasTimer(false) {}
virtual void setSharedTimer(long long timemillis) { m_hasTimer = true; }
virtual void stopSharedTimer() { m_hasTimer = false; }
virtual void setSharedTimerCallback(void (*f)()) { m_func = f; }
// Cookie methods that do nothing.
virtual void setCookies(const KURL&, const KURL&, const String&) {}
virtual String cookies(const KURL&) { return ""; }
virtual bool cookiesEnabled() { return false; }
bool m_hasTimer;
void (*m_func)();
};
static void historyItemChanged(HistoryItem* i) {
if (i->bridge())
i->bridge()->updateHistoryItem(i);
}
int main(int argc, char** argv) {
int width = 800;
int height = 600;
if (argc <= 1) {
LOGE("Please supply a file to read\n");
return 1;
} else {
while (true) {
int c = getopt(argc, argv, "d:");
if (c == -1)
break;
else if (c == 'd') {
char* x = strchr(optarg, 'x');
if (x) {
width = atoi(optarg);
height = atoi(x + 1);
LOGD("Rendering page at %dx%d", width, height);
}
}
}
}
JSC::initializeThreading();
// Setting this allows data: urls to load from a local file.
FrameLoader::setLocalLoadPolicy(FrameLoader::AllowLocalLoadsForAll);
// Create the fake JNIEnv and JavaVM
InitializeJavaVM();
// The real function is private to libwebcore but we know what it does.
notifyHistoryItemChanged = historyItemChanged;
// Implement the shared timer callback
MyJavaSharedClient client;
JavaSharedClient::SetTimerClient(&client);
JavaSharedClient::SetCookieClient(&client);
// Create the page with all the various clients
ChromeClientAndroid* chrome = new ChromeClientAndroid;
EditorClientAndroid* editor = new EditorClientAndroid;
Page* page = new Page(chrome, new ContextMenuClientAndroid, editor,
new DragClientAndroid, new InspectorClientAndroid);
editor->setPage(page);
// Create MyWebFrame that intercepts network requests
MyWebFrame* webFrame = new MyWebFrame(page);
webFrame->setUserAgent("Performance testing"); // needs to be non-empty
chrome->setWebFrame(webFrame);
// ChromeClientAndroid maintains the reference.
Release(webFrame);
// Create the Frame and the FrameLoaderClient
FrameLoaderClientAndroid* loader = new FrameLoaderClientAndroid(webFrame);
RefPtr<Frame> frame = Frame::create(page, NULL, loader);
loader->setFrame(frame.get());
// Build our View system, resize it to the given dimensions and release our
// references. Note: We keep a referenec to frameView so we can layout and
// draw later without risk of it being deleted.
WebViewCore* webViewCore = new WebViewCore(JSC::Bindings::getJNIEnv(),
MY_JOBJECT, frame.get());
FrameView* frameView = new FrameView(frame.get());
WebFrameView* webFrameView = new WebFrameView(frameView, webViewCore);
frame->setView(frameView);
frameView->resize(width, height);
Release(webViewCore);
Release(webFrameView);
// Initialize the frame and turn of low-bandwidth display (it fails an
// assertion in the Cache code)
frame->init();
frame->selection()->setFocused(true);
frame->loader()->setUseLowBandwidthDisplay(false);
// Set all the default settings the Browser normally uses.
Settings* s = frame->settings();
s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now
s->setStandardFontFamily("sans-serif");
s->setFixedFontFamily("monospace");
s->setSansSerifFontFamily("sans-serif");
s->setSerifFontFamily("serif");
s->setCursiveFontFamily("cursive");
s->setFantasyFontFamily("fantasy");
s->setMinimumFontSize(8);
s->setMinimumLogicalFontSize(8);
s->setDefaultFontSize(16);
s->setDefaultFixedFontSize(13);
s->setLoadsImagesAutomatically(true);
s->setJavaScriptEnabled(true);
s->setDefaultTextEncodingName("latin1");
s->setPluginsEnabled(false);
s->setShrinksStandaloneImagesToFit(false);
s->setUseWideViewport(false);
// Finally, load the actual data
ResourceRequest req(argv[optind]);
frame->loader()->load(req);
// Layout the page and service the timer
frameView->layout();
while (client.m_hasTimer)
client.m_func();
// Layout more if needed.
while (frameView->needsLayout())
frameView->layout();
// Draw into an offscreen bitmap
SkBitmap bmp;
bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height);
bmp.allocPixels();
SkCanvas canvas(bmp);
PlatformGraphicsContext ctx(&canvas, NULL);
GraphicsContext gc(&ctx);
frameView->paintContents(&gc, IntRect(0, 0, width, height));
// Write the bitmap to the sdcard
SkImageEncoder* enc = SkImageEncoder::Create(SkImageEncoder::kPNG_Type);
enc->encodeFile("/sdcard/webcore_test.png", bmp, 100);
delete enc;
// Tear down the world.
frameView->deref();
frame->loader()->detachFromParent();
delete page;
return 0;
}