summaryrefslogtreecommitdiffstats
path: root/Source/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit')
-rw-r--r--Source/WebKit/Android.mk4
-rw-r--r--Source/WebKit/android/AndroidLog.h4
-rw-r--r--Source/WebKit/android/RenderSkinMediaButton.cpp14
-rw-r--r--Source/WebKit/android/RenderSkinMediaButton.h34
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp62
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h26
-rw-r--r--Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp1
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp96
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h61
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp223
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h86
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp125
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationManager.h80
-rwxr-xr-xSource/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp21
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h11
-rw-r--r--Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp58
-rw-r--r--Source/WebKit/android/WebCoreSupport/MemoryUsage.cpp44
-rw-r--r--Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp21
-rw-r--r--Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp2
-rw-r--r--Source/WebKit/android/WebCoreSupport/WebRequest.cpp7
-rw-r--r--Source/WebKit/android/WebCoreSupport/WebRequest.h2
-rw-r--r--Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp2
-rw-r--r--Source/WebKit/android/jni/GeolocationServiceBridge.cpp242
-rw-r--r--Source/WebKit/android/jni/GeolocationServiceBridge.h75
-rwxr-xr-xSource/WebKit/android/jni/MockGeolocation.cpp68
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp225
-rw-r--r--Source/WebKit/android/jni/PicturePile.h38
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp65
-rw-r--r--Source/WebKit/android/jni/WebCoreFrameBridge.cpp25
-rw-r--r--Source/WebKit/android/jni/WebCoreFrameBridge.h2
-rw-r--r--Source/WebKit/android/jni/WebFrameView.cpp1
-rw-r--r--Source/WebKit/android/jni/WebHistory.cpp65
-rw-r--r--Source/WebKit/android/jni/WebSettings.cpp6
-rw-r--r--Source/WebKit/android/jni/WebStorage.cpp10
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp376
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h39
-rw-r--r--Source/WebKit/android/nav/DrawExtra.cpp8
-rw-r--r--Source/WebKit/android/nav/DrawExtra.h3
-rw-r--r--Source/WebKit/android/nav/SelectText.h10
-rw-r--r--Source/WebKit/android/nav/WebView.cpp72
-rw-r--r--Source/WebKit/android/plugins/ANPSoundInterface.cpp2
-rw-r--r--Source/WebKit/android/plugins/ANPSurfaceInterface.cpp1
-rw-r--r--Source/WebKit/android/plugins/PluginWidgetAndroid.cpp8
-rw-r--r--Source/WebKit/android/plugins/PluginWidgetAndroid.h3
-rw-r--r--Source/WebKit/android/smoke/MessageThread.cpp146
-rw-r--r--Source/WebKit/android/smoke/MessageThread.h108
-rw-r--r--Source/WebKit/android/smoke/MessageTypes.h159
47 files changed, 1788 insertions, 953 deletions
diff --git a/Source/WebKit/Android.mk b/Source/WebKit/Android.mk
index c3e9798..07634b6 100644
--- a/Source/WebKit/Android.mk
+++ b/Source/WebKit/Android.mk
@@ -27,6 +27,9 @@ LOCAL_SRC_FILES := \
android/WebCoreSupport/EditorClientAndroid.cpp \
android/WebCoreSupport/FrameLoaderClientAndroid.cpp \
android/WebCoreSupport/FrameNetworkingContextAndroid.cpp \
+ android/WebCoreSupport/GeolocationClientAndroid.cpp \
+ android/WebCoreSupport/GeolocationClientImpl.cpp \
+ android/WebCoreSupport/GeolocationManager.cpp \
android/WebCoreSupport/GeolocationPermissions.cpp \
android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp \
android/WebCoreSupport/MemoryUsage.cpp \
@@ -61,6 +64,7 @@ LOCAL_SRC_FILES += \
android/jni/DeviceMotionClientImpl.cpp \
android/jni/DeviceOrientationClientImpl.cpp \
android/jni/GeolocationPermissionsBridge.cpp \
+ android/jni/GeolocationServiceBridge.cpp \
android/jni/JavaBridge.cpp \
android/jni/JavaSharedClient.cpp \
android/jni/MIMETypeRegistry.cpp \
diff --git a/Source/WebKit/android/AndroidLog.h b/Source/WebKit/android/AndroidLog.h
index f034d35..6b6c1a0 100644
--- a/Source/WebKit/android/AndroidLog.h
+++ b/Source/WebKit/android/AndroidLog.h
@@ -30,6 +30,8 @@
#define LOG_TAG __FILE__
#endif
+#define ATRACE_TAG ATRACE_TAG_WEBVIEW
+
#include <cutils/log.h>
#include <utils/Trace.h>
#include <wtf/CurrentTime.h>
@@ -58,7 +60,7 @@ extern FILE* gRenderTreeFile;
#define INT_RECT_FORMAT "[x=%d,y=%d,w=%d,h=%d]"
#define INT_RECT_ARGS(ir) ir.x(), ir.y(), ir.width(), ir.height()
-#define TRACE_METHOD() android::ScopedTrace __st(ATRACE_TAG_WEBVIEW, __func__);
+#define TRACE_METHOD() android::ScopedTrace __st(ATRACE_TAG, __func__);
#define TIME_METHOD() MethodTimer __method_timer(__func__)
class MethodTimer {
diff --git a/Source/WebKit/android/RenderSkinMediaButton.cpp b/Source/WebKit/android/RenderSkinMediaButton.cpp
index b3aa57d..a2f19c3 100644
--- a/Source/WebKit/android/RenderSkinMediaButton.cpp
+++ b/Source/WebKit/android/RenderSkinMediaButton.cpp
@@ -26,12 +26,13 @@
#define LOG_TAG "WebCore"
#include "config.h"
-#include "android_graphics.h"
+#include "RenderSkinMediaButton.h"
+
#include "Document.h"
#include "IntRect.h"
#include "Node.h"
#include "RenderObject.h"
-#include "RenderSkinMediaButton.h"
+#include "RenderSkinAndroid.h"
#include "RenderSlider.h"
#include "SkCanvas.h"
#include "SkNinePatch.h"
@@ -88,8 +89,9 @@ void RenderSkinMediaButton::Decode()
}
}
-void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonType,
- bool translucent, RenderObject* o, bool drawBackground)
+void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r,
+ MediaButton buttonType, bool translucent,
+ bool drawBackground, const IntRect& thumb)
{
if (!gDecoded) {
Decode();
@@ -179,9 +181,7 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT
SkScalar quarterHeight = SkScalarHalf(SkScalarHalf(bounds.height()));
bounds.fTop += quarterHeight + SkScalarHalf(3);
bounds.fBottom += -quarterHeight + SK_ScalarHalf;
- if (o && o->isSlider()) {
- RenderSlider* slider = toRenderSlider(o);
- IntRect thumb = slider->thumbRect();
+ if (!thumb.isEmpty()) {
// Inset the track by half the width of the thumb, so the track
// does not appear to go beyond the space where the thumb can
// be.
diff --git a/Source/WebKit/android/RenderSkinMediaButton.h b/Source/WebKit/android/RenderSkinMediaButton.h
index 484b90c..98c9e04 100644
--- a/Source/WebKit/android/RenderSkinMediaButton.h
+++ b/Source/WebKit/android/RenderSkinMediaButton.h
@@ -26,27 +26,43 @@
#ifndef RenderSkinMediaButton_h
#define RenderSkinMediaButton_h
-#include "RenderSkinAndroid.h"
+#include "IntRect.h"
class SkCanvas;
namespace WebCore {
-class IntRect;
-class RenderObject;
class RenderSkinMediaButton {
public:
static void Decode();
+
/**
- * Draw the skin to the canvas, using the rectangle for its bounds and the
- * State to determine which skin to use, i.e. focused or not focused.
+ * Button types
*/
- static void Draw(SkCanvas* , const IntRect& , int buttonType, bool translucent = false,
- RenderObject* o = 0, bool drawBackground = true);
+ typedef enum
+ {
+ PAUSE,
+ PLAY,
+ MUTE,
+ REWIND,
+ FORWARD,
+ FULLSCREEN,
+ SPINNER_OUTER,
+ SPINNER_INNER,
+ VIDEO,
+ BACKGROUND_SLIDER,
+ SLIDER_TRACK,
+ SLIDER_THUMB
+ } MediaButton;
+
/**
- * Button types
+ * Draw the skin to the canvas, using the rectangle for its bounds and the
+ * State to determine which skin to use, i.e. focused or not focused.
*/
- enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, FULLSCREEN, SPINNER_OUTER, SPINNER_INNER , VIDEO, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB };
+ static void Draw(SkCanvas* canvas, const IntRect& rect, MediaButton buttonType,
+ bool translucent = false, bool drawBackground = true,
+ const IntRect& thumb = IntRect());
+
/**
* Slider dimensions
*/
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 907dc3c..9094732 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -512,39 +512,6 @@ void ChromeClientAndroid::populateVisitedLinks()
android::WebViewCore::getWebViewCore(view)->populateVisitedLinks(&page->group());
}
-void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
-{
- ASSERT(geolocation);
- if (!m_geolocationPermissions) {
- m_geolocationPermissions = new GeolocationPermissions(android::WebViewCore::getWebViewCore(frame->view()),
- m_webFrame->page()->mainFrame());
- }
- m_geolocationPermissions->queryPermissionState(frame);
-}
-
-void ChromeClientAndroid::cancelGeolocationPermissionRequestForFrame(Frame* frame, WebCore::Geolocation*)
-{
- if (m_geolocationPermissions)
- m_geolocationPermissions->cancelPermissionStateQuery(frame);
-}
-
-void ChromeClientAndroid::provideGeolocationPermissions(const String &origin, bool allow, bool remember)
-{
- ASSERT(m_geolocationPermissions);
- m_geolocationPermissions->providePermissionState(origin, allow, remember);
-}
-
-void ChromeClientAndroid::storeGeolocationPermissions()
-{
- GeolocationPermissions::maybeStorePermanentPermissions();
-}
-
-void ChromeClientAndroid::onMainFrameLoadStarted()
-{
- if (m_geolocationPermissions.get())
- m_geolocationPermissions->resetTemporaryPermissionStates();
-}
-
void ChromeClientAndroid::runOpenPanel(Frame* frame,
PassRefPtr<FileChooser> chooser)
{
@@ -605,16 +572,6 @@ void ChromeClientAndroid::reachedApplicationCacheOriginQuota(SecurityOrigin*)
notImplemented();
}
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
-void ChromeClientAndroid::webAppCanBeInstalled()
-{
- FrameView* frameView = m_webFrame->page()->mainFrame()->view();
- android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
- if (core)
- core->notifyWebAppCanBeInstalled();
-}
-#endif
-
#if ENABLE(VIDEO)
bool ChromeClientAndroid::supportsFullscreenForNode(const Node* node)
{
@@ -627,16 +584,23 @@ void ChromeClientAndroid::enterFullscreenForNode(Node* node)
return;
HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
- String url = videoElement->currentSrc();
- LayerAndroid* layer = videoElement->platformLayer();
- if (!layer)
- return;
FrameView* frameView = m_webFrame->page()->mainFrame()->view();
android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
- m_webFrame->page()->mainFrame()->document()->webkitWillEnterFullScreenForElement(videoElement);
if (core)
- core->enterFullscreenForVideoLayer(layer->uniqueId(), url);
+ core->enterFullscreenForVideoLayer();
+
+ MediaPlayer* player = videoElement->player();
+ if (player) {
+ // We need to use the same document object as the
+ // MediaPlayerPrivateAndroid::onStopFullscreen().
+ Document* doc = player->mediaPlayerClient()->mediaPlayerOwningDocument();
+ if (doc)
+ doc->webkitWillEnterFullScreenForElement(videoElement);
+ // Now the player is responsible to trigger to the java side for
+ // entering full screen mode.
+ player->enterFullscreenMode();
+ }
}
void ChromeClientAndroid::exitFullscreenForNode(Node* node)
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 36576e6..4d27605 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -28,7 +28,6 @@
#include "ChromeClient.h"
-#include "GeolocationPermissions.h"
#include "PopupMenu.h"
#include "SearchPopupMenu.h"
#include "Timer.h"
@@ -47,13 +46,13 @@ namespace android {
class ChromeClientAndroid : public ChromeClient {
public:
- ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0)
+ ChromeClientAndroid() : m_webFrame(0)
#if USE(ACCELERATED_COMPOSITING)
- , m_rootGraphicsLayer(0)
- , m_needsLayerSync(false)
+ , m_rootGraphicsLayer(0)
+ , m_needsLayerSync(false)
#endif
- , m_triedToReclaimDBQuota(false)
- { }
+ , m_triedToReclaimDBQuota(false)
+ { }
virtual void chromeDestroyed();
virtual void setWindowRect(const FloatRect&);
@@ -147,12 +146,9 @@ namespace android {
#endif
// Methods used to request and provide Geolocation permissions.
- virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
- virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*);
- // Android-specific
- void provideGeolocationPermissions(const String &origin, bool allow, bool remember);
- void storeGeolocationPermissions();
- void onMainFrameLoadStarted();
+ // Not used with client-based Geolocation
+ virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) { ASSERT_NOT_REACHED(); }
+ virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*) { ASSERT_NOT_REACHED(); }
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
virtual void setCursor(const Cursor&);
@@ -184,10 +180,6 @@ namespace android {
virtual void showContextMenu();
#endif
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
- virtual void webAppCanBeInstalled();
-#endif
-
#if ENABLE(FULLSCREEN_API)
virtual void exitFullScreenForElement(Element*);
#endif
@@ -202,8 +194,6 @@ namespace android {
private:
android::WebFrame* m_webFrame;
- // The Geolocation permissions manager.
- OwnPtr<GeolocationPermissions> m_geolocationPermissions;
#if USE(ACCELERATED_COMPOSITING)
WebCore::GraphicsLayer* m_rootGraphicsLayer;
bool m_needsLayerSync;
diff --git a/Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index ac5cd9d..f62b2d1 100644
--- a/Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -76,7 +76,6 @@
#include "WebViewClientError.h"
#include "WebViewCore.h"
#include "autofill/WebAutofill.h"
-#include "android_graphics.h"
#include <androidfw/AssetManager.h>
#include <wtf/text/CString.h>
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp
new file mode 100644
index 0000000..7c5b207
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#include "config.h"
+#include "GeolocationClientAndroid.h"
+
+#include "WebViewCore.h"
+
+#include <Frame.h>
+#include <Page.h>
+
+using WebCore::Geolocation;
+using WebCore::GeolocationClient;
+using WebCore::GeolocationController;
+using WebCore::GeolocationPosition;
+
+namespace android {
+
+GeolocationClientAndroid::GeolocationClientAndroid() : m_webViewCore(0)
+{
+}
+
+GeolocationClientAndroid::~GeolocationClientAndroid()
+{
+}
+
+void GeolocationClientAndroid::geolocationDestroyed()
+{
+ delete this;
+}
+
+void GeolocationClientAndroid::startUpdating()
+{
+ client()->startUpdating();
+}
+
+void GeolocationClientAndroid::stopUpdating()
+{
+ client()->stopUpdating();
+}
+
+void GeolocationClientAndroid::setEnableHighAccuracy(bool enableHighAccuracy)
+{
+ client()->setEnableHighAccuracy(enableHighAccuracy);
+}
+
+GeolocationPosition* GeolocationClientAndroid::lastPosition()
+{
+ return client()->lastPosition();
+}
+
+void GeolocationClientAndroid::requestPermission(Geolocation* geolocation)
+{
+ client()->requestPermission(geolocation);
+}
+
+void GeolocationClientAndroid::cancelPermissionRequest(Geolocation* geolocation)
+{
+ client()->cancelPermissionRequest(geolocation);
+}
+
+void GeolocationClientAndroid::setWebViewCore(WebViewCore* webViewCore)
+{
+ ASSERT(!m_webViewCore);
+ m_webViewCore = webViewCore;
+ ASSERT(m_webViewCore);
+}
+
+GeolocationClient* GeolocationClientAndroid::client() const
+{
+ return m_webViewCore->geolocationManager()->client();
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h
new file mode 100644
index 0000000..22405e1
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#ifndef GeolocationClientAndroid_h
+#define GeolocationClientAndroid_h
+
+#include <GeolocationClient.h>
+
+namespace android {
+
+class WebViewCore;
+
+// The Android implementation of GeolocationClient. Acts as a proxy to
+// the real or mock impl, which is owned by the GeolocationManager.
+class GeolocationClientAndroid : public WebCore::GeolocationClient {
+public:
+ GeolocationClientAndroid();
+ virtual ~GeolocationClientAndroid();
+
+ // GeolocationClient
+ virtual void geolocationDestroyed();
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual void setEnableHighAccuracy(bool);
+ virtual WebCore::GeolocationPosition* lastPosition();
+ virtual void requestPermission(WebCore::Geolocation*);
+ virtual void cancelPermissionRequest(WebCore::Geolocation*);
+
+ void setWebViewCore(WebViewCore*);
+
+private:
+ WebCore::GeolocationClient* client() const;
+
+ WebViewCore* m_webViewCore;
+};
+
+} // namespace android
+
+#endif // GeolocationClientAndroid_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp
new file mode 100644
index 0000000..6291b7d
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#include "config.h"
+#include "GeolocationClientImpl.h"
+
+#include <Frame.h>
+#include <Page.h>
+#include <GeolocationController.h>
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <WebViewCore.h>
+#if PLATFORM(ANDROID)
+// Required for sim-eng build
+#include <math.h>
+#endif
+#include <wtf/CurrentTime.h>
+
+using WebCore::Geolocation;
+using WebCore::GeolocationError;
+using WebCore::GeolocationPosition;
+using WebCore::Timer;
+
+using namespace std;
+
+namespace {
+
+bool isPositionMovement(GeolocationPosition* position1, GeolocationPosition* position2)
+{
+ // For the small distances in which we are likely concerned, it's reasonable
+ // to approximate the distance between the two positions as the sum of the
+ // differences in latitude and longitude.
+ double delta = fabs(position1->latitude() - position2->latitude()) + fabs(position1->longitude() - position2->longitude());
+ // Approximate conversion from degrees of arc to metres.
+ delta *= 60 * 1852;
+ // The threshold is when the distance between the two positions exceeds the
+ // worse (larger) of the two accuracies.
+ int maxAccuracy = max(position1->accuracy(), position2->accuracy());
+ return delta > maxAccuracy;
+}
+
+bool isPositionMoreAccurate(GeolocationPosition* position1, GeolocationPosition* position2)
+{
+ return position2->accuracy() < position1->accuracy();
+}
+
+bool isPositionMoreTimely(GeolocationPosition* position1)
+{
+ double currentTime = WTF::currentTime();
+ double maximumAge = 10 * 60; // 10 minutes
+ return currentTime - position1->timestamp() > maximumAge;
+}
+
+} // anonymous namespace
+
+namespace android {
+
+GeolocationClientImpl::GeolocationClientImpl(WebViewCore* webViewCore)
+ : m_webViewCore(webViewCore)
+ , m_timer(this, &GeolocationClientImpl::timerFired)
+ , m_isSuspended(false)
+ , m_useGps(false)
+{
+}
+
+GeolocationClientImpl::~GeolocationClientImpl()
+{
+}
+
+void GeolocationClientImpl::geolocationDestroyed()
+{
+ // Lifetime is managed by GeolocationManager.
+}
+
+void GeolocationClientImpl::startUpdating()
+{
+ // This method is called every time a new watch or one-shot position request
+ // is started. If we already have a position or an error, call back
+ // immediately.
+ if (m_lastPosition || m_lastError) {
+ m_timer.startOneShot(0);
+ }
+
+ // Lazilly create the Java object.
+ bool haveJavaBridge = m_javaBridge;
+ if (!haveJavaBridge)
+ m_javaBridge.set(new GeolocationServiceBridge(this, m_webViewCore));
+ ASSERT(m_javaBridge);
+
+ // Set whether to use GPS before we start the implementation.
+ m_javaBridge->setEnableGps(m_useGps);
+
+ // If we're suspended, don't start the service. It will be started when we
+ // get the call to resume().
+ if (!haveJavaBridge && !m_isSuspended)
+ m_javaBridge->start();
+}
+
+void GeolocationClientImpl::stopUpdating()
+{
+ // TODO: It would be good to re-use the Java bridge object.
+ m_javaBridge.clear();
+ m_useGps = false;
+ // Reset last position and error to make sure that we always try to get a
+ // new position from the client when a request is first made.
+ m_lastPosition = 0;
+ m_lastError = 0;
+
+ if (m_timer.isActive())
+ m_timer.stop();
+}
+
+void GeolocationClientImpl::setEnableHighAccuracy(bool enableHighAccuracy)
+{
+ // On Android, high power == GPS.
+ m_useGps = enableHighAccuracy;
+ if (m_javaBridge)
+ m_javaBridge->setEnableGps(m_useGps);
+}
+
+GeolocationPosition* GeolocationClientImpl::lastPosition()
+{
+ return m_lastPosition.get();
+}
+
+void GeolocationClientImpl::requestPermission(Geolocation* geolocation)
+{
+ permissions()->queryPermissionState(geolocation->frame());
+}
+
+void GeolocationClientImpl::cancelPermissionRequest(Geolocation* geolocation)
+{
+ permissions()->cancelPermissionStateQuery(geolocation->frame());
+}
+
+// Note that there is no guarantee that subsequent calls to this method offer a
+// more accurate or updated position.
+void GeolocationClientImpl::newPositionAvailable(PassRefPtr<GeolocationPosition> position)
+{
+ ASSERT(position);
+ if (!m_lastPosition
+ || isPositionMovement(m_lastPosition.get(), position.get())
+ || isPositionMoreAccurate(m_lastPosition.get(), position.get())
+ || isPositionMoreTimely(m_lastPosition.get())) {
+ m_lastPosition = position;
+ // Remove the last error.
+ m_lastError = 0;
+ m_webViewCore->mainFrame()->page()->geolocationController()->positionChanged(m_lastPosition.get());
+ }
+}
+
+void GeolocationClientImpl::newErrorAvailable(PassRefPtr<WebCore::GeolocationError> error)
+{
+ ASSERT(error);
+ // We leave the last position
+ m_lastError = error;
+ m_webViewCore->mainFrame()->page()->geolocationController()->errorOccurred(m_lastError.get());
+}
+
+void GeolocationClientImpl::suspend()
+{
+ m_isSuspended = true;
+ if (m_javaBridge)
+ m_javaBridge->stop();
+}
+
+void GeolocationClientImpl::resume()
+{
+ m_isSuspended = false;
+ if (m_javaBridge)
+ m_javaBridge->start();
+}
+
+void GeolocationClientImpl::resetTemporaryPermissionStates()
+{
+ permissions()->resetTemporaryPermissionStates();
+}
+
+void GeolocationClientImpl::providePermissionState(String origin, bool allow, bool remember)
+{
+ permissions()->providePermissionState(origin, allow, remember);
+}
+
+GeolocationPermissions* GeolocationClientImpl::permissions() const
+{
+ if (!m_permissions)
+ m_permissions = new GeolocationPermissions(m_webViewCore);
+ return m_permissions.get();
+}
+
+void GeolocationClientImpl::timerFired(Timer<GeolocationClientImpl>* timer)
+{
+ ASSERT(&m_timer == timer);
+ ASSERT(m_lastPosition || m_lastError);
+ if (m_lastPosition)
+ m_webViewCore->mainFrame()->page()->geolocationController()->positionChanged(m_lastPosition.get());
+ else
+ m_webViewCore->mainFrame()->page()->geolocationController()->errorOccurred(m_lastError.get());
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h
new file mode 100644
index 0000000..26e6c0c
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#ifndef GeolocationClientImpl_h
+#define GeolocationClientImpl_h
+
+#include "GeolocationServiceBridge.h"
+#include "GeolocationClient.h"
+#include "GeolocationPermissions.h"
+
+#include <Timer.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class Geolocation;
+class GeolocationController;
+}
+
+namespace android {
+
+class WebViewCore;
+
+// The real implementation of GeolocationClient.
+class GeolocationClientImpl : public WebCore::GeolocationClient, public GeolocationServiceBridge::Listener {
+public:
+ GeolocationClientImpl(WebViewCore*);
+ virtual ~GeolocationClientImpl();
+
+ // WebCore::GeolocationClient
+ virtual void geolocationDestroyed();
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual void setEnableHighAccuracy(bool);
+ virtual WebCore::GeolocationPosition* lastPosition();
+ virtual void requestPermission(WebCore::Geolocation*);
+ virtual void cancelPermissionRequest(WebCore::Geolocation*);
+
+ // GeolocationServiceBridge::Listener
+ virtual void newPositionAvailable(PassRefPtr<WebCore::GeolocationPosition>);
+ virtual void newErrorAvailable(PassRefPtr<WebCore::GeolocationError>);
+
+ void suspend();
+ void resume();
+ void resetTemporaryPermissionStates();
+ void providePermissionState(String origin, bool allow, bool remember);
+
+private:
+ GeolocationPermissions* permissions() const;
+ void timerFired(WebCore::Timer<GeolocationClientImpl>*);
+
+ WebViewCore* m_webViewCore;
+ RefPtr<WebCore::GeolocationPosition> m_lastPosition;
+ RefPtr<WebCore::GeolocationError> m_lastError;
+ OwnPtr<GeolocationServiceBridge> m_javaBridge;
+ mutable OwnPtr<GeolocationPermissions> m_permissions;
+ WebCore::Timer<GeolocationClientImpl> m_timer;
+ bool m_isSuspended;
+ bool m_useGps;
+};
+
+} // namespace android
+
+#endif // GeolocationClientImpl_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp
new file mode 100644
index 0000000..cbf399d
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#include "config.h"
+#include "GeolocationManager.h"
+
+#include "GeolocationClientImpl.h"
+#include "WebViewCore.h"
+
+#include <Frame.h>
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <JNIHelp.h>
+#include <Page.h>
+
+using WebCore::GeolocationClient;
+using WebCore::GeolocationClientMock;
+
+namespace android {
+
+GeolocationManager::GeolocationManager(WebViewCore* webViewCore)
+ : m_useMock(false)
+ , m_webViewCore(webViewCore)
+{
+}
+
+GeolocationClient* GeolocationManager::client() const
+{
+ if (m_useMock)
+ return mockClient();
+ return realClient();
+}
+
+void GeolocationManager::suspendRealClient()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->suspend();
+}
+
+void GeolocationManager::resumeRealClient()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->resume();
+}
+
+void GeolocationManager::resetRealClientTemporaryPermissionStates()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->resetTemporaryPermissionStates();
+}
+
+void GeolocationManager::provideRealClientPermissionState(WTF::String origin, bool allow, bool remember)
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->providePermissionState(origin, allow, remember);
+}
+
+void GeolocationManager::setUseMock()
+{
+ m_useMock = true;
+ m_mockClient.clear();
+}
+
+void GeolocationManager::setMockPosition(PassRefPtr<WebCore::GeolocationPosition> position)
+{
+ ASSERT(m_useMock);
+ mockClient()->setPosition(position);
+}
+
+void GeolocationManager::setMockError(PassRefPtr<WebCore::GeolocationError> error)
+{
+ ASSERT(m_useMock);
+ mockClient()->setError(error);
+}
+
+void GeolocationManager::setMockPermission(bool allowed)
+{
+ ASSERT(m_useMock);
+ mockClient()->setPermission(allowed);
+}
+
+GeolocationClientImpl* GeolocationManager::realClient() const
+{
+ if (!m_realClient)
+ m_realClient.set(new GeolocationClientImpl(m_webViewCore));
+ return m_realClient.get();
+}
+
+GeolocationClientMock* GeolocationManager::mockClient() const
+{
+ ASSERT(m_useMock);
+ if (!m_mockClient) {
+ m_mockClient.set(new GeolocationClientMock);
+ m_mockClient->setController(m_webViewCore->mainFrame()->page()->geolocationController());
+ }
+ return m_mockClient.get();
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationManager.h b/Source/WebKit/android/WebCoreSupport/GeolocationManager.h
new file mode 100644
index 0000000..6459db1
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#ifndef GeolocationManager_h
+#define GeolocationManager_h
+
+#include "GeolocationClientImpl.h"
+
+#include <GeolocationClientMock.h>
+#include <OwnPtr.h>
+#include <PassRefPtr.h>
+
+namespace WebCore {
+class GeolocationError;
+class GeolocationPosition;
+}
+
+namespace android {
+
+class GeolocationClientImpl;
+class WebViewCore;
+
+// This class takes care of the fact that the client used for Geolocation
+// may be either the real implementation or a mock. It also handles setting the
+// data on the mock client. This class is owned by WebViewCore and exists to
+// keep cruft out of that class.
+class GeolocationManager {
+public:
+ GeolocationManager(WebViewCore*);
+
+ // For use by GeolocationClientAndroid. Gets the current client, either the
+ // real or mock.
+ WebCore::GeolocationClient* client() const;
+
+ void suspendRealClient();
+ void resumeRealClient();
+ void resetRealClientTemporaryPermissionStates();
+ void provideRealClientPermissionState(WTF::String origin, bool allow, bool remember);
+
+ // Sets use of the Geolocation mock client. Also resets that client.
+ void setUseMock();
+ void setMockPosition(PassRefPtr<WebCore::GeolocationPosition>);
+ void setMockError(PassRefPtr<WebCore::GeolocationError>);
+ void setMockPermission(bool allowed);
+
+private:
+ GeolocationClientImpl* realClient() const;
+ WebCore::GeolocationClientMock* mockClient() const;
+
+ bool m_useMock;
+ WebViewCore* m_webViewCore;
+ mutable OwnPtr<GeolocationClientImpl> m_realClient;
+ mutable OwnPtr<WebCore::GeolocationClientMock> m_mockClient;
+};
+
+} // namespace android
+
+#endif // GeolocationManager_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
index 36a9b61..fb29bd6 100755
--- a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
@@ -26,16 +26,16 @@
#include "config.h"
#include "GeolocationPermissions.h"
-#include "DOMWindow.h"
-#include "Frame.h"
-#include "Geolocation.h"
-#include "Navigator.h"
-#include "SQLiteDatabase.h"
-#include "SQLiteFileSystem.h"
-#include "SQLiteStatement.h"
-#include "SQLiteTransaction.h"
#include "WebViewCore.h"
+#include <DOMWindow.h>
+#include <Frame.h>
+#include <Geolocation.h>
+#include <Navigator.h>
+#include <SQLiteDatabase.h>
+#include <SQLiteFileSystem.h>
+#include <SQLiteStatement.h>
+#include <SQLiteTransaction.h>
#include <text/CString.h>
using namespace WebCore;
@@ -51,9 +51,8 @@ String GeolocationPermissions::s_databasePath;
static const char* databaseName = "GeolocationPermissions.db";
-GeolocationPermissions::GeolocationPermissions(WebViewCore* webViewCore, Frame* mainFrame)
+GeolocationPermissions::GeolocationPermissions(WebViewCore* webViewCore)
: m_webViewCore(webViewCore)
- , m_mainFrame(mainFrame)
, m_timer(this, &GeolocationPermissions::timerFired)
{
@@ -266,7 +265,7 @@ void GeolocationPermissions::maybeCallbackFrames(String origin, bool allow)
// or have their contents replaced. Even uniqueChildName is not unique when
// frames are dynamically deleted and created. Instead, we simply call back
// to the Geolocation object in all frames from the correct origin.
- for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) {
+ for (Frame* frame = m_webViewCore->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (origin == frame->document()->securityOrigin()->toString()) {
// If the page has changed, it may no longer have a Geolocation
// object.
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
index fb31dfe..8f4b96e 100644
--- a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
@@ -26,9 +26,8 @@
#ifndef GeolocationPermissions_h
#define GeolocationPermissions_h
-#include "PlatformString.h"
-#include "Timer.h"
-
+#include <PlatformString.h>
+#include <Timer.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
@@ -63,9 +62,8 @@ namespace android {
class GeolocationPermissions : public RefCounted<GeolocationPermissions> {
public:
// Creates the GeolocationPermissions object to manage permissions for
- // the specified main frame (i.e. tab). The WebViewCore is used to
- // communicate with the browser to display UI.
- GeolocationPermissions(WebViewCore* webViewCore, WebCore::Frame* mainFrame);
+ // the WebView.
+ GeolocationPermissions(WebViewCore* webViewCore);
virtual ~GeolocationPermissions();
// Queries the permission state for the specified frame. If the
@@ -140,7 +138,6 @@ namespace android {
const WTF::String& nextOriginInQueue();
WebViewCore* m_webViewCore;
- WebCore::Frame* m_mainFrame;
// A vector of the origins queued to make a permission request.
// The first in the vector is the origin currently making the request.
typedef Vector<WTF::String> OriginVector;
diff --git a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
index 1607b0e..de91766 100644
--- a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
@@ -30,6 +30,7 @@
#include "BaseLayerAndroid.h"
#include "GraphicsContext.h"
+#include "HTMLMediaElement.h"
#include "SkiaUtils.h"
#include "TilesManager.h"
#include "VideoLayerAndroid.h"
@@ -55,6 +56,7 @@ static const char* g_ProxyJavaClassAudio = "android/webkit/HTML5Audio";
struct MediaPlayerPrivate::JavaGlue {
jobject m_javaProxy;
jmethodID m_play;
+ jmethodID m_enterFullscreenForVideoLayer;
jmethodID m_teardown;
jmethodID m_seek;
jmethodID m_pause;
@@ -191,11 +193,19 @@ void MediaPlayerPrivate::onTimeupdate(int position)
m_player->timeChanged();
}
-void MediaPlayerPrivate::onStopFullscreen()
+void MediaPlayerPrivate::onStopFullscreen(bool stillPlaying)
{
- if (m_player && m_player->mediaPlayerClient()
- && m_player->mediaPlayerClient()->mediaPlayerOwningDocument()) {
- m_player->mediaPlayerClient()->mediaPlayerOwningDocument()->webkitCancelFullScreen();
+ if (m_player && m_player->mediaPlayerClient()) {
+ Document* doc = m_player->mediaPlayerClient()->mediaPlayerOwningDocument();
+ if (doc) {
+ HTMLMediaElement* element =
+ static_cast<HTMLMediaElement*>(doc->webkitCurrentFullScreenElement());
+ element->exitFullscreen();
+ doc->webkitDidExitFullScreenForElement(element);
+
+ if (stillPlaying)
+ element->play(true);
+ }
}
}
@@ -234,6 +244,22 @@ public:
checkException(env);
}
+
+ void enterFullscreenMode()
+ {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ if (!env || !m_url.length() || !m_glue->m_javaProxy)
+ return;
+
+ jstring jUrl = wtfStringToJstring(env, m_url);
+ env->CallVoidMethod(m_glue->m_javaProxy,
+ m_glue->m_enterFullscreenForVideoLayer, jUrl,
+ m_videoLayer->uniqueId());
+ env->DeleteLocalRef(jUrl);
+
+ checkException(env);
+ }
+
bool canLoadPoster() const { return true; }
void setPoster(const String& url)
{
@@ -260,9 +286,6 @@ public:
if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef()))
return;
- SkCanvas* canvas = ctxt->platformContext()->getCanvas();
- if (!canvas)
- return;
// We paint with the following rules in mind:
// - only downscale the poster, never upscale
// - maintain the natural aspect ratio of the poster
@@ -273,7 +296,7 @@ public:
int posterX = ((r.width() - posterWidth) / 2) + r.x();
int posterY = ((r.height() - posterHeight) / 2) + r.y();
IntRect targetRect(posterX, posterY, posterWidth, posterHeight);
- canvas->drawBitmapRect(*m_poster, 0, targetRect, 0);
+ ctxt->platformContext()->drawBitmapRect(*m_poster, 0, targetRect);
}
void onPosterFetched(SkBitmap* poster)
@@ -289,6 +312,13 @@ public:
m_naturalSize = IntSize(poster->width(), poster->height());
m_player->sizeChanged();
}
+ // At this time, we know that the proxy has been setup. And it is the
+ // right time to trigger autoplay through the HTMLMediaElement state
+ // change. Since we are using the java MediaPlayer, so we have to
+ // pretend that the MediaPlayer has enough data.
+ m_readyState = MediaPlayer::HaveEnoughData;
+ m_player->readyStateChanged();
+
}
void onPrepared(int duration, int width, int height)
@@ -319,9 +349,13 @@ public:
return;
m_glue = new JavaGlue;
- m_glue->m_getInstance = env->GetStaticMethodID(clazz, "getInstance", "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;");
+ m_glue->m_getInstance =
+ env->GetStaticMethodID(clazz, "getInstance",
+ "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;");
m_glue->m_loadPoster = env->GetMethodID(clazz, "loadPoster", "(Ljava/lang/String;)V");
m_glue->m_play = env->GetMethodID(clazz, "play", "(Ljava/lang/String;II)V");
+ m_glue->m_enterFullscreenForVideoLayer =
+ env->GetMethodID(clazz, "enterFullscreenForVideoLayer", "(Ljava/lang/String;I)V");
m_glue->m_teardown = env->GetMethodID(clazz, "teardown", "()V");
m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V");
@@ -628,12 +662,12 @@ static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex,
return true;
}
-static void OnStopFullscreen(JNIEnv* env, jobject obj, int pointer)
+static void OnStopFullscreen(JNIEnv* env, jobject obj, int stillPlaying, int pointer)
{
if (pointer) {
WebCore::MediaPlayerPrivate* player =
reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer);
- player->onStopFullscreen();
+ player->onStopFullscreen(stillPlaying);
}
}
@@ -645,7 +679,7 @@ static JNINativeMethod g_MediaPlayerMethods[] = {
(void*) OnPrepared },
{ "nativeOnEnded", "(I)V",
(void*) OnEnded },
- { "nativeOnStopFullscreen", "(I)V",
+ { "nativeOnStopFullscreen", "(II)V",
(void*) OnStopFullscreen },
{ "nativeOnPaused", "(I)V",
(void*) OnPaused },
diff --git a/Source/WebKit/android/WebCoreSupport/MemoryUsage.cpp b/Source/WebKit/android/WebCoreSupport/MemoryUsage.cpp
index 592fad3..5b8c33b 100644
--- a/Source/WebKit/android/WebCoreSupport/MemoryUsage.cpp
+++ b/Source/WebKit/android/WebCoreSupport/MemoryUsage.cpp
@@ -26,50 +26,22 @@
#include "config.h"
#include "MemoryUsage.h"
-#include <malloc.h>
-#include <wtf/CurrentTime.h>
-
#include <v8.h>
-using namespace WTF;
-
-class MemoryUsageCache {
-public:
- MemoryUsageCache()
- : m_cachedMemoryUsage(0)
- , m_cacheTime(0)
- {
- }
+// Workaround an issue where malloc_footprint is in malloc.h
+// but is not actually implemented.
+// See: http://code.google.com/p/android/issues/detail?id=34897
+extern "C" size_t dlmalloc_footprint(void);
- int getCachedMemoryUsage(bool forceFresh);
-
-private:
- unsigned m_cachedMemoryUsage;
- double m_cacheTime;
- static const int CACHE_VALIDITY_MS = 2000;
-};
+using namespace WTF;
-int MemoryUsageCache::getCachedMemoryUsage(bool forceFresh)
+int MemoryUsage::memoryUsageMb(bool /* forceFresh */)
{
- if (!forceFresh && currentTimeMS() <= m_cacheTime + CACHE_VALIDITY_MS)
- return m_cachedMemoryUsage;
-
- struct mallinfo minfo = mallinfo();
- m_cachedMemoryUsage = (minfo.hblkhd + minfo.arena) >> 20;
-
+ size_t footprint = dlmalloc_footprint() >> 20;
v8::HeapStatistics stat;
v8::V8::GetHeapStatistics(&stat);
unsigned v8Usage = stat.total_heap_size() >> 20;
- m_cachedMemoryUsage += v8Usage;
-
- m_cacheTime = currentTimeMS();
- return m_cachedMemoryUsage;
-}
-
-int MemoryUsage::memoryUsageMb(bool forceFresh)
-{
- static MemoryUsageCache cache;
- return cache.getCachedMemoryUsage(forceFresh);
+ return footprint + v8Usage;
}
int MemoryUsage::m_lowMemoryUsageMb = 0;
diff --git a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
index 9b8aac8..6e39c33 100644
--- a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
+++ b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
@@ -43,6 +43,7 @@
#include "WebViewCore.h"
#include "npruntime.h"
+#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
@@ -111,12 +112,6 @@ NPObject* PlatformBridge::pluginScriptableObject(Widget* widget)
return pluginView->getNPObject();
}
-bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView)
-{
- android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
- return webViewCore->isPaused();
-}
-
bool PlatformBridge::popupsAllowed(NPP)
{
return false;
@@ -130,15 +125,21 @@ String PlatformBridge::resolveFilePathForContentUri(const String& contentUri)
int PlatformBridge::PlatformBridge::screenDepth()
{
+ android::sp<android::IBinder> display(
+ android::SurfaceComposerClient::getBuiltInDisplay(
+ android::ISurfaceComposer::eDisplayIdMain));
android::DisplayInfo info;
- android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info);
+ android::SurfaceComposerClient::getDisplayInfo(display, &info);
return info.pixelFormatInfo.bitsPerPixel;
}
FloatRect PlatformBridge::screenRect()
{
+ android::sp<android::IBinder> display(
+ android::SurfaceComposerClient::getBuiltInDisplay(
+ android::ISurfaceComposer::eDisplayIdMain));
android::DisplayInfo info;
- android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info);
+ android::SurfaceComposerClient::getDisplayInfo(display, &info);
return FloatRect(0.0, 0.0, info.w, info.h);
}
@@ -170,10 +171,10 @@ void PlatformBridge::updateViewport(FrameView* frameView)
webViewCore->updateViewport();
}
-void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, bool changeToPassword, const WTF::String& text)
+void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, const WTF::String& text)
{
android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
- webViewCore->updateTextfield(nodePtr, changeToPassword, text);
+ webViewCore->updateTextfield(nodePtr, text);
}
void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) {
diff --git a/Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp b/Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp
index 0af3cc2..f42f307 100644
--- a/Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp
+++ b/Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp
@@ -189,7 +189,7 @@ int WebCookieJar::getNumCookiesInDatabase()
return cookieStore()->GetCookieMonster()->GetAllCookies().size();
}
-class FlushSemaphore : public base::RefCounted<FlushSemaphore>
+class FlushSemaphore : public base::RefCountedThreadSafe<FlushSemaphore>
{
public:
FlushSemaphore()
diff --git a/Source/WebKit/android/WebCoreSupport/WebRequest.cpp b/Source/WebKit/android/WebCoreSupport/WebRequest.cpp
index 9d16378..dda0ee1 100644
--- a/Source/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/Source/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -83,6 +83,7 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& web
: m_urlLoader(loader)
, m_url(webResourceRequest.url())
, m_userAgent(webResourceRequest.userAgent())
+ , m_referer(webResourceRequest.referrer())
, m_loadState(Created)
, m_authRequestCount(0)
, m_cacheMode(0)
@@ -109,6 +110,7 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& web
, m_interceptResponse(intercept)
, m_url(webResourceRequest.url())
, m_userAgent(webResourceRequest.userAgent())
+ , m_referer(webResourceRequest.referrer())
, m_loadState(Created)
, m_authRequestCount(0)
, m_cacheMode(0)
@@ -136,6 +138,11 @@ const std::string& WebRequest::getUserAgent() const
return m_userAgent;
}
+const std::string& WebRequest::getReferer() const
+{
+ return m_referer;
+}
+
#ifdef LOG_REQUESTS
namespace {
int remaining = 0;
diff --git a/Source/WebKit/android/WebCoreSupport/WebRequest.h b/Source/WebKit/android/WebCoreSupport/WebRequest.h
index d9054e9..4a4e10b 100644
--- a/Source/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/Source/WebKit/android/WebCoreSupport/WebRequest.h
@@ -89,6 +89,7 @@ public:
const std::string& getUrl() const;
const std::string& getUserAgent() const;
+ const std::string& getReferer() const;
void setSync(bool sync) { m_isSync = sync; }
private:
@@ -109,6 +110,7 @@ private:
scoped_ptr<UrlInterceptResponse> m_interceptResponse;
std::string m_url;
std::string m_userAgent;
+ std::string m_referer;
LoadState m_loadState;
int m_authRequestCount;
int m_cacheMode;
diff --git a/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index 5df0ed2..003b334 100644
--- a/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/Source/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -245,7 +245,7 @@ void WebUrlLoaderClient::downloadFile()
if (m_response) {
std::string contentDisposition;
m_response->getHeader("content-disposition", &contentDisposition);
- m_webFrame->downloadStart(m_response->getUrl(), m_request->getUserAgent(), contentDisposition, m_response->getMimeType(), m_response->getExpectedSize());
+ m_webFrame->downloadStart(m_response->getUrl(), m_request->getUserAgent(), contentDisposition, m_response->getMimeType(), m_request->getReferer(), m_response->getExpectedSize());
m_isCertMimeType = isMimeTypeForCert(m_response->getMimeType());
// Currently, only certificate mime type needs to receive the data.
diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.cpp b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp
new file mode 100644
index 0000000..056c788
--- /dev/null
+++ b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#include "config.h"
+#include "GeolocationServiceBridge.h"
+
+#include "WebViewCore.h"
+
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <JNIHelp.h>
+
+using JSC::Bindings::getJNIEnv;
+using WebCore::GeolocationError;
+using WebCore::GeolocationPosition;
+
+namespace android {
+
+static const char* javaGeolocationServiceClassName = "android/webkit/GeolocationService";
+enum javaGeolocationServiceClassMethods {
+ GeolocationServiceMethodInit = 0,
+ GeolocationServiceMethodStart,
+ GeolocationServiceMethodStop,
+ GeolocationServiceMethodSetEnableGps,
+ GeolocationServiceMethodCount,
+};
+static jmethodID javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodCount];
+
+static const JNINativeMethod javaGeolocationServiceClassNativeMethods[] = {
+ { "nativeNewLocationAvailable", "(JLandroid/location/Location;)V",
+ (void*) GeolocationServiceBridge::newLocationAvailable },
+ { "nativeNewErrorAvailable", "(JLjava/lang/String;)V",
+ (void*) GeolocationServiceBridge::newErrorAvailable }
+};
+
+static const char *javaLocationClassName = "android/location/Location";
+enum javaLocationClassMethods {
+ LocationMethodGetLatitude = 0,
+ LocationMethodGetLongitude,
+ LocationMethodHasAltitude,
+ LocationMethodGetAltitude,
+ LocationMethodHasAccuracy,
+ LocationMethodGetAccuracy,
+ LocationMethodHasBearing,
+ LocationMethodGetBearing,
+ LocationMethodHasSpeed,
+ LocationMethodGetSpeed,
+ LocationMethodGetTime,
+ LocationMethodCount,
+};
+static jmethodID javaLocationClassMethodIDs[LocationMethodCount];
+
+GeolocationServiceBridge::GeolocationServiceBridge(Listener* listener, WebViewCore* webViewCore)
+ : m_listener(listener)
+ , m_javaGeolocationServiceObject(0)
+{
+ ASSERT(m_listener);
+ startJavaImplementation(webViewCore);
+}
+
+GeolocationServiceBridge::~GeolocationServiceBridge()
+{
+ stop();
+ stopJavaImplementation();
+}
+
+bool GeolocationServiceBridge::start()
+{
+ if (!m_javaGeolocationServiceObject)
+ return false;
+ return getJNIEnv()->CallBooleanMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart]);
+}
+
+void GeolocationServiceBridge::stop()
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop]);
+}
+
+void GeolocationServiceBridge::setEnableGps(bool enable)
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps],
+ enable);
+}
+
+void GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong nativeObject, jobject location)
+{
+ ASSERT(nativeObject);
+ ASSERT(location);
+ GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+ object->m_listener->newPositionAvailable(toGeolocationPosition(env, location));
+}
+
+void GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message)
+{
+ GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+ RefPtr<GeolocationError> error = GeolocationError::create(GeolocationError::PositionUnavailable, jstringToWtfString(env, message));
+ object->m_listener->newErrorAvailable(error.release());
+}
+
+PassRefPtr<GeolocationPosition> GeolocationServiceBridge::toGeolocationPosition(JNIEnv *env, const jobject &location)
+{
+ // Altitude is optional and may not be supplied.
+ bool hasAltitude =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAltitude]);
+ double Altitude =
+ hasAltitude ?
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetAltitude]) :
+ 0.0;
+ // Accuracy is required, but is not supplied by the emulator.
+ double Accuracy =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAccuracy]) ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetAccuracy]) :
+ 0.0;
+ // heading is optional and may not be supplied.
+ bool hasHeading =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasBearing]);
+ double heading =
+ hasHeading ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetBearing]) :
+ 0.0;
+ // speed is optional and may not be supplied.
+ bool hasSpeed =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasSpeed]);
+ double speed =
+ hasSpeed ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) :
+ 0.0;
+
+ return GeolocationPosition::create(
+ env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]) / 1000.0,
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]),
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]),
+ Accuracy,
+ hasAltitude, Altitude,
+ false, 0.0, // AltitudeAccuracy not provided.
+ hasHeading, heading,
+ hasSpeed, speed);
+}
+
+void GeolocationServiceBridge::startJavaImplementation(WebViewCore* webViewCore)
+{
+ JNIEnv* env = getJNIEnv();
+
+ // Get the Java GeolocationService class.
+ jclass javaGeolocationServiceClass = env->FindClass(javaGeolocationServiceClassName);
+ ASSERT(javaGeolocationServiceClass);
+
+ // Set up the methods we wish to call on the Java GeolocationService class.
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit] =
+ env->GetMethodID(javaGeolocationServiceClass, "<init>", "(Landroid/content/Context;J)V");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart] =
+ env->GetMethodID(javaGeolocationServiceClass, "start", "()Z");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop] =
+ env->GetMethodID(javaGeolocationServiceClass, "stop", "()V");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps] =
+ env->GetMethodID(javaGeolocationServiceClass, "setEnableGps", "(Z)V");
+
+ // Create the Java GeolocationService object.
+ jobject context = webViewCore->getContext();
+ if (!context)
+ return;
+ jlong nativeObject = reinterpret_cast<jlong>(this);
+ jobject object = env->NewObject(javaGeolocationServiceClass,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit],
+ context,
+ nativeObject);
+
+ m_javaGeolocationServiceObject = getJNIEnv()->NewGlobalRef(object);
+ ASSERT(m_javaGeolocationServiceObject);
+
+ // Register to handle calls to native methods of the Java GeolocationService
+ // object. We register once only.
+ static int registered = jniRegisterNativeMethods(env,
+ javaGeolocationServiceClassName,
+ javaGeolocationServiceClassNativeMethods,
+ NELEM(javaGeolocationServiceClassNativeMethods));
+ ASSERT(registered == JNI_OK);
+
+ // Set up the methods we wish to call on the Java Location class.
+ jclass javaLocationClass = env->FindClass(javaLocationClassName);
+ ASSERT(javaLocationClass);
+ javaLocationClassMethodIDs[LocationMethodGetLatitude] =
+ env->GetMethodID(javaLocationClass, "getLatitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodGetLongitude] =
+ env->GetMethodID(javaLocationClass, "getLongitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodHasAltitude] =
+ env->GetMethodID(javaLocationClass, "hasAltitude", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetAltitude] =
+ env->GetMethodID(javaLocationClass, "getAltitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodHasAccuracy] =
+ env->GetMethodID(javaLocationClass, "hasAccuracy", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetAccuracy] =
+ env->GetMethodID(javaLocationClass, "getAccuracy", "()F");
+ javaLocationClassMethodIDs[LocationMethodHasBearing] =
+ env->GetMethodID(javaLocationClass, "hasBearing", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetBearing] =
+ env->GetMethodID(javaLocationClass, "getBearing", "()F");
+ javaLocationClassMethodIDs[LocationMethodHasSpeed] =
+ env->GetMethodID(javaLocationClass, "hasSpeed", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetSpeed] =
+ env->GetMethodID(javaLocationClass, "getSpeed", "()F");
+ javaLocationClassMethodIDs[LocationMethodGetTime] =
+ env->GetMethodID(javaLocationClass, "getTime", "()J");
+}
+
+void GeolocationServiceBridge::stopJavaImplementation()
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject);
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.h b/Source/WebKit/android/jni/GeolocationServiceBridge.h
new file mode 100644
index 0000000..826ba71
--- /dev/null
+++ b/Source/WebKit/android/jni/GeolocationServiceBridge.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012, 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 THE COPYRIGHT OWNER 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.
+ */
+
+#ifndef GeolocationServiceBridge_h
+#define GeolocationServiceBridge_h
+
+#include <JNIUtility.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+class GeolocationError;
+class GeolocationPosition;
+}
+
+namespace android {
+
+class WebViewCore;
+
+// GeolocationServiceBridge is the bridge to the Java implementation. It manages
+// the lifetime of the Java object. It is an implementation detail of
+// GeolocationClientAndroid.
+class GeolocationServiceBridge {
+public:
+ class Listener {
+ public:
+ virtual ~Listener() {}
+ virtual void newPositionAvailable(PassRefPtr<WebCore::GeolocationPosition>) = 0;
+ virtual void newErrorAvailable(PassRefPtr<WebCore::GeolocationError>) = 0;
+ };
+
+ GeolocationServiceBridge(Listener*, WebViewCore*);
+ ~GeolocationServiceBridge();
+
+ bool start();
+ void stop();
+ void setEnableGps(bool enable);
+
+ // Static wrapper functions to hide JNI nastiness.
+ static void newLocationAvailable(JNIEnv *env, jclass, jlong nativeObject, jobject location);
+ static void newErrorAvailable(JNIEnv *env, jclass, jlong nativeObject, jstring message);
+ static PassRefPtr<WebCore::GeolocationPosition> toGeolocationPosition(JNIEnv *env, const jobject &location);
+
+private:
+ void startJavaImplementation(WebViewCore*);
+ void stopJavaImplementation();
+
+ Listener* m_listener;
+ jobject m_javaGeolocationServiceObject;
+};
+
+} // namespace android
+
+#endif // GeolocationServiceBridge_h
diff --git a/Source/WebKit/android/jni/MockGeolocation.cpp b/Source/WebKit/android/jni/MockGeolocation.cpp
index 250953f..d588010 100755
--- a/Source/WebKit/android/jni/MockGeolocation.cpp
+++ b/Source/WebKit/android/jni/MockGeolocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2009, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,19 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// The functions in this file are used to configure the mock GeolocationService
+// The functions in this file are used to configure the mock Geolocation client
// for the LayoutTests.
#include "config.h"
-#include "Coordinates.h"
-#include "GeolocationServiceMock.h"
-#include "Geoposition.h"
-#include "JavaSharedClient.h"
-#include "PositionError.h"
-#include "WebCoreJni.h"
-#include <JNIHelp.h>
-#include <JNIUtility.h>
+#include "WebViewCore.h"
+
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include "JNIHelp.h"
+#include "ScopedLocalRef.h"
#include <wtf/CurrentTime.h>
using namespace WebCore;
@@ -44,30 +42,46 @@ namespace android {
static const char* javaMockGeolocationClass = "android/webkit/MockGeolocation";
-static void setPosition(JNIEnv* env, jobject, double latitude, double longitude, double accuracy)
+WebViewCore* getWebViewCore(JNIEnv* env, jobject webViewCore)
+{
+ ScopedLocalRef<jclass> webViewCoreClass(env, env->FindClass("android/webkit/WebViewCore"));
+ jfieldID nativeClassField = env->GetFieldID(webViewCoreClass.get(), "mNativeClass", "I");
+ return reinterpret_cast<WebViewCore*>(env->GetIntField(webViewCore, nativeClassField));
+}
+
+static void setUseMock(JNIEnv* env, jobject, jobject webViewCore)
+{
+ getWebViewCore(env, webViewCore)->geolocationManager()->setUseMock();
+}
+
+static void setPosition(JNIEnv* env, jobject, jobject webViewCore, double latitude, double longitude, double accuracy)
+{
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockPosition(GeolocationPosition::create(WTF::currentTime(),
+ latitude,
+ longitude,
+ accuracy,
+ false, 0.0, // altitude,
+ false, 0.0, // altitudeAccuracy,
+ false, 0.0, // heading
+ false, 0.0)); // speed
+}
+
+static void setError(JNIEnv* env, jobject, jobject webViewCore, int code, jstring message)
{
- RefPtr<Coordinates> coordinates = Coordinates::create(latitude,
- longitude,
- false, 0.0, // altitude,
- accuracy,
- false, 0.0, // altitudeAccuracy,
- false, 0.0, // heading
- false, 0.0); // speed
- RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTimeMS());
- GeolocationServiceMock::setPosition(position.release());
+ GeolocationError::ErrorCode codeEnum = static_cast<GeolocationError::ErrorCode>(code);
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockError(GeolocationError::create(codeEnum, jstringToWtfString(env, message)));
}
-static void setError(JNIEnv* env, jobject, int code, jstring message)
+static void setPermission(JNIEnv* env, jobject, jobject webViewCore, bool allow)
{
- PositionError::ErrorCode codeEnum = static_cast<PositionError::ErrorCode>(code);
- String messageString = jstringToWtfString(env, message);
- RefPtr<PositionError> error = PositionError::create(codeEnum, messageString);
- GeolocationServiceMock::setError(error.release());
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockPermission(allow);
}
static JNINativeMethod gMockGeolocationMethods[] = {
- { "nativeSetPosition", "(DDD)V", (void*) setPosition },
- { "nativeSetError", "(ILjava/lang/String;)V", (void*) setError }
+ { "nativeSetUseMock", "(Landroid/webkit/WebViewCore;)V", (void*) setUseMock },
+ { "nativeSetPosition", "(Landroid/webkit/WebViewCore;DDD)V", (void*) setPosition },
+ { "nativeSetError", "(Landroid/webkit/WebViewCore;ILjava/lang/String;)V", (void*) setError },
+ { "nativeSetPermission", "(Landroid/webkit/WebViewCore;Z)V", (void*) setPermission },
};
int registerMockGeolocation(JNIEnv* env)
diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp
index ccdfa59..f995e92 100644
--- a/Source/WebKit/android/jni/PicturePile.cpp
+++ b/Source/WebKit/android/jni/PicturePile.cpp
@@ -35,11 +35,16 @@
#include "PlatformGraphicsContextSkia.h"
#include "SkCanvas.h"
#include "SkNWayCanvas.h"
-#include "SkPicture.h"
#include "SkPixelRef.h"
#include "SkRect.h"
#include "SkRegion.h"
+#if USE_RECORDING_CONTEXT
+#include "PlatformGraphicsContextRecording.h"
+#else
+#include "SkPicture.h"
+#endif
+
#define ENABLE_PRERENDERED_INVALS true
#define MAX_OVERLAP_COUNT 2
#define MAX_OVERLAP_AREA .7
@@ -50,11 +55,18 @@ static SkIRect toSkIRect(const IntRect& rect) {
return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
}
-static IntRect extractClipBounds(SkCanvas* canvas, const IntSize& size) {
- SkRect clip;
- canvas->getClipBounds(&clip);
- clip.intersect(0, 0, size.width(), size.height());
- return enclosingIntRect(clip);
+PictureContainer::PictureContainer(const PictureContainer& other)
+ : picture(other.picture)
+ , area(other.area)
+ , dirty(other.dirty)
+ , prerendered(other.prerendered)
+{
+ SkSafeRef(picture);
+}
+
+PictureContainer::~PictureContainer()
+{
+ SkSafeUnref(picture);
}
PicturePile::PicturePile(const PicturePile& other)
@@ -64,15 +76,6 @@ PicturePile::PicturePile(const PicturePile& other)
{
}
-PicturePile::PicturePile(SkPicture* picture)
-{
- m_size = IntSize(picture->width(), picture->height());
- PictureContainer pc(IntRect(0, 0, m_size.width(), m_size.height()));
- pc.picture = picture;
- pc.dirty = false;
- m_pile.append(pc);
-}
-
void PicturePile::draw(SkCanvas* canvas)
{
/* Loop down recursively, subtracting the previous clip from the SkRegion,
@@ -81,10 +84,10 @@ void PicturePile::draw(SkCanvas* canvas)
* the rect bounds of the SkRegion for the clip, so this still can't be
* used for translucent surfaces
*/
- TRACE_METHOD();
- IntRect clipBounds = extractClipBounds(canvas, m_size);
- SkRegion clipRegion(toSkIRect(clipBounds));
- drawWithClipRecursive(canvas, clipRegion, m_pile.size() - 1);
+ if (canvas->quickReject(SkRect::MakeWH(m_size.width(), m_size.height()),
+ SkCanvas::kBW_EdgeType))
+ return;
+ drawWithClipRecursive(canvas, m_pile.size() - 1);
}
void PicturePile::clearPrerenders()
@@ -93,25 +96,23 @@ void PicturePile::clearPrerenders()
m_pile[i].prerendered.clear();
}
-void PicturePile::drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion,
- int index)
+void PicturePile::drawWithClipRecursive(SkCanvas* canvas, int index)
{
// TODO: Add some debug visualizations of this
- if (index < 0 || clipRegion.isEmpty())
+ if (index < 0)
return;
PictureContainer& pc = m_pile[index];
- IntRect intersection = clipRegion.getBounds();
- intersection.intersect(pc.area);
- if (pc.picture && !intersection.isEmpty()) {
- clipRegion.op(intersection, SkRegion::kDifference_Op);
- drawWithClipRecursive(canvas, clipRegion, index - 1);
- int saved = canvas->save();
- canvas->clipRect(intersection);
- canvas->translate(pc.area.x(), pc.area.y());
- canvas->drawPicture(*pc.picture);
+ if (pc.picture && !canvas->quickReject(pc.area, SkCanvas::kBW_EdgeType)) {
+ int saved = canvas->save(SkCanvas::kClip_SaveFlag);
+ if (canvas->clipRect(pc.area, SkRegion::kDifference_Op))
+ drawWithClipRecursive(canvas, index - 1);
+ canvas->restoreToCount(saved);
+ saved = canvas->save(SkCanvas::kClip_SaveFlag);
+ if (canvas->clipRect(pc.area))
+ drawPicture(canvas, pc);
canvas->restoreToCount(saved);
} else
- drawWithClipRecursive(canvas, clipRegion, index - 1);
+ drawWithClipRecursive(canvas, index - 1);
}
// Used by WebViewCore
@@ -140,14 +141,30 @@ void PicturePile::setSize(const IntSize& size)
{
if (m_size == size)
return;
+ IntSize oldSize = m_size;
m_size = size;
- // TODO: See above about just adding invals for new content
- m_pile.clear();
- m_webkitInvals.clear();
- if (!size.isEmpty()) {
- IntRect area(0, 0, size.width(), size.height());
- m_webkitInvals.append(area);
- m_pile.append(area);
+ if (size.width() <= oldSize.width() && size.height() <= oldSize.height()) {
+ // We are shrinking - huzzah, nothing to do!
+ // TODO: Loop through and throw out Pictures that are now clipped out
+ } else if (oldSize.width() == size.width()) {
+ // Only changing vertically
+ IntRect rect(0, std::min(oldSize.height(), size.height()),
+ size.width(), std::abs(oldSize.height() - size.height()));
+ invalidate(rect);
+ } else if (oldSize.height() == size.height()) {
+ // Only changing horizontally
+ IntRect rect(std::min(oldSize.width(), size.width()), 0,
+ std::abs(oldSize.width() - size.width()), size.height());
+ invalidate(rect);
+ } else {
+ // Both width & height changed, full inval :(
+ m_pile.clear();
+ m_webkitInvals.clear();
+ if (!size.isEmpty()) {
+ IntRect area(0, 0, size.width(), size.height());
+ m_webkitInvals.append(area);
+ m_pile.append(area);
+ }
}
}
@@ -163,43 +180,8 @@ void PicturePile::updatePicturesIfNeeded(PicturePainter* painter)
void PicturePile::updatePicture(PicturePainter* painter, PictureContainer& pc)
{
- /* The ref counting here is a bit unusual. What happens is begin/end recording
- * will ref/unref the recording canvas. However, 'canvas' might be pointing
- * at an SkNWayCanvas instead of the recording canvas, which needs to be
- * unref'd. Thus what we do is ref the recording canvas so that we can
- * always unref whatever canvas we have at the end.
- */
TRACE_METHOD();
- SkPicture* picture = new SkPicture();
- SkCanvas* canvas = picture->beginRecording(pc.area.width(), pc.area.height(),
- SkPicture::kUsePathBoundsForClip_RecordingFlag);
- SkSafeRef(canvas);
- canvas->translate(-pc.area.x(), -pc.area.y());
- IntRect drawArea = pc.area;
- if (pc.prerendered.get()) {
- SkCanvas* prerender = painter->createPrerenderCanvas(pc.prerendered.get());
- if (!prerender) {
- ALOGV("Failed to create prerendered for " INT_RECT_FORMAT,
- INT_RECT_ARGS(pc.prerendered->area));
- pc.prerendered.clear();
- } else {
- drawArea.unite(pc.prerendered->area);
- SkNWayCanvas* nwayCanvas = new SkNWayCanvas(drawArea.width(), drawArea.height());
- nwayCanvas->translate(-drawArea.x(), -drawArea.y());
- nwayCanvas->addCanvas(canvas);
- nwayCanvas->addCanvas(prerender);
- SkSafeUnref(canvas);
- SkSafeUnref(prerender);
- canvas = nwayCanvas;
- }
- }
- WebCore::PlatformGraphicsContextSkia pgc(canvas);
- WebCore::GraphicsContext gc(&pgc);
- ALOGV("painting picture: " INT_RECT_FORMAT, INT_RECT_ARGS(drawArea));
- painter->paintContents(&gc, drawArea);
- SkSafeUnref(canvas);
- picture->endRecording();
-
+ Picture* picture = recordPicture(painter, pc);
SkSafeUnref(pc.picture);
pc.picture = picture;
pc.dirty = false;
@@ -298,4 +280,97 @@ PrerenderedInval* PicturePile::prerenderedInvalForArea(const IntRect& area)
return 0;
}
+bool PicturePile::hasText() const
+{
+ for (size_t i = 0; i < m_pile.size(); i++) {
+ if (m_pile[i].hasText)
+ return true;
+ }
+ return false;
+}
+
+bool PicturePile::isEmpty() const
+{
+ for (size_t i = 0; i < m_pile.size(); i++) {
+ if (m_pile[i].picture)
+ return false;
+ }
+ return true;
+}
+
+#if USE_RECORDING_CONTEXT
+void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc)
+{
+ TRACE_METHOD();
+ pc.picture->draw(canvas);
+}
+
+Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& pc)
+{
+ pc.prerendered.clear(); // TODO: Support? Not needed?
+
+ Recording* picture = new Recording();
+ WebCore::PlatformGraphicsContextRecording pgc(picture);
+ WebCore::GraphicsContext gc(&pgc);
+ painter->paintContents(&gc, pc.area);
+ pc.hasText = pgc.hasText();
+ if (pgc.isEmpty()) {
+ SkSafeUnref(picture);
+ picture = 0;
+ }
+
+ return picture;
+}
+#else
+void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc)
+{
+ canvas->translate(pc.area.x(), pc.area.y());
+ pc.picture->draw(canvas);
+}
+
+Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& pc)
+{
+ /* The ref counting here is a bit unusual. What happens is begin/end recording
+ * will ref/unref the recording canvas. However, 'canvas' might be pointing
+ * at an SkNWayCanvas instead of the recording canvas, which needs to be
+ * unref'd. Thus what we do is ref the recording canvas so that we can
+ * always unref whatever canvas we have at the end.
+ */
+ SkPicture* picture = new SkPicture();
+ SkCanvas* canvas = picture->beginRecording(pc.area.width(), pc.area.height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag);
+ SkSafeRef(canvas);
+ canvas->translate(-pc.area.x(), -pc.area.y());
+ IntRect drawArea = pc.area;
+ if (pc.prerendered.get()) {
+ SkCanvas* prerender = painter->createPrerenderCanvas(pc.prerendered.get());
+ if (!prerender) {
+ ALOGV("Failed to create prerendered for " INT_RECT_FORMAT,
+ INT_RECT_ARGS(pc.prerendered->area));
+ pc.prerendered.clear();
+ } else {
+ drawArea.unite(pc.prerendered->area);
+ SkNWayCanvas* nwayCanvas = new SkNWayCanvas(drawArea.width(), drawArea.height());
+ nwayCanvas->translate(-drawArea.x(), -drawArea.y());
+ nwayCanvas->addCanvas(canvas);
+ nwayCanvas->addCanvas(prerender);
+ SkSafeUnref(canvas);
+ SkSafeUnref(prerender);
+ canvas = nwayCanvas;
+ }
+ }
+ WebCore::PlatformGraphicsContextSkia pgc(canvas);
+ WebCore::GraphicsContext gc(&pgc);
+ ALOGV("painting picture: " INT_RECT_FORMAT, INT_RECT_ARGS(drawArea));
+ painter->paintContents(&gc, drawArea);
+
+ // TODO: consider paint-time checking for these with SkPicture painting?
+ pc.hasText = true;
+
+ SkSafeUnref(canvas);
+ picture->endRecording();
+ return picture;
+}
+#endif
+
} // namespace WebCore
diff --git a/Source/WebKit/android/jni/PicturePile.h b/Source/WebKit/android/jni/PicturePile.h
index b28a792..1f99054 100644
--- a/Source/WebKit/android/jni/PicturePile.h
+++ b/Source/WebKit/android/jni/PicturePile.h
@@ -38,7 +38,17 @@
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
+#define USE_RECORDING_CONTEXT true
+#if USE_RECORDING_CONTEXT
+namespace WebCore {
+class Recording;
+}
+typedef WebCore::Recording Picture;
+#else
class SkPicture;
+typedef SkPicture Picture;
+#endif
+
class SkCanvas;
namespace WebCore {
@@ -57,37 +67,27 @@ public:
class PictureContainer {
public:
- SkPicture* picture;
+ Picture* picture;
IntRect area;
bool dirty;
RefPtr<PrerenderedInval> prerendered;
+ bool hasText;
PictureContainer(const IntRect& area)
: picture(0)
, area(area)
, dirty(true)
+ , hasText(false)
{}
- PictureContainer(const PictureContainer& other)
- : picture(other.picture)
- , area(other.area)
- , dirty(other.dirty)
- , prerendered(other.prerendered)
- {
- SkSafeRef(picture);
- }
-
- ~PictureContainer()
- {
- SkSafeUnref(picture);
- }
+ PictureContainer(const PictureContainer& other);
+ ~PictureContainer();
};
class PicturePile {
public:
PicturePile() {}
PicturePile(const PicturePile& other);
- PicturePile(SkPicture* picture);
const IntSize& size() { return m_size; }
@@ -104,11 +104,17 @@ public:
SkRegion& dirtyRegion() { return m_dirtyRegion; }
PrerenderedInval* prerenderedInvalForArea(const IntRect& area);
+ // UI-side methods used to check content, after construction/updates are complete
+ bool hasText() const;
+ bool isEmpty() const;
+
private:
void applyWebkitInvals();
void updatePicture(PicturePainter* painter, PictureContainer& container);
+ Picture* recordPicture(PicturePainter* painter, PictureContainer& container);
void appendToPile(const IntRect& inval, const IntRect& originalInval = IntRect());
- void drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion, int index);
+ void drawWithClipRecursive(SkCanvas* canvas, int index);
+ void drawPicture(SkCanvas* canvas, PictureContainer& pc);
IntSize m_size;
Vector<PictureContainer> m_pile;
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index 02ddca6..8963837 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -30,6 +30,7 @@
#include "BaseLayerAndroid.h"
#include "CreateJavaOutputStreamAdaptor.h"
+#include "DumpLayer.h"
#include "FixedPositioning.h"
#include "ImagesManager.h"
#include "IFrameContentLayerAndroid.h"
@@ -56,6 +57,68 @@ enum LayerTypes {
LTFixedLayerAndroid = 3
};
+#define ID "mID"
+#define LEFT "layout:mLeft"
+#define TOP "layout:mTop"
+#define WIDTH "layout:getWidth()"
+#define HEIGHT "layout:getHeight()"
+
+class HierarchyLayerDumper : public LayerDumper {
+public:
+ HierarchyLayerDumper(SkWStream* stream, int level)
+ : LayerDumper(level)
+ , m_stream(stream)
+ {}
+
+ virtual void beginLayer(const char* className, const LayerAndroid* layerPtr) {
+ LayerDumper::beginLayer(className, layerPtr);
+ for (int i = 0; i < m_indentLevel; i++) {
+ m_stream->writeText(" ");
+ }
+ m_stream->writeText(className);
+ m_stream->writeText("@");
+ m_stream->writeHexAsText(layerPtr->uniqueId());
+ m_stream->writeText(" ");
+
+ writeHexVal(ID, (int) layerPtr);
+ writeIntVal(LEFT, layerPtr->getPosition().fX);
+ writeIntVal(TOP, layerPtr->getPosition().fY);
+ writeIntVal(WIDTH, layerPtr->getWidth());
+ writeIntVal(HEIGHT, layerPtr->getHeight());
+ }
+
+ virtual void beginChildren(int childCount) {
+ m_stream->writeText("\n");
+ LayerDumper::beginChildren(childCount);
+ }
+
+protected:
+ virtual void writeEntry(const char* label, const char* value) {
+ m_stream->writeText(label);
+ m_stream->writeText("=");
+ int len = strlen(value);
+ m_stream->writeDecAsText(len);
+ m_stream->writeText(",");
+ m_stream->writeText(value);
+ m_stream->writeText(" ");
+ }
+
+private:
+ SkWStream* m_stream;
+};
+
+static void nativeDumpLayerHierarchy(JNIEnv* env, jobject, jint jbaseLayer, jint level,
+ jobject jstream, jbyteArray jstorage)
+{
+ SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
+ BaseLayerAndroid* baseLayer = reinterpret_cast<BaseLayerAndroid*>(jbaseLayer);
+ SkSafeRef(baseLayer);
+ HierarchyLayerDumper dumper(stream, level);
+ baseLayer->dumpLayers(&dumper);
+ SkSafeUnref(baseLayer);
+ delete stream;
+}
+
static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
jobject jstream, jbyteArray jstorage)
{
@@ -478,6 +541,8 @@ LayerAndroid* deserializeLayer(int version, SkStream* stream)
* JNI registration
*/
static JNINativeMethod gSerializerMethods[] = {
+ { "nativeDumpLayerHierarchy", "(IILjava/io/OutputStream;[B)V",
+ (void*) nativeDumpLayerHierarchy },
{ "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
(void*) nativeSerializeViewState },
{ "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I",
diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
index 4ce3d8e..61ffd29 100644
--- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -50,6 +50,7 @@
#include "FrameLoadRequest.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "GeolocationClientAndroid.h"
#include "GraphicsContext.h"
#include "HistoryItem.h"
#include "HTMLCollection.h"
@@ -88,7 +89,6 @@
#include "WebFrameView.h"
#include "WebUrlLoaderClient.h"
#include "WebViewCore.h"
-#include "android_graphics.h"
#include "jni.h"
#include "wds/DebugServer.h"
@@ -273,7 +273,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[BLjava/lang/String;)V");
mJavaFrame->mRequestClientCert = env->GetMethodID(clazz, "requestClientCert", "(ILjava/lang/String;)V");
mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
mJavaFrame->mDidReceiveData = env->GetMethodID(clazz, "didReceiveData", "([BI)V");
mJavaFrame->mDidFinishLoading = env->GetMethodID(clazz, "didFinishLoading", "()V");
mJavaFrame->mSetCertificate = env->GetMethodID(clazz, "setCertificate", "([B)V");
@@ -497,15 +497,9 @@ WebFrame::loadStarted(WebCore::Frame* frame)
if (favicon)
env->DeleteLocalRef(favicon);
- // Inform the client that the main frame has started a new load.
- if (isMainFrame && mPage) {
- Chrome* chrome = mPage->chrome();
- if (chrome) {
- ChromeClientAndroid* client = static_cast<ChromeClientAndroid*>(chrome->client());
- if (client)
- client->onMainFrameLoadStarted();
- }
- }
+ // The main frame has started a new load.
+ if (isMainFrame && mPage)
+ WebViewCore::getWebViewCore(mPage->mainFrame()->view())->geolocationManager()->resetRealClientTemporaryPermissionStates();
}
void
@@ -842,7 +836,7 @@ WebFrame::requestClientCert(WebUrlLoaderClient* client, const std::string& hostA
}
void
-WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength)
+WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, const std::string& referer, long long contentLength)
{
JNIEnv* env = getJNIEnv();
AutoJObject javaFrame = mJavaFrame->frame(env);
@@ -852,13 +846,15 @@ WebFrame::downloadStart(const std::string& url, const std::string& userAgent, co
jstring jUserAgent = stdStringToJstring(env, userAgent, true);
jstring jContentDisposition = stdStringToJstring(env, contentDisposition, true);
jstring jMimetype = stdStringToJstring(env, mimetype, true);
+ jstring jReferer = stdStringToJstring(env, referer, true);
- env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, contentLength);
+ env->CallVoidMethod(javaFrame.get(), mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, jReferer, contentLength);
env->DeleteLocalRef(jUrl);
env->DeleteLocalRef(jUserAgent);
env->DeleteLocalRef(jContentDisposition);
env->DeleteLocalRef(jMimetype);
+ env->DeleteLocalRef(jReferer);
checkException(env);
}
@@ -1099,6 +1095,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
EditorClientAndroid* editorC = new EditorClientAndroid;
DeviceMotionClientAndroid* deviceMotionC = new DeviceMotionClientAndroid;
DeviceOrientationClientAndroid* deviceOrientationC = new DeviceOrientationClientAndroid;
+ GeolocationClientAndroid* geolocationC = new GeolocationClientAndroid;
WebCore::Page::PageClients pageClients;
pageClients.chromeClient = chromeC;
@@ -1108,6 +1105,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
pageClients.inspectorClient = new InspectorClientAndroid;
pageClients.deviceMotionClient = deviceMotionC;
pageClients.deviceOrientationClient = deviceOrientationC;
+ pageClients.geolocationClient = geolocationC;
WebCore::Page* page = new WebCore::Page(pageClients);
editorC->setPage(page);
@@ -1150,6 +1148,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
frame->page()->focusController()->setFocused(true);
deviceMotionC->setWebViewCore(webViewCore);
deviceOrientationC->setWebViewCore(webViewCore);
+ geolocationC->setWebViewCore(webViewCore);
// Allow local access to file:/// and substitute data
WebCore::SecurityOrigin::setLocalLoadPolicy(
diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.h b/Source/WebKit/android/jni/WebCoreFrameBridge.h
index 30c1d83..56b095b 100644
--- a/Source/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/Source/WebKit/android/jni/WebCoreFrameBridge.h
@@ -116,7 +116,7 @@ class WebFrame : public WebCoreRefObject {
void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials, bool suppressDialog);
void reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert, const std::string& url);
void requestClientCert(WebUrlLoaderClient* client, const std::string& hostAndPort);
- void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength);
+ void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, const std::string& referer, long long contentLength);
void didReceiveData(const char* data, int size);
void didFinishLoading();
void setCertificate(const std::string& cert);
diff --git a/Source/WebKit/android/jni/WebFrameView.cpp b/Source/WebKit/android/jni/WebFrameView.cpp
index 10e31dc..ed332aa 100644
--- a/Source/WebKit/android/jni/WebFrameView.cpp
+++ b/Source/WebKit/android/jni/WebFrameView.cpp
@@ -28,7 +28,6 @@
#include <config.h>
#include "WebFrameView.h"
-#include "android_graphics.h"
#include "GraphicsContext.h"
#include "Frame.h"
#include "FrameTree.h"
diff --git a/Source/WebKit/android/jni/WebHistory.cpp b/Source/WebKit/android/jni/WebHistory.cpp
index 6b71d0f..c06244b 100644
--- a/Source/WebKit/android/jni/WebHistory.cpp
+++ b/Source/WebKit/android/jni/WebHistory.cpp
@@ -60,19 +60,19 @@ static void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item);
static void writeChildrenRecursive(WTF::Vector<char>& vector, WebCore::HistoryItem* parent);
static bool readItemRecursive(WebCore::HistoryItem* child, const char** pData, int length);
-// Field ids for WebHistoryItems
-struct WebHistoryItemFields {
+// Field ids for WebHistoryClassicItems
+struct WebHistoryItemClassicFields {
jmethodID mInit;
-} gWebHistoryItem;
+} gWebHistoryItemClassic;
-struct WebBackForwardListFields {
+struct WebBackForwardListClassicFields {
jmethodID mAddHistoryItem;
jmethodID mRemoveHistoryItem;
jmethodID mSetCurrentIndex;
-} gWebBackForwardList;
+} gWebBackForwardListClassic;
//--------------------------------------------------------------------------
-// WebBackForwardList native methods.
+// WebBackForwardListClassic native methods.
//--------------------------------------------------------------------------
static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame)
@@ -398,9 +398,9 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item)
WebHistoryItem* bridge = new WebHistoryItem(item);
bridge->setActive();
item->setBridge(bridge);
- // Allocate a blank WebHistoryItem
- jclass clazz = env->FindClass("android/webkit/WebHistoryItem");
- jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit,
+ // Allocate a blank WebHistoryItemClassic
+ jclass clazz = env->FindClass("android/webkit/WebHistoryItemClassic");
+ jobject newItem = env->NewObject(clazz, gWebHistoryItemClassic.mInit,
reinterpret_cast<int>(bridge));
env->DeleteLocalRef(clazz);
@@ -409,7 +409,7 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item)
bridge->updateHistoryItem(item);
// Add it to the list.
- env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem);
+ env->CallVoidMethod(list.get(), gWebBackForwardListClassic.mAddHistoryItem, newItem);
// Delete our local reference.
env->DeleteLocalRef(newItem);
@@ -418,13 +418,13 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item)
void WebHistory::RemoveItem(const AutoJObject& list, int index)
{
if (list.get())
- list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mRemoveHistoryItem, index);
+ list.env()->CallVoidMethod(list.get(), gWebBackForwardListClassic.mRemoveHistoryItem, index);
}
void WebHistory::UpdateHistoryIndex(const AutoJObject& list, int newIndex)
{
if (list.get())
- list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mSetCurrentIndex, newIndex);
+ list.env()->CallVoidMethod(list.get(), gWebBackForwardListClassic.mSetCurrentIndex, newIndex);
}
static void writeString(WTF::Vector<char>& vector, const WTF::String& str)
@@ -948,14 +948,14 @@ static void unitTest()
//---------------------------------------------------------
// JNI registration
//---------------------------------------------------------
-static JNINativeMethod gWebBackForwardListMethods[] = {
+static JNINativeMethod gWebBackForwardListClassicMethods[] = {
{ "nativeClose", "(I)V",
(void*) WebHistoryClose },
{ "restoreIndex", "(II)V",
(void*) WebHistoryRestoreIndex }
};
-static JNINativeMethod gWebHistoryItemMethods[] = {
+static JNINativeMethod gWebHistoryItemClassicMethods[] = {
{ "inflate", "(I[B)I",
(void*) WebHistoryInflate },
{ "nativeRef", "(I)V",
@@ -981,31 +981,30 @@ int registerWebHistory(JNIEnv* env)
#ifdef UNIT_TEST
unitTest();
#endif
- // Find WebHistoryItem, its constructor, and the update method.
- jclass clazz = env->FindClass("android/webkit/WebHistoryItem");
- ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem");
- gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "(I)V");
- ALOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor");
-
+ // Find WebHistoryItemClassic, its constructor, and the update method.
+ jclass clazz = env->FindClass("android/webkit/WebHistoryItemClassic");
+ ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItemClassic");
+ gWebHistoryItemClassic.mInit = env->GetMethodID(clazz, "<init>", "(I)V");
+ ALOG_ASSERT(gWebHistoryItemClassic.mInit, "Could not find WebHistoryItemClassic constructor");
env->DeleteLocalRef(clazz);
- // Find the WebBackForwardList object and method.
- clazz = env->FindClass("android/webkit/WebBackForwardList");
- ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList");
- gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem",
+ // Find the WebBackForwardListClassic object and method.
+ clazz = env->FindClass("android/webkit/WebBackForwardListClassic");
+ ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardListClassic");
+ gWebBackForwardListClassic.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem",
"(Landroid/webkit/WebHistoryItem;)V");
- ALOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem");
- gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem",
+ ALOG_ASSERT(gWebBackForwardListClassic.mAddHistoryItem, "Could not find method addHistoryItem");
+ gWebBackForwardListClassic.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem",
"(I)V");
- ALOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem");
- gWebBackForwardList.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V");
- ALOG_ASSERT(gWebBackForwardList.mSetCurrentIndex, "Could not find method setCurrentIndex");
+ ALOG_ASSERT(gWebBackForwardListClassic.mRemoveHistoryItem, "Could not find method removeHistoryItem");
+ gWebBackForwardListClassic.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V");
+ ALOG_ASSERT(gWebBackForwardListClassic.mSetCurrentIndex, "Could not find method setCurrentIndex");
env->DeleteLocalRef(clazz);
- int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList",
- gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods));
- return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem",
- gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods));
+ int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardListClassic",
+ gWebBackForwardListClassicMethods, NELEM(gWebBackForwardListClassicMethods));
+ return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItemClassic",
+ gWebHistoryItemClassicMethods, NELEM(gWebHistoryItemClassicMethods));
}
} /* namespace android */
diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp
index 467da3d..1bd3e36 100644
--- a/Source/WebKit/android/jni/WebSettings.cpp
+++ b/Source/WebKit/android/jni/WebSettings.cpp
@@ -151,6 +151,7 @@ struct FieldIds {
#endif
mOverrideCacheMode = env->GetFieldID(clazz, "mOverrideCacheMode", "I");
mPasswordEchoEnabled = env->GetFieldID(clazz, "mPasswordEchoEnabled", "Z");
+ mMediaPlaybackRequiresUserGesture = env->GetFieldID(clazz, "mMediaPlaybackRequiresUserGesture", "Z");
ALOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm");
ALOG_ASSERT(mTextSize, "Could not find field mTextSize");
@@ -195,6 +196,7 @@ struct FieldIds {
ALOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree");
ALOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity");
ALOG_ASSERT(mPasswordEchoEnabled, "Could not find field mPasswordEchoEnabled");
+ ALOG_ASSERT(mMediaPlaybackRequiresUserGesture, "Could not find field mMediaPlaybackRequiresUserGesture");
jclass enumClass = env->FindClass("java/lang/Enum");
ALOG_ASSERT(enumClass, "Could not find Enum class!");
@@ -281,6 +283,7 @@ struct FieldIds {
#endif
jfieldID mOverrideCacheMode;
jfieldID mPasswordEchoEnabled;
+ jfieldID mMediaPlaybackRequiresUserGesture;
};
static struct FieldIds* gFieldIds;
@@ -616,6 +619,9 @@ public:
bool echoPassword = env->GetBooleanField(obj,
gFieldIds->mPasswordEchoEnabled);
s->setPasswordEchoEnabled(echoPassword);
+
+ flag = env->GetBooleanField(obj, gFieldIds->mMediaPlaybackRequiresUserGesture);
+ s->setMediaPlaybackRequiresUserGesture(flag);
}
};
diff --git a/Source/WebKit/android/jni/WebStorage.cpp b/Source/WebKit/android/jni/WebStorage.cpp
index 66a3517..0cfe414 100644
--- a/Source/WebKit/android/jni/WebStorage.cpp
+++ b/Source/WebKit/android/jni/WebStorage.cpp
@@ -130,14 +130,10 @@ static void DeleteOrigin(JNIEnv* env, jobject obj, jstring origin)
static void DeleteAllData(JNIEnv* env, jobject obj)
{
+ // delete WebSQL database
WebCore::DatabaseTracker::tracker().deleteAllDatabases();
-
- Vector<WebCore::KURL> manifestUrls;
- if (!WebCore::cacheStorage().manifestURLs(&manifestUrls))
- return;
- int size = manifestUrls.size();
- for (int i = 0; i < size; ++i)
- WebCore::cacheStorage().deleteCacheGroup(manifestUrls[i]);
+ // delete AppCache
+ WebCore::cacheStorage().deleteAllEntries();
// FIXME: this is a workaround for eliminating any DOM Storage data (both
// session and local storage) as there is no functionality inside WebKit at the
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index f17e573..aa38222 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -30,6 +30,7 @@
#include "AccessibilityObject.h"
#include "AndroidHitTestResult.h"
+#include "ApplicationCacheStorage.h"
#include "Attribute.h"
#include "content/address_detector.h"
#include "Chrome.h"
@@ -62,7 +63,6 @@
#include "Geolocation.h"
#include "GraphicsContext.h"
#include "GraphicsJNI.h"
-#include "GraphicsOperationCollection.h"
#include "HTMLAnchorElement.h"
#include "HTMLAreaElement.h"
#include "HTMLElement.h"
@@ -131,10 +131,10 @@
#include "WebCoreJni.h"
#include "WebFrameView.h"
#include "WindowsKeyboardCodes.h"
-#include "android_graphics.h"
#include "autofill/WebAutofill.h"
#include "htmlediting.h"
#include "markup.h"
+#include "unicode/uloc.h"
#include "visible_units.h"
#include <JNIHelp.h>
@@ -367,8 +367,6 @@ struct WebViewCore::JavaGlue {
jmethodID m_showRect;
jmethodID m_centerFitRect;
jmethodID m_setScrollbarModes;
- jmethodID m_setInstallableWebApp;
- jmethodID m_enterFullscreenForVideoLayer;
jmethodID m_exitFullscreenVideo;
jmethodID m_setWebTextViewAutoFillable;
jmethodID m_selectAt;
@@ -401,7 +399,7 @@ struct WebViewCore::TextFieldInitDataGlue {
jfieldID m_maxLength;
jfieldID m_contentBounds;
jfieldID m_nodeLayerId;
- jfieldID m_contentRect;
+ jfieldID m_clientRect;
};
/*
@@ -423,7 +421,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_mainFrame(mainframe)
, m_popupReply(0)
, m_blockTextfieldUpdates(false)
- , m_focusBoundsChanged(false)
, m_skipContentDraw(false)
, m_textGeneration(0)
, m_maxXScroll(320/4)
@@ -436,7 +433,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_textWrapWidth(320)
, m_scale(1.0f)
, m_groupForVisitedLinks(0)
- , m_isPaused(false)
, m_cacheMode(0)
, m_fullscreenVideoMode(false)
, m_matchCount(0)
@@ -446,6 +442,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_screenOnCounter(0)
, m_currentNodeDomNavigationAxis(0)
, m_deviceMotionAndOrientationManager(this)
+ , m_geolocationManager(this)
#if ENABLE(TOUCH_EVENTS)
, m_forwardingTouchEvents(false)
#endif
@@ -471,7 +468,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V");
m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V");
m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V");
- m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V");
+ m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(ILjava/lang/String;I)V");
m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIIII)V");
m_javaGlue->m_updateTextSizeAndScroll = GetJMethod(env, clazz, "updateTextSizeAndScroll", "(IIIII)V");
m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
@@ -479,7 +476,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_needTouchEvents = GetJMethod(env, clazz, "needTouchEvents", "(Z)V");
m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V");
m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;JJ)V");
- m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(J)V");
+ m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(JJ)V");
m_javaGlue->m_populateVisitedLinks = GetJMethod(env, clazz, "populateVisitedLinks", "()V");
m_javaGlue->m_geolocationPermissionsShowPrompt = GetJMethod(env, clazz, "geolocationPermissionsShowPrompt", "(Ljava/lang/String;)V");
m_javaGlue->m_geolocationPermissionsHidePrompt = GetJMethod(env, clazz, "geolocationPermissionsHidePrompt", "()V");
@@ -499,9 +496,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_showRect = GetJMethod(env, clazz, "showRect", "(IIIIIIFFFF)V");
m_javaGlue->m_centerFitRect = GetJMethod(env, clazz, "centerFitRect", "(IIII)V");
m_javaGlue->m_setScrollbarModes = GetJMethod(env, clazz, "setScrollbarModes", "(II)V");
- m_javaGlue->m_setInstallableWebApp = GetJMethod(env, clazz, "setInstallableWebApp", "()V");
#if ENABLE(VIDEO)
- m_javaGlue->m_enterFullscreenForVideoLayer = GetJMethod(env, clazz, "enterFullscreenForVideoLayer", "(ILjava/lang/String;)V");
m_javaGlue->m_exitFullscreenVideo = GetJMethod(env, clazz, "exitFullscreenVideo", "()V");
#endif
m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
@@ -526,7 +521,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_textFieldInitDataGlue->m_maxLength = env->GetFieldID(tfidClazz, "mMaxLength", "I");
m_textFieldInitDataGlue->m_contentBounds = env->GetFieldID(tfidClazz, "mContentBounds", "Landroid/graphics/Rect;");
m_textFieldInitDataGlue->m_nodeLayerId = env->GetFieldID(tfidClazz, "mNodeLayerId", "I");
- m_textFieldInitDataGlue->m_contentRect = env->GetFieldID(tfidClazz, "mContentRect", "Landroid/graphics/Rect;");
+ m_textFieldInitDataGlue->m_clientRect = env->GetFieldID(tfidClazz, "mClientRect", "Landroid/graphics/Rect;");
m_textFieldInitDataGlue->m_constructor = GetJMethod(env, tfidClazz, "<init>", "()V");
env->DeleteLocalRef(tfidClazz);
@@ -728,13 +723,6 @@ void WebViewCore::clearContent()
updateLocale();
}
-bool WebViewCore::focusBoundsChanged()
-{
- bool result = m_focusBoundsChanged;
- m_focusBoundsChanged = false;
- return result;
-}
-
void WebViewCore::paintContents(WebCore::GraphicsContext* gc, WebCore::IntRect& dirty)
{
WebCore::FrameView* view = m_mainFrame->view();
@@ -1507,6 +1495,7 @@ bool WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos)
VisibleSelection selection(pos);
selection.expandUsingGranularity(WordGranularity);
SelectionController* selectionController = frame->selection();
+ selection = VisibleSelection(selection.start(), selection.end());
bool wordSelected = false;
if (selectionController->shouldChangeSelection(selection)) {
@@ -1566,7 +1555,8 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off
void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer,
const WebCore::Position& pos, const IntPoint& frameOffset,
- SelectText::HandleId handleId, int caretRectOffset, EAffinity affinity)
+ SelectText::HandleId handleId, SelectText::HandleType handleType,
+ int caretRectOffset, EAffinity affinity)
{
Node* node = pos.anchorNode();
LayerAndroid* layer = 0;
@@ -1584,8 +1574,9 @@ void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer,
caretRect.setX(absoluteOffset.x() - offset.x() + caretRectOffset);
caretRect.setY(absoluteOffset.y() - offset.y());
selectTextContainer->setCaretRect(handleId, caretRect);
+ selectTextContainer->setHandleType(handleId, handleType);
selectTextContainer->setTextRect(handleId,
- positionToTextRect(pos, affinity, offset));
+ positionToTextRect(pos, affinity, offset, caretRect));
}
bool WebViewCore::isLtr(const Position& position)
@@ -1601,14 +1592,28 @@ bool WebViewCore::isLtr(const Position& position)
return isLtr;
}
+static Node* findInputParent(Node* node)
+{
+ Node* testNode = node;
+ while (testNode) {
+ RenderObject* renderer = testNode->renderer();
+ if (renderer
+ && (renderer->isTextArea() || renderer->isTextControl())) {
+ return testNode;
+ }
+ testNode = testNode->parentOrHostNode();
+ }
+ return node;
+}
+
SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
{
bool isCaret = selection.isCaret();
+ Position base = selection.base();
+ Position extent = selection.extent();
if (selection.isNone() || (!selection.isContentEditable() && isCaret)
- || !selection.start().anchorNode()
- || !selection.start().anchorNode()->renderer()
- || !selection.end().anchorNode()
- || !selection.end().anchorNode()->renderer())
+ || !base.anchorNode() || !base.anchorNode()->renderer()
+ || !extent.anchorNode() || !extent.anchorNode()->renderer())
return 0;
RefPtr<Range> range = selection.firstRange();
@@ -1624,20 +1629,39 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint());
SelectText* selectTextContainer = new SelectText();
if (isCaret) {
- setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset,
- SelectText::LeftHandle, 0, selection.affinity());
- setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset,
- SelectText::RightHandle, 0, selection.affinity());
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::BaseHandle, SelectText::CenterHandle, 0,
+ selection.affinity());
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::ExtentHandle, SelectText::CenterHandle, 0,
+ selection.affinity());
} else {
- bool ltr = isLtr(selection.start());
- Position left = ltr ? selection.start() : selection.end();
- Position right = ltr ? selection.end() : selection.start();
- int leftOffset = isLtr(left) ? 0 : -1;
- int rightOffset = isLtr(right) ? 0 : -1;
- setSelectionCaretInfo(selectTextContainer, left, frameOffset,
- SelectText::LeftHandle, leftOffset, selection.affinity());
- setSelectionCaretInfo(selectTextContainer, right, frameOffset,
- SelectText::RightHandle, rightOffset, selection.affinity());
+ bool isBaseLtr = isLtr(base);
+ bool isBaseStart = comparePositions(base, extent) <= 0;
+ int baseOffset = isBaseLtr ? 0 : -1;
+ SelectText::HandleType baseHandleType = (isBaseLtr == isBaseStart)
+ ? SelectText::LeftHandle : SelectText::RightHandle;
+ EAffinity affinity = selection.affinity();
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::BaseHandle, baseHandleType, baseOffset, affinity);
+ bool isExtentLtr = isLtr(extent);
+ int extentOffset = isExtentLtr ? 0 : -1;
+ SelectText::HandleType extentHandleType = (isExtentLtr == isBaseStart)
+ ? SelectText::RightHandle : SelectText::LeftHandle;
+ setSelectionCaretInfo(selectTextContainer, extent, frameOffset,
+ SelectText::ExtentHandle, extentHandleType, extentOffset, affinity);
+ IntRect clipRect;
+ if (selection.isContentEditable()) {
+ Node* editable = findInputParent(base.anchorNode());
+ RenderObject* render = editable->renderer();
+ if (render && render->isBox() && !render->isBody()) {
+ RenderBox* renderBox = toRenderBox(render);
+ clipRect = renderBox->clientBoxRect();
+ FloatPoint pos = renderBox->localToAbsolute(clipRect.location());
+ clipRect.setX(pos.x());
+ clipRect.setY(pos.y());
+ }
+ }
Node* stopNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) {
@@ -1651,7 +1675,8 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
int layerId = platformLayerIdFromNode(node, &layer);
Vector<IntRect> rects;
renderText->absoluteRectsForRange(rects, startOffset, endOffset, true);
- selectTextContainer->addHighlightRegion(layer, rects, frameOffset);
+ selectTextContainer->addHighlightRegion(layer, rects, frameOffset,
+ clipRect);
}
}
selectTextContainer->setText(range->text());
@@ -1659,9 +1684,9 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
}
IntRect WebViewCore::positionToTextRect(const Position& position,
- EAffinity affinity, const WebCore::IntPoint& offset)
+ EAffinity affinity, const WebCore::IntPoint& offset, const IntRect& caretRect)
{
- IntRect textRect;
+ IntRect textRect = caretRect;
InlineBox* inlineBox;
int offsetIndex;
position.getInlineBoxAndOffset(affinity, inlineBox, offsetIndex);
@@ -1697,25 +1722,25 @@ IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point,
return IntPoint(point.x() + frameOffset.x(), point.y() + frameOffset.y());
}
-Position WebViewCore::trimSelectionPosition(const Position &start, const Position& stop)
+VisiblePosition WebViewCore::trimSelectionPosition(const VisiblePosition &start,
+ const VisiblePosition& stop)
{
int direction = comparePositions(start, stop);
if (direction == 0)
return start;
bool forward = direction < 0;
- EAffinity affinity = forward ? DOWNSTREAM : UPSTREAM;
bool move;
- Position pos = start;
+ VisiblePosition pos = start;
bool movedTooFar = false;
do {
move = true;
- Node* node = pos.anchorNode();
+ Node* node = pos.deepEquivalent().anchorNode();
if (node && node->isTextNode() && node->renderer()) {
RenderText *textRenderer = toRenderText(node->renderer());
move = !textRenderer->textLength();
}
if (move) {
- Position nextPos = forward ? pos.next() : pos.previous();
+ VisiblePosition nextPos = forward ? pos.next() : pos.previous();
movedTooFar = nextPos.isNull() || pos == nextPos
|| ((comparePositions(nextPos, stop) < 0) != forward);
pos = nextPos;
@@ -1726,47 +1751,65 @@ Position WebViewCore::trimSelectionPosition(const Position &start, const Positio
return pos;
}
-void WebViewCore::selectText(int startX, int startY, int endX, int endY)
+void WebViewCore::selectText(SelectText::HandleId handleId, int x, int y)
{
SelectionController* sc = focusedFrame()->selection();
- IntPoint startPoint = convertGlobalContentToFrameContent(IntPoint(startX, startY));
- VisiblePosition startPosition(visiblePositionForContentPoint(startPoint));
- IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY));
- VisiblePosition endPosition(visiblePositionForContentPoint(endPoint));
+ VisibleSelection selection = sc->selection();
+ Position base = selection.base();
+ Position extent = selection.extent();
+ IntPoint dragPoint = convertGlobalContentToFrameContent(IntPoint(x, y));
+ VisiblePosition dragPosition(visiblePositionForContentPoint(dragPoint));
- if (startPosition.isNull() || endPosition.isNull())
+ if (base.isNull() || extent.isNull() || dragPosition.isNull())
return;
+ bool draggingBase = (handleId == SelectText::BaseHandle);
+ if (draggingBase)
+ base = dragPosition.deepEquivalent();
+ else
+ extent = dragPosition.deepEquivalent();
- // Ensure startPosition is before endPosition
- if (comparePositions(startPosition, endPosition) > 0)
- swap(startPosition, endPosition);
+ bool baseIsStart = (comparePositions(base, extent) <= 0);
+ Position& start = baseIsStart ? base : extent;
+ Position& end = baseIsStart ? extent : base;
+ VisiblePosition startPosition(start, selection.affinity());
+ VisiblePosition endPosition(end, selection.affinity());
+ bool draggingStart = (baseIsStart == draggingBase);
- if (sc->isContentEditable()) {
- startPosition = sc->selection().visibleStart().honorEditableBoundaryAtOrAfter(startPosition);
- endPosition = sc->selection().visibleEnd().honorEditableBoundaryAtOrBefore(endPosition);
- if (startPosition.isNull() || endPosition.isNull()) {
+ if (draggingStart) {
+ if (selection.isRange()) {
+ startPosition = trimSelectionPosition(startPosition, endPosition);
+ if ((startPosition != endPosition) && isEndOfBlock(startPosition)) {
+ // Ensure startPosition is not at end of block
+ VisiblePosition nextStartPosition(startPosition.next());
+ if (nextStartPosition.isNotNull())
+ startPosition = nextStartPosition;
+ }
+ }
+ startPosition = endPosition.honorEditableBoundaryAtOrAfter(startPosition);
+ if (startPosition.isNull())
return;
+ start = startPosition.deepEquivalent();
+ if (selection.isCaret())
+ end = start;
+ } else {
+ if (selection.isRange()) {
+ endPosition = trimSelectionPosition(endPosition, startPosition);
+ if ((start != end) && isStartOfBlock(endPosition)) {
+ // Ensure endPosition is not at start of block
+ VisiblePosition prevEndPosition(endPosition.previous());
+ if (!prevEndPosition.isNull())
+ endPosition = prevEndPosition;
+ }
}
+ endPosition = startPosition.honorEditableBoundaryAtOrAfter(endPosition);
+ if (endPosition.isNull())
+ return;
+ end = endPosition.deepEquivalent();
+ if (selection.isCaret())
+ start = end;
}
- // Ensure startPosition is not at end of block
- if (startPosition != endPosition && isEndOfBlock(startPosition)) {
- VisiblePosition nextStartPosition(startPosition.next());
- if (!nextStartPosition.isNull())
- startPosition = nextStartPosition;
- }
- // Ensure endPosition is not at start of block
- if (startPosition != endPosition && isStartOfBlock(endPosition)) {
- VisiblePosition prevEndPosition(endPosition.previous());
- if (!prevEndPosition.isNull())
- endPosition = prevEndPosition;
- }
-
- Position start = startPosition.deepEquivalent();
- Position end = endPosition.deepEquivalent();
- start = trimSelectionPosition(start, end);
- end = trimSelectionPosition(end, start);
- VisibleSelection selection(start, end);
+ selection = VisibleSelection(base, extent);
// Only allow changes between caret positions or to text selection.
bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret());
if (selectChangeAllowed && sc->shouldChangeSelection(selection))
@@ -2944,33 +2987,31 @@ void WebViewCore::passToJs(int generation, const WTF::String& current,
WTF::String test = getInputText(focus);
if (test != current) {
// If the text changed during the key event, update the UI text field.
- updateTextfield(focus, false, test);
+ updateTextfield(focus, test);
}
// Now that the selection has settled down, send it.
updateTextSelection();
}
-WebCore::IntRect WebViewCore::scrollFocusedTextInput(float xPercent, int y)
+void WebViewCore::scrollFocusedTextInput(float xPercent, int y)
{
WebCore::Node* focus = currentFocus();
if (!focus) {
clearTextEntry();
- return WebCore::IntRect();
+ return;
}
WebCore::RenderTextControl* renderText = toRenderTextControl(focus);
if (!renderText) {
clearTextEntry();
- return WebCore::IntRect();
+ return;
}
- int x = (int) (xPercent * (renderText->scrollWidth() -
- renderText->clientWidth()));
+ int x = (int)round(xPercent * (renderText->scrollWidth() -
+ renderText->contentWidth()));
renderText->setScrollLeft(x);
renderText->setScrollTop(y);
focus->document()->frame()->selection()->recomputeCaretRect();
- LayerAndroid* layer = 0;
- platformLayerIdFromNode(focus, &layer);
- return absoluteContentRect(focus, layer);
+ updateTextSelection();
}
void WebViewCore::setFocusControllerActive(bool active)
@@ -3364,10 +3405,10 @@ bool WebViewCore::isAutoCompleteEnabled(Node* node)
return isEnabled;
}
-WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node,
+WebCore::IntRect WebViewCore::absoluteClientRect(WebCore::Node* node,
LayerAndroid* layer)
{
- IntRect contentRect;
+ IntRect clientRect;
if (node) {
RenderObject* render = node->renderer();
if (render && render->isBox() && !render->isBody()) {
@@ -3376,11 +3417,15 @@ WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node,
WebViewCore::layerToAbsoluteOffset(layer, offset);
RenderBox* renderBox = toRenderBox(render);
- contentRect = renderBox->absoluteContentBox();
- contentRect.move(-offset.x(), -offset.y());
+ clientRect = renderBox->clientBoxRect();
+ IntRect contentBox = renderBox->contentBoxRect();
+ clientRect.setX(contentBox.x());
+ clientRect.setWidth(contentBox.width());
+ FloatPoint absPos = renderBox->localToAbsolute(FloatPoint());
+ clientRect.move(absPos.x() - offset.x(), absPos.y() - offset.y());
}
}
- return contentRect;
+ return clientRect;
}
jobject WebViewCore::createTextFieldInitData(Node* node)
@@ -3417,7 +3462,7 @@ jobject WebViewCore::createTextFieldInitData(Node* node)
env->SetIntField(initData, classDef->m_maxLength, getMaxLength(node));
LayerAndroid* layer = 0;
int layerId = platformLayerIdFromNode(node, &layer);
- IntRect bounds = absoluteContentRect(node, layer);
+ IntRect bounds = absoluteClientRect(node, layer);
ScopedLocalRef<jobject> jbounds(env, intRectToRect(env, bounds));
env->SetObjectField(initData, classDef->m_contentBounds, jbounds.get());
env->SetIntField(initData, classDef->m_nodeLayerId, layerId);
@@ -3429,7 +3474,7 @@ jobject WebViewCore::createTextFieldInitData(Node* node)
contentRect.move(-rtc->scrollLeft(), -rtc->scrollTop());
}
ScopedLocalRef<jobject> jcontentRect(env, intRectToRect(env, contentRect));
- env->SetObjectField(initData, classDef->m_contentRect, jcontentRect.get());
+ env->SetObjectField(initData, classDef->m_clientRect, jcontentRect.get());
return initData;
}
@@ -3611,6 +3656,19 @@ bool WebViewCore::exceededDatabaseQuota(const WTF::String& url, const WTF::Strin
#endif
}
+/*
+ * TODO Note that this logic still needs to be cleaned up. Normally the
+ * information provided in this callback is used to resize the appcache.
+ * so we need to provide the current database size. However, webkit provides no
+ * way to reach this information. It can be calculated by fetching all the
+ * origins and their usage, however this is too expensize (requires one inner
+ * join operation for each origin). Rather, we simply return the maximum cache size,
+ * which should be equivalent to the current cache size. This is generally safe.
+ * However, setting the maximum database size to less than the current database size
+ * may cause a problem. In this case, ApplicationCacheStorage ("the owner of database")
+ * uses the updated value, while database internally ignores it and uses the current size
+ * as quota. This means the value we returned here won't reflect the actual database size.
+ */
bool WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
@@ -3618,7 +3676,7 @@ bool WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded)
AutoJObject javaObject = m_javaGlue->object(env);
if (!javaObject.get())
return false;
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded);
+ env->CallVoidMethod(javaObject.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded, WebCore::cacheStorage().maximumSize());
checkException(env);
return true;
#endif
@@ -3848,8 +3906,7 @@ void WebViewCore::updateTextSizeAndScroll(WebCore::Node* node)
checkException(env);
}
-void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword,
- const WTF::String& text)
+void WebViewCore::updateTextfield(WebCore::Node* ptr, const WTF::String& text)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject javaObject = m_javaGlue->object(env);
@@ -3857,15 +3914,9 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword,
return;
if (m_blockTextfieldUpdates)
return;
- if (changeToPassword) {
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield,
- (int) ptr, true, 0, m_textGeneration);
- checkException(env);
- return;
- }
jstring string = wtfStringToJstring(env, text);
env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield,
- (int) ptr, false, string, m_textGeneration);
+ (int) ptr, string, m_textGeneration);
env->DeleteLocalRef(string);
checkException(env);
}
@@ -4059,27 +4110,11 @@ void WebViewCore::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode
checkException(env);
}
-void WebViewCore::notifyWebAppCanBeInstalled()
-{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject javaObject = m_javaGlue->object(env);
- if (!javaObject.get())
- return;
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_setInstallableWebApp);
- checkException(env);
-}
-
#if ENABLE(VIDEO)
-void WebViewCore::enterFullscreenForVideoLayer(int layerId, const WTF::String& url)
+void WebViewCore::enterFullscreenForVideoLayer()
{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject javaObject = m_javaGlue->object(env);
- if (!javaObject.get())
- return;
- jstring jUrlStr = wtfStringToJstring(env, url);
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_enterFullscreenForVideoLayer, layerId, jUrlStr);
+ // Just need to update the video mode, to avoid multiple exit full screen.
m_fullscreenVideoMode = true;
- checkException(env);
}
void WebViewCore::exitFullscreenVideo()
@@ -4373,6 +4408,44 @@ void WebViewCore::getLocale(String& language, String& region)
region = String(propRegn, 2);
}
+// generate bcp47 identifier for the supplied language/region
+static void toLanguageTag(char* output, size_t outSize, const String& language,
+ const String& region) {
+ if (output == NULL || outSize <= 0)
+ return;
+ String locale = language;
+ locale.append('_');
+ locale.append(region);
+ char canonicalChars[ULOC_FULLNAME_CAPACITY];
+ UErrorCode uErr = U_ZERO_ERROR;
+ uloc_canonicalize(locale.ascii().data(), canonicalChars,
+ ULOC_FULLNAME_CAPACITY, &uErr);
+ if (U_SUCCESS(uErr)) {
+ char likelyChars[ULOC_FULLNAME_CAPACITY];
+ uErr = U_ZERO_ERROR;
+ uloc_addLikelySubtags(canonicalChars, likelyChars,
+ ULOC_FULLNAME_CAPACITY, &uErr);
+ if (U_SUCCESS(uErr)) {
+ uErr = U_ZERO_ERROR;
+ uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
+ if (U_SUCCESS(uErr)) {
+ return;
+ } else {
+ ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
+ u_errorName(uErr));
+ }
+ } else {
+ ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s", canonicalChars,
+ u_errorName(uErr));
+ }
+ } else {
+ ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale.ascii().data(),
+ u_errorName(uErr));
+ }
+ // unable to build a proper language identifier
+ output[0] = '\0';
+}
+
void WebViewCore::updateLocale()
{
static String prevLang;
@@ -4387,6 +4460,9 @@ void WebViewCore::updateLocale()
prevRegn = region;
GlyphPageTreeNode::resetRoots();
fontCache()->invalidate();
+ char langTag[ULOC_FULLNAME_CAPACITY];
+ toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, language, region);
+ FontPlatformData::setDefaultLanguage(langTag);
}
}
@@ -4505,12 +4581,10 @@ static void PassToJs(JNIEnv* env, jobject obj, jint nativeClass,
}
static void ScrollFocusedTextInput(JNIEnv* env, jobject obj, jint nativeClass,
- jfloat xPercent, jint y, jobject contentBounds)
+ jfloat xPercent, jint y)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- IntRect bounds = viewImpl->scrollFocusedTextInput(xPercent, y);
- if (contentBounds)
- GraphicsJNI::irect_to_jrect(bounds, env, contentBounds);
+ viewImpl->scrollFocusedTextInput(xPercent, y);
}
static void SetFocusControllerActive(JNIEnv* env, jobject obj, jint nativeClass,
@@ -4765,10 +4839,7 @@ static void GeolocationPermissionsProvide(JNIEnv* env, jobject obj,
jint nativeClass, jstring origin, jboolean allow, jboolean remember)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- Frame* frame = viewImpl->mainFrame();
-
- ChromeClientAndroid* chromeClient = static_cast<ChromeClientAndroid*>(frame->page()->chrome()->client());
- chromeClient->provideGeolocationPermissions(jstringToWtfString(env, origin), allow, remember);
+ viewImpl->geolocationManager()->provideRealClientPermissionState(jstringToWtfString(env, origin), allow, remember);
}
static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass,
@@ -4777,20 +4848,6 @@ static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass,
WebCore::SchemeRegistry::registerURLSchemeAsLocal(jstringToWtfString(env, scheme));
}
-static bool FocusBoundsChanged(JNIEnv* env, jobject obj, jint nativeClass)
-{
- return reinterpret_cast<WebViewCore*>(nativeClass)->focusBoundsChanged();
-}
-
-static void SetIsPaused(JNIEnv* env, jobject obj, jint nativeClass,
- jboolean isPaused)
-{
- // tell the webcore thread to stop thinking while we do other work
- // (selection and scrolling). This has nothing to do with the lifecycle
- // pause and resume.
- reinterpret_cast<WebViewCore*>(nativeClass)->setIsPaused(isPaused);
-}
-
static void Pause(JNIEnv* env, jobject obj, jint nativeClass)
{
// This is called for the foreground tab when the browser is put to the
@@ -4798,50 +4855,36 @@ static void Pause(JNIEnv* env, jobject obj, jint nativeClass)
// browser). The browser can only be killed by the system when it is in the
// background, so saving the Geolocation permission state now ensures that
// is maintained when the browser is killed.
- WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- ChromeClient* chromeClient = viewImpl->mainFrame()->page()->chrome()->client();
- ChromeClientAndroid* chromeClientAndroid = static_cast<ChromeClientAndroid*>(chromeClient);
- chromeClientAndroid->storeGeolocationPermissions();
+ GeolocationPermissions::maybeStorePermanentPermissions();
+ WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
Frame* mainFrame = viewImpl->mainFrame();
- for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
- Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation();
- if (geolocation)
- geolocation->suspend();
- }
if (mainFrame)
mainFrame->settings()->setMinDOMTimerInterval(BACKGROUND_TIMER_INTERVAL);
viewImpl->deviceMotionAndOrientationManager()->maybeSuspendClients();
+ viewImpl->geolocationManager()->suspendRealClient();
ANPEvent event;
SkANP::InitEvent(&event, kLifecycle_ANPEventType);
event.data.lifecycle.action = kPause_ANPLifecycleAction;
viewImpl->sendPluginEvent(event);
-
- viewImpl->setIsPaused(true);
}
static void Resume(JNIEnv* env, jobject obj, jint nativeClass)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
Frame* mainFrame = viewImpl->mainFrame();
- for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
- Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation();
- if (geolocation)
- geolocation->resume();
- }
if (mainFrame)
mainFrame->settings()->setMinDOMTimerInterval(FOREGROUND_TIMER_INTERVAL);
viewImpl->deviceMotionAndOrientationManager()->maybeResumeClients();
+ viewImpl->geolocationManager()->resumeRealClient();
ANPEvent event;
SkANP::InitEvent(&event, kLifecycle_ANPEventType);
event.data.lifecycle.action = kResume_ANPLifecycleAction;
viewImpl->sendPluginEvent(event);
-
- viewImpl->setIsPaused(false);
}
static void FreeMemory(JNIEnv* env, jobject obj, jint nativeClass)
@@ -4959,10 +5002,10 @@ static jobject GetText(JNIEnv* env, jobject obj, jint nativeClass,
}
static void SelectText(JNIEnv* env, jobject obj, jint nativeClass,
- jint startX, jint startY, jint endX, jint endY)
+ jint handleId, jint x, jint y)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->selectText(startX, startY, endX, endY);
+ viewImpl->selectText(static_cast<SelectText::HandleId>(handleId), x, y);
}
static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass)
@@ -5006,8 +5049,6 @@ static int FindNext(JNIEnv* env, jobject obj, jint nativeClass,
static JNINativeMethod gJavaWebViewCoreMethods[] = {
{ "nativeClearContent", "(I)V",
(void*) ClearContent },
- { "nativeFocusBoundsChanged", "(I)Z",
- (void*) FocusBoundsChanged } ,
{ "nativeKey", "(IIIIZZZZ)Z",
(void*) Key },
{ "nativeContentInvalidateAll", "(I)V",
@@ -5034,7 +5075,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) MoveMouse },
{ "passToJs", "(IILjava/lang/String;IIZZZZ)V",
(void*) PassToJs },
- { "nativeScrollFocusedTextInput", "(IFILandroid/graphics/Rect;)V",
+ { "nativeScrollFocusedTextInput", "(IFI)V",
(void*) ScrollFocusedTextInput },
{ "nativeSetFocusControllerActive", "(IZ)V",
(void*) SetFocusControllerActive },
@@ -5072,7 +5113,6 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SetNewStorageLimit },
{ "nativeGeolocationPermissionsProvide", "(ILjava/lang/String;ZZ)V",
(void*) GeolocationPermissionsProvide },
- { "nativeSetIsPaused", "(IZ)V", (void*) SetIsPaused },
{ "nativePause", "(I)V", (void*) Pause },
{ "nativeResume", "(I)V", (void*) Resume },
{ "nativeFreeMemory", "(I)V", (void*) FreeMemory },
@@ -5100,7 +5140,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) InsertText },
{ "nativeGetText", "(IIIII)Ljava/lang/String;",
(void*) GetText },
- { "nativeSelectText", "(IIIII)V",
+ { "nativeSelectText", "(IIII)V",
(void*) SelectText },
{ "nativeClearTextSelection", "(I)V",
(void*) ClearSelection },
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 5264f7f..4e223b3 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -30,6 +30,7 @@
#include "DOMSelection.h"
#include "FileChooser.h"
#include "FocusDirection.h"
+#include "GeolocationManager.h"
#include "HitTestResult.h"
#include "PicturePile.h"
#include "PlatformGraphicsContext.h"
@@ -201,13 +202,9 @@ namespace android {
/**
* Tell the java side to update the focused textfield
* @param pointer Pointer to the node for the input field.
- * @param changeToPassword If true, we are changing the textfield to
- * a password field, and ignore the WTF::String
- * @param text If changeToPassword is false, this is the new text that
- * should go into the textfield.
+ * @param text This is the new text that should go into the textfield.
*/
- void updateTextfield(WebCore::Node* pointer,
- bool changeToPassword, const WTF::String& text);
+ void updateTextfield(WebCore::Node* pointer, const WTF::String& text);
/**
* Tell the java side to update the current selection in the focused
@@ -396,7 +393,7 @@ namespace android {
/**
* Scroll the focused textfield to (x, y) in document space
*/
- WebCore::IntRect scrollFocusedTextInput(float x, int y);
+ void scrollFocusedTextInput(float x, int y);
/**
* Set the FocusController's active and focused states, so that
* the caret will draw (true) or not.
@@ -508,8 +505,6 @@ namespace android {
// reset the picture set to empty
void clearContent();
- bool focusBoundsChanged();
-
// record content in a new BaseLayerAndroid, copying the layer tree as well
WebCore::BaseLayerAndroid* recordContent(SkIPoint* );
@@ -526,8 +521,6 @@ namespace android {
WebCore::Frame* mainFrame() const { return m_mainFrame; }
WebCore::Frame* focusedFrame() const;
- void notifyWebAppCanBeInstalled();
-
void deleteText(int startX, int startY, int endX, int endY);
WTF::String getText(int startX, int startY, int endX, int endY);
void insertText(const WTF::String &text);
@@ -539,19 +532,18 @@ namespace android {
void updateMatchCount() const;
#if ENABLE(VIDEO)
- void enterFullscreenForVideoLayer(int layerId, const WTF::String& url);
+ void enterFullscreenForVideoLayer();
void exitFullscreenVideo();
#endif
void setWebTextViewAutoFillable(int queryId, const string16& previewSummary);
DeviceMotionAndOrientationManager* deviceMotionAndOrientationManager() { return &m_deviceMotionAndOrientationManager; }
+ GeolocationManager* geolocationManager() { return &m_geolocationManager; }
void listBoxRequest(WebCoreReply* reply, const uint16_t** labels,
size_t count, const int enabled[], size_t enabledCount,
bool multiple, const int selected[], size_t selectedCountOrSelection);
- bool isPaused() const { return m_isPaused; }
- void setIsPaused(bool isPaused) { m_isPaused = isPaused; }
bool drawIsPaused() const;
// The actual content (without title bar) size in doc coordinate
int screenWidth() const { return m_screenWidth; }
@@ -580,7 +572,7 @@ namespace android {
int startX, int startY, int endX, int endY);
static int platformLayerIdFromNode(WebCore::Node* node,
WebCore::LayerAndroid** outLayer = 0);
- void selectText(int startX, int startY, int endX, int endY);
+ void selectText(SelectText::HandleId handleId, int x, int y);
bool selectWordAt(int x, int y);
// Converts from the global content coordinates that WebView sends
@@ -728,18 +720,20 @@ namespace android {
void setSelectionCaretInfo(SelectText* selectTextContainer,
const WebCore::Position& position,
const WebCore::IntPoint& frameOffset,
- SelectText::HandleId handleId, int offset,
- EAffinity affinity);
+ SelectText::HandleId handleId, SelectText::HandleType handleType,
+ int offset, EAffinity affinity);
static int getMaxLength(WebCore::Node* node);
static WTF::String getFieldName(WebCore::Node* node);
static bool isAutoCompleteEnabled(WebCore::Node* node);
- WebCore::IntRect absoluteContentRect(WebCore::Node* node,
+ WebCore::IntRect absoluteClientRect(WebCore::Node* node,
WebCore::LayerAndroid* layer);
static WebCore::IntRect positionToTextRect(const WebCore::Position& position,
- WebCore::EAffinity affinity, const WebCore::IntPoint& offset);
+ WebCore::EAffinity affinity, const WebCore::IntPoint& offset,
+ const WebCore::IntRect& caretRect);
static bool isLtr(const WebCore::Position& position);
- static WebCore::Position trimSelectionPosition(
- const WebCore::Position& start, const WebCore::Position& stop);
+ static WebCore::VisiblePosition trimSelectionPosition(
+ const WebCore::VisiblePosition& start,
+ const WebCore::VisiblePosition& stop);
// called from constructor, to add this to a global list
static void addInstance(WebViewCore*);
@@ -759,7 +753,6 @@ namespace android {
// Used in passToJS to avoid updating the UI text field until after the
// key event has been processed.
bool m_blockTextfieldUpdates;
- bool m_focusBoundsChanged;
bool m_skipContentDraw;
// Passed in with key events to know when they were generated. Store it
// with the cache so that we can ignore stale text changes.
@@ -782,7 +775,6 @@ namespace android {
int m_textWrapWidth;
float m_scale;
WebCore::PageGroup* m_groupForVisitedLinks;
- bool m_isPaused;
int m_cacheMode;
bool m_fullscreenVideoMode;
@@ -801,6 +793,7 @@ namespace android {
int m_screenOnCounter;
WebCore::Node* m_currentNodeDomNavigationAxis;
DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager;
+ GeolocationManager m_geolocationManager;
#if ENABLE(TOUCH_EVENTS)
bool m_forwardingTouchEvents;
diff --git a/Source/WebKit/android/nav/DrawExtra.cpp b/Source/WebKit/android/nav/DrawExtra.cpp
index 2f57dc1..a7d686c 100644
--- a/Source/WebKit/android/nav/DrawExtra.cpp
+++ b/Source/WebKit/android/nav/DrawExtra.cpp
@@ -52,7 +52,8 @@ SkRegion* RegionLayerDrawExtra::getHighlightRegionsForLayer(const LayerAndroid*
}
void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects,
- const IntPoint& additionalOffset)
+ const IntPoint& additionalOffset,
+ const IntRect& clipRect)
{
if (rects.isEmpty())
return;
@@ -66,6 +67,11 @@ void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const V
WebViewCore::layerToAbsoluteOffset(layer, offset);
for (size_t i = 0; i < rects.size(); i++) {
IntRect r = rects.at(i);
+ if (!clipRect.isEmpty()) {
+ r.intersect(clipRect);
+ if (r.isEmpty())
+ continue; // don't add it to the region
+ }
r.move(-offset.x(), -offset.y());
region->op(r.x(), r.y(), r.maxX(), r.maxY(), SkRegion::kUnion_Op);
}
diff --git a/Source/WebKit/android/nav/DrawExtra.h b/Source/WebKit/android/nav/DrawExtra.h
index cc94476..1850b6b 100644
--- a/Source/WebKit/android/nav/DrawExtra.h
+++ b/Source/WebKit/android/nav/DrawExtra.h
@@ -65,7 +65,8 @@ public:
virtual ~RegionLayerDrawExtra();
void addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects,
- const IntPoint& additionalOffset = IntPoint());
+ const IntPoint& additionalOffset = IntPoint(),
+ const IntRect& clipRect = IntRect());
virtual void draw(SkCanvas*, LayerAndroid*);
virtual void drawGL(GLExtras*, const LayerAndroid*);
diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h
index aaaf3bb..8f7592d 100644
--- a/Source/WebKit/android/nav/SelectText.h
+++ b/Source/WebKit/android/nav/SelectText.h
@@ -35,8 +35,13 @@ namespace android {
class SelectText : public RegionLayerDrawExtra {
public:
enum HandleId {
+ BaseHandle = 0,
+ ExtentHandle = 1,
+ };
+ enum HandleType {
LeftHandle = 0,
- RightHandle = 1,
+ CenterHandle = 1,
+ RightHandle = 2,
};
IntRect& caretRect(HandleId id) { return m_caretRects[id]; }
@@ -48,11 +53,14 @@ public:
void setText(const String& text) { m_text = text.threadsafeCopy(); }
String& getText() { return m_text; }
+ HandleType getHandleType(HandleId id) { return m_handleType[id]; }
+ void setHandleType(HandleId id, HandleType type) { m_handleType[id] = type; }
private:
IntRect m_caretRects[2];
IntRect m_textRects[2];
int m_caretLayerId[2];
+ HandleType m_handleType[2];
String m_text;
};
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index a67b5fd..66dbdc1 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -32,6 +32,7 @@
#include "BaseLayerAndroid.h"
#include "BaseRenderer.h"
#include "DrawExtra.h"
+#include "DumpLayer.h"
#include "Frame.h"
#include "GLWebViewState.h"
#include "GraphicsJNI.h"
@@ -57,7 +58,6 @@
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"
-#include "android_graphics.h"
#ifdef GET_NATIVE_VIEW
#undef GET_NATIVE_VIEW
@@ -716,7 +716,7 @@ void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect)
if (findMaskedRectsForLayer(m_baseLayer, rects, movingLayerId)) {
float maxSize = 0.0;
const FloatRect* largest = 0;
- for (int i = 0; i < rects.size(); i++) {
+ for (unsigned int i = 0; i < rects.size(); i++) {
const FloatRect& rect = rects[i];
float size = rect.width() * rect.height();
if (size > maxSize) {
@@ -731,6 +731,29 @@ void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect)
}
}
+bool isHandleLeft(SelectText::HandleId handleId)
+{
+ SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
+ if (!selectText)
+ return (handleId == SelectText::BaseHandle);
+
+ return (selectText->getHandleType(handleId) == SelectText::LeftHandle);
+}
+
+bool isPointVisible(int layerId, int contentX, int contentY)
+{
+ bool isVisible = true;
+ const TransformationMatrix* transform = getLayerTransform(layerId);
+ if (transform) {
+ // layer is guaranteed to be non-NULL because of getLayerTransform
+ LayerAndroid* layer = m_baseLayer->findById(layerId);
+ IntRect rect = layer->visibleContentArea();
+ rect = transform->mapRect(rect);
+ isVisible = rect.contains(contentX, contentY);
+ }
+ return isVisible;
+}
+
private: // local state for WebView
bool m_isDrawingPaused;
// private to getFrameCache(); other functions operate in a different thread
@@ -972,6 +995,28 @@ static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pic
GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture);
}
+static jboolean nativeDumpLayerContentToPicture(JNIEnv *env, jobject obj, jint instance,
+ jstring jclassName, jint layerId, jobject pict)
+{
+ bool success = false;
+ SkPicture* picture = GraphicsJNI::getNativePicture(env, pict);
+ std::string classname = jstringToStdString(env, jclassName);
+ BaseLayerAndroid* baseLayer = reinterpret_cast<WebView*>(instance)->getBaseLayer();
+ LayerAndroid* layer = baseLayer->findById(layerId);
+ SkSafeRef(layer);
+ if (layer && layer->subclassName() == classname) {
+ LayerContent* content = layer->content();
+ if (content) {
+ SkCanvas* canvas = picture->beginRecording(content->width(), content->height());
+ content->draw(canvas);
+ picture->endRecording();
+ success = true;
+ }
+ }
+ SkSafeUnref(layer);
+ return success;
+}
+
static bool nativeHasContent(JNIEnv *env, jobject obj)
{
return GET_NATIVE_VIEW(env, obj)->hasContent();
@@ -1164,7 +1209,8 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
if (baseLayer) {
FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w");
if (file) {
- baseLayer->dumpLayers(file, 0);
+ WebCore::FileLayerDumper dumper(file);
+ baseLayer->dumpLayers(&dumper);
fclose(file);
}
}
@@ -1288,6 +1334,20 @@ static void nativeFindMaxVisibleRect(JNIEnv *env, jobject obj, jint nativeView,
GraphicsJNI::irect_to_jrect(nativeRect, env, visibleContentRect);
}
+static bool nativeIsHandleLeft(JNIEnv *env, jobject obj, jint nativeView,
+ jint handleId)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ return webview->isHandleLeft(static_cast<SelectText::HandleId>(handleId));
+}
+
+static bool nativeIsPointVisible(JNIEnv *env, jobject obj, jint nativeView,
+ jint layerId, jint contentX, jint contentY)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ return webview->isPointVisible(layerId, contentX, contentY);
+}
+
/*
* JNI registration
*/
@@ -1318,6 +1378,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeGetBaseLayer },
{ "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V",
(void*) nativeCopyBaseContentToPicture },
+ { "nativeDumpLayerContentToPicture", "(ILjava/lang/String;ILandroid/graphics/Picture;)Z",
+ (void*) nativeDumpLayerContentToPicture },
{ "nativeHasContent", "()Z",
(void*) nativeHasContent },
{ "nativeDiscardAllTextures", "()V",
@@ -1366,6 +1428,10 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetHwAccelerated },
{ "nativeFindMaxVisibleRect", "(IILandroid/graphics/Rect;)V",
(void*) nativeFindMaxVisibleRect },
+ { "nativeIsHandleLeft", "(II)Z",
+ (void*) nativeIsHandleLeft },
+ { "nativeIsPointVisible", "(IIII)Z",
+ (void*) nativeIsPointVisible },
};
int registerWebView(JNIEnv* env)
diff --git a/Source/WebKit/android/plugins/ANPSoundInterface.cpp b/Source/WebKit/android/plugins/ANPSoundInterface.cpp
index 9d19443..929832b 100644
--- a/Source/WebKit/android/plugins/ANPSoundInterface.cpp
+++ b/Source/WebKit/android/plugins/ANPSoundInterface.cpp
@@ -100,7 +100,7 @@ static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate,
track->mTrack = new android::AudioTrack(AUDIO_STREAM_MUSIC,
sampleRate,
fromANPFormat(format),
- (channelCount > 1) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
+ audio_channel_out_mask_from_count(channelCount),
0, // frameCount
(audio_output_flags_t) 0, // AUDIO_OUTPUT_FLAG_NONE,
callbackProc,
diff --git a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
index 92dbbcd..2b593e2 100644
--- a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
+++ b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
@@ -30,7 +30,6 @@
#include "PluginView.h"
#include "PluginWidgetAndroid.h"
#include "SkANP.h"
-#include "android_graphics.h"
#include <JNIUtility.h>
#include <gui/Surface.h>
#include <ui/Rect.h>
diff --git a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
index 09bb24e..2fd2ef4 100644
--- a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -42,7 +42,6 @@
#include "SkString.h"
#include "SkTime.h"
#include "WebViewCore.h"
-#include "android_graphics.h"
#include <JNIUtility.h>
//#define PLUGIN_DEBUG_LOCAL // controls the printing of log messages
@@ -225,7 +224,7 @@ void PluginWidgetAndroid::viewInvalidate() {
m_core->viewInvalidate(rect);
}
-void PluginWidgetAndroid::draw(SkCanvas* canvas) {
+void PluginWidgetAndroid::draw(PlatformGraphicsContext* context) {
if (NULL == m_flipPixelRef || !m_flipPixelRef->isDirty()) {
return;
}
@@ -249,10 +248,11 @@ void PluginWidgetAndroid::draw(SkCanvas* canvas) {
bitmap) &&
pkg->pluginFuncs()->event(instance, &event)) {
- if (canvas && m_pluginWindow) {
+ if (context && m_pluginWindow) {
SkBitmap bm(bitmap);
bm.setPixelRef(m_flipPixelRef);
- canvas->drawBitmap(bm, 0, 0);
+ IntRect dst(0, 0, bm.width(), bm.height());
+ context->drawBitmapRect(bm, 0, dst);
}
}
break;
diff --git a/Source/WebKit/android/plugins/PluginWidgetAndroid.h b/Source/WebKit/android/plugins/PluginWidgetAndroid.h
index 87612dd..73b116b 100644
--- a/Source/WebKit/android/plugins/PluginWidgetAndroid.h
+++ b/Source/WebKit/android/plugins/PluginWidgetAndroid.h
@@ -28,6 +28,7 @@
#include "android_npapi.h"
#include "ANPSystem_npapi.h"
+#include "GraphicsContext.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "MediaLayer.h"
@@ -98,7 +99,7 @@ struct PluginWidgetAndroid {
/* Called to draw into the plugin's bitmap. If canvas is non-null, the
bitmap itself is then drawn into the canvas.
*/
- void draw(SkCanvas* canvas = NULL);
+ void draw(PlatformGraphicsContext* context = NULL);
/* Send this event to the plugin instance. A non-zero value will be
returned if the plugin handled the event.
diff --git a/Source/WebKit/android/smoke/MessageThread.cpp b/Source/WebKit/android/smoke/MessageThread.cpp
deleted file mode 100644
index 97ab18c..0000000
--- a/Source/WebKit/android/smoke/MessageThread.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2010, 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 THE COPYRIGHT OWNER 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 "MessageThread"
-
-#include "config.h"
-
-#include <sys/time.h>
-#include <time.h>
-
-#include "MessageThread.h"
-#include "ScriptController.h"
-
-#include <utils/Log.h>
-
-namespace android {
-
-static bool compareMessages(const Message& msg1,
- const Message& msg2,
- bool memberIsNull) {
- return (msg1.object() == msg2.object() &&
- (memberIsNull || msg1.member() == msg2.member()));
-}
-
-bool MessageQueue::hasMessages(const Message& message) {
- AutoMutex lock(m_mutex);
-
- static const Message::GenericMemberFunction nullMember = NULL;
- const bool memberIsNull = message.member() == nullMember;
-
- for (list<Message*>::iterator it = m_messages.begin();
- it != m_messages.end(); ++it) {
- Message* m = *it;
- if (compareMessages(message, *m, memberIsNull))
- return true;
- }
- return false;
-}
-
-void MessageQueue::remove(const Message& message) {
- AutoMutex lock(m_mutex);
-
- static const Message::GenericMemberFunction nullMember = NULL;
- const bool memberIsNull = message.member() == nullMember;
-
- for (list<Message*>::iterator it = m_messages.begin();
- it != m_messages.end(); ++it) {
- Message* m = *it;
- if (compareMessages(message, *m, memberIsNull)) {
- it = m_messages.erase(it);
- delete m;
- }
- }
-}
-
-void MessageQueue::post(Message* message) {
- AutoMutex lock(m_mutex);
-
- double when = message->m_when;
- ALOG_ASSERT(when > 0, "Message time may not be 0");
-
- list<Message*>::iterator it;
- for (it = m_messages.begin(); it != m_messages.end(); ++it) {
- Message* m = *it;
- if (when < m->m_when) {
- break;
- }
- }
- m_messages.insert(it, message);
- m_condition.signal();
-}
-
-void MessageQueue::postAtFront(Message* message) {
- AutoMutex lock(m_mutex);
- message->m_when = 0;
- m_messages.push_front(message);
-}
-
-Message* MessageQueue::next() {
- AutoMutex lock(m_mutex);
- while (true) {
- if (m_messages.empty()) {
- // No messages, wait until another arrives
- m_condition.wait(m_mutex);
- }
- Message* next = m_messages.front();
- double now = WTF::currentTimeMS();
- double diff = next->m_when - now;
- if (diff > 0) {
- // Not time for this message yet, wait the difference in nanos
- m_condition.waitRelative(m_mutex,
- static_cast<nsecs_t>(diff * 1000000) /* nanos */);
- } else {
- // Time for this message to run.
- m_messages.pop_front();
- return next;
- }
- }
-}
-
-bool MessageThread::threadLoop() {
- WebCore::ScriptController::initializeThreading();
-
- while (true) {
- Message* message = m_queue.next();
- if (message != NULL) {
- message->run();
- }
- }
- return false;
-}
-
-// Global thread object obtained by messageThread().
-static sp<MessageThread> gMessageThread;
-
-MessageThread* messageThread() {
- if (gMessageThread == NULL) {
- gMessageThread = new MessageThread();
- gMessageThread->run("WebCoreThread");
- }
- return gMessageThread.get();
-}
-
-} // namespace android
diff --git a/Source/WebKit/android/smoke/MessageThread.h b/Source/WebKit/android/smoke/MessageThread.h
deleted file mode 100644
index 34ff4af..0000000
--- a/Source/WebKit/android/smoke/MessageThread.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2010, 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 THE COPYRIGHT OWNER 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.
- */
-
-#ifndef MessageThread_h
-#define MessageThread_h
-
-#include <list>
-
-#include "MessageTypes.h"
-
-#include <utils/threads.h>
-
-using std::list;
-
-namespace android {
-
-class MessageQueue {
-public:
- MessageQueue() {}
-
- // Return true if the queue has messages with the given object and member
- // function. If member is null, return true if the message has the same
- // object.
- template <class T>
- bool hasMessages(T* object, void (T::*member)(void));
-
- // Remove all messages with the given object and member function. If
- // member is null, remove all messages with the given object.
- template <class T>
- void remove(T* object, void (T::*member)(void));
-
- // Post a new message to the queue.
- void post(Message* closure);
-
- // Post a new message at the front of the queue.
- void postAtFront(Message* closure);
-
- // Obtain the next message. Blocks until either a new message arrives or
- // we reach the time of the next message.
- Message* next();
-
-private:
- bool hasMessages(const Message& message);
- void remove(const Message& message);
-
- list<Message*> m_messages;
- Mutex m_mutex;
- Condition m_condition;
-};
-
-template <class T>
-bool MessageQueue::hasMessages(T* object, void (T::*member)(void)) {
- MemberFunctionMessage<T, void> message(object, member);
- return hasMessages(message);
-}
-
-template <class T>
-void MessageQueue::remove(T* object, void (T::*member)(void)) {
- MemberFunctionMessage<T, void> message(object, member);
- remove(message);
-}
-
-class MessageThread : public Thread {
-public:
- MessageQueue& queue() { return m_queue; }
-
-private:
- MessageThread() : Thread(true /* canCallJava */) {}
-
- virtual bool threadLoop();
-
- MessageQueue m_queue;
- // Used for thread initialization
- Mutex m_mutex;
- Condition m_condition;
-
- friend MessageThread* messageThread();
-};
-
-// Get (possibly creating) the global MessageThread object used to pass
-// messages to WebCore.
-MessageThread* messageThread();
-
-} // namespace android
-
-#endif // MessageThread_h
diff --git a/Source/WebKit/android/smoke/MessageTypes.h b/Source/WebKit/android/smoke/MessageTypes.h
deleted file mode 100644
index 4d30648..0000000
--- a/Source/WebKit/android/smoke/MessageTypes.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2010, 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 THE COPYRIGHT OWNER 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.
- */
-
-#ifndef MessageTypes_h
-#define MessageTypes_h
-
-#include <wtf/CurrentTime.h>
-
-// TODO(phanna): autogenerate these types!
-
-namespace android {
-
-// Forward declared for friendship!
-class MessageQueue;
-
-// Removes the reference from the typename so we store the actual value in the
-// closure.
-template <typename T> struct remove_reference { typedef T type; };
-template <typename T> struct remove_reference<T&> { typedef T type; };
-
-// Prevent the compiler from inferring the type.
-template <typename T> struct identity { typedef T type; };
-
-// Message base class. Defines the public run() method and contains generic
-// object and member function variables for use in MessageQueue.
-//
-// Note: The template subclass MemberFunctionMessage casts its object and
-// member function to the generic void* and Message::* types. During run(),
-// each template specialization downcasts to the original type and invokes the
-// correct function. This may seem dangerous but the compiler enforces
-// correctness in NewMessage and in the template constructor.
-class Message {
-public:
- typedef void (Message::*GenericMemberFunction)(void);
-
- virtual ~Message() {}
- virtual void run() = 0;
-
- // The wall time that the message is supposed to run.
- double m_when;
-
- void* object() const { return m_object; }
- GenericMemberFunction member() const { return m_member; }
-
-protected:
- Message(void* object, GenericMemberFunction member, long delay = 0)
- : m_object(object)
- , m_member(member) {
- m_when = WTF::currentTimeMS() + delay;
- }
-
- // Downcast back to the original template params in run(). Also accessed
- // by MessageQueue to compare messages.
- void* m_object;
- GenericMemberFunction m_member;
-
-private:
- // Disallow copy
- Message(const Message&);
-};
-
-// Forward declaration for partial specialization.
-template <class T, typename A1>
-class MemberFunctionMessage;
-
-template <class T>
-class MemberFunctionMessage<T, void> : public Message {
-private:
- typedef void (T::*MemberSignature)();
-
-public:
- inline MemberFunctionMessage(T* object,
- MemberSignature member,
- long delay = 0)
- : Message(reinterpret_cast<void*>(object),
- reinterpret_cast<GenericMemberFunction>(member),
- delay) {}
-
- virtual void run() {
- MemberSignature member = reinterpret_cast<MemberSignature>(m_member);
- (reinterpret_cast<T*>(m_object)->*member)();
- delete this;
- }
-};
-
-template <class T>
-inline Message* NewMessage(T* object, void (T::*member)()) {
- return new MemberFunctionMessage<T, void>(object, member);
-}
-
-template <class T>
-inline Message* NewDelayedMessage(T* object, void (T::*member)(), long delay) {
- return new MemberFunctionMessage<T, void>(object, member, delay);
-}
-
-template <class T, typename A1>
-class MemberFunctionMessage : public Message {
-private:
- typedef void (T::*MemberSignature)(A1);
-
-public:
- inline MemberFunctionMessage(T* object,
- MemberSignature member,
- A1 arg1,
- long delay = 0)
- : Message(reinterpret_cast<void*>(object),
- reinterpret_cast<GenericMemberFunction>(member),
- delay)
- , m_arg1(arg1) {}
-
- virtual void run() {
- MemberSignature member = reinterpret_cast<MemberSignature>(m_member);
- (reinterpret_cast<T*>(m_object)->*member)(m_arg1);
- delete this;
- }
-
-private:
- typename remove_reference<A1>::type m_arg1;
-};
-
-template <class T, typename A1>
-inline Message* NewMessage(T* object, void (T::*member)(A1),
- typename identity<A1>::type arg1) {
- return new MemberFunctionMessage<T, A1>(
- object, member, arg1);
-}
-
-template <class T, typename A1>
-inline Message* NewDelayedMessage(T* object, void (T::*member)(A1),
- typename identity<A1>::type arg1, long delay) {
- return new MemberFunctionMessage<T, A1>(object, member, arg1, delay);
-}
-
-} // namespace android
-
-
-#endif // MessageTypes_h