diff options
Diffstat (limited to 'WebKit')
204 files changed, 0 insertions, 48905 deletions
diff --git a/WebKit/Android.mk b/WebKit/Android.mk deleted file mode 100644 index 5998227..0000000 --- a/WebKit/Android.mk +++ /dev/null @@ -1,132 +0,0 @@ -## -## -## Copyright 2008, The Android Open Source Project -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## - -LOCAL_SRC_FILES := \ - android/WebCoreSupport/CachedFramePlatformDataAndroid.cpp \ - android/WebCoreSupport/ChromeClientAndroid.cpp \ - android/WebCoreSupport/ContextMenuClientAndroid.cpp \ - android/WebCoreSupport/DeviceMotionClientAndroid.cpp \ - android/WebCoreSupport/DeviceOrientationClientAndroid.cpp \ - android/WebCoreSupport/DragClientAndroid.cpp \ - android/WebCoreSupport/EditorClientAndroid.cpp \ - android/WebCoreSupport/FrameLoaderClientAndroid.cpp \ - android/WebCoreSupport/FrameNetworkingContextAndroid.cpp \ - android/WebCoreSupport/GeolocationPermissions.cpp \ - android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp \ - android/WebCoreSupport/MemoryUsage.cpp \ - android/WebCoreSupport/PlatformBridge.cpp \ - android/WebCoreSupport/ResourceLoaderAndroid.cpp \ - android/WebCoreSupport/UrlInterceptResponse.cpp \ - android/WebCoreSupport/V8Counters.cpp - -ifeq ($(HTTP_STACK),chrome) -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - android/WebCoreSupport/ChromiumInit.cpp \ - android/WebCoreSupport/CacheResult.cpp \ - android/WebCoreSupport/WebCache.cpp \ - android/WebCoreSupport/WebCookieJar.cpp \ - android/WebCoreSupport/WebUrlLoader.cpp \ - android/WebCoreSupport/WebUrlLoaderClient.cpp \ - android/WebCoreSupport/WebRequest.cpp \ - android/WebCoreSupport/WebRequestContext.cpp \ - android/WebCoreSupport/WebResourceRequest.cpp \ - android/WebCoreSupport/WebResponse.cpp \ - android/WebCoreSupport/WebViewClientError.cpp -endif # HTTP_STACK == chrome - -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - android/RenderSkinAndroid.cpp \ - android/RenderSkinButton.cpp \ - android/RenderSkinCombo.cpp \ - android/RenderSkinMediaButton.cpp \ - android/RenderSkinNinePatch.cpp \ - android/RenderSkinRadio.cpp \ - android/TimeCounter.cpp \ - \ - android/benchmark/Intercept.cpp \ - android/benchmark/MyJavaVM.cpp \ - \ - android/icu/unicode/ucnv.cpp \ - \ - android/jni/CacheManager.cpp \ - android/jni/CookieManager.cpp \ - android/jni/DeviceMotionAndOrientationManager.cpp \ - android/jni/DeviceMotionClientImpl.cpp \ - android/jni/DeviceOrientationClientImpl.cpp \ - android/jni/GeolocationPermissionsBridge.cpp \ - android/jni/JavaBridge.cpp \ - android/jni/JavaSharedClient.cpp \ - android/jni/JniUtil.cpp \ - android/jni/MIMETypeRegistry.cpp \ - android/jni/MockGeolocation.cpp \ - android/jni/PictureSet.cpp \ - android/jni/WebCoreFrameBridge.cpp \ - android/jni/WebCoreJni.cpp \ - android/jni/WebCoreResourceLoader.cpp \ - android/jni/WebFrameView.cpp \ - android/jni/WebHistory.cpp \ - android/jni/WebIconDatabase.cpp \ - android/jni/WebStorage.cpp \ - android/jni/WebSettings.cpp \ - android/jni/WebViewCore.cpp \ - \ - android/nav/CacheBuilder.cpp \ - android/nav/CachedColor.cpp \ - android/nav/CachedFrame.cpp \ - android/nav/CachedHistory.cpp \ - android/nav/CachedInput.cpp \ - android/nav/CachedLayer.cpp \ - android/nav/CachedNode.cpp \ - android/nav/CachedRoot.cpp \ - android/nav/FindCanvas.cpp \ - android/nav/SelectText.cpp \ - android/nav/WebView.cpp \ - \ - android/plugins/ANPBitmapInterface.cpp \ - android/plugins/ANPCanvasInterface.cpp \ - android/plugins/ANPEventInterface.cpp \ - android/plugins/ANPLogInterface.cpp \ - android/plugins/ANPMatrixInterface.cpp \ - android/plugins/ANPOpenGLInterface.cpp \ - android/plugins/ANPPaintInterface.cpp \ - android/plugins/ANPPathInterface.cpp \ - android/plugins/ANPSoundInterface.cpp \ - android/plugins/ANPSurfaceInterface.cpp \ - android/plugins/ANPSystemInterface.cpp \ - android/plugins/ANPTypefaceInterface.cpp \ - android/plugins/ANPVideoInterface.cpp \ - android/plugins/ANPWindowInterface.cpp \ - android/plugins/PluginDebugAndroid.cpp \ - android/plugins/PluginTimer.cpp \ - android/plugins/PluginViewBridgeAndroid.cpp \ - android/plugins/PluginWidgetAndroid.cpp \ - android/plugins/SkANP.cpp \ - \ - android/wds/Command.cpp \ - android/wds/Connection.cpp \ - android/wds/DebugServer.cpp - -# Needed for autofill. -ifeq ($(ENABLE_AUTOFILL),true) -LOCAL_CFLAGS += -DENABLE_WEB_AUTOFILL - -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp \ - android/WebCoreSupport/autofill/FormFieldAndroid.cpp \ - android/WebCoreSupport/autofill/FormManagerAndroid.cpp \ - android/WebCoreSupport/autofill/WebAutoFill.cpp -endif # ENABLE_AUTOFILL == true diff --git a/WebKit/android/AndroidLog.h b/WebKit/android/AndroidLog.h deleted file mode 100644 index a69dce6..0000000 --- a/WebKit/android/AndroidLog.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2008, 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 ANDROIDLOG_H_ -#define ANDROIDLOG_H_ - -#ifdef ANDROID_DOM_LOGGING -#include <stdio.h> -extern FILE* gDomTreeFile; -#define DOM_TREE_LOG_FILE "/sdcard/domTree.txt" -#define DUMP_DOM_LOGD(...) { if (gDomTreeFile) \ - fprintf(gDomTreeFile, __VA_ARGS__); else LOGD(__VA_ARGS__); } - -extern FILE* gRenderTreeFile; -#define RENDER_TREE_LOG_FILE "/sdcard/renderTree.txt" -#define DUMP_RENDER_LOGD(...) { if (gRenderTreeFile) \ - fprintf(gRenderTreeFile, __VA_ARGS__); else LOGD(__VA_ARGS__); } -#else -#define DUMP_DOM_LOGD(...) ((void)0) -#define DUMP_RENDER_LOGD(...) ((void)0) -#endif /* ANDROID_DOM_LOGGING */ - -#define DISPLAY_TREE_LOG_FILE "/sdcard/displayTree.txt" -#define LAYERS_TREE_LOG_FILE "/sdcard/layersTree.plist" - -#endif /* ANDROIDLOG_H_ */ diff --git a/WebKit/android/JavaVM/jni.h b/WebKit/android/JavaVM/jni.h deleted file mode 100644 index da02603..0000000 --- a/WebKit/android/JavaVM/jni.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2007, 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 _JNI_COVER_H_ -#define _JNI_COVER_H_ - -#include "nativehelper/jni.h" -#define AttachCurrentThread(a, b) AttachCurrentThread((JNIEnv**) a, b) - -#endif diff --git a/WebKit/android/RenderSkinAndroid.cpp b/WebKit/android/RenderSkinAndroid.cpp deleted file mode 100644 index 9383a9c..0000000 --- a/WebKit/android/RenderSkinAndroid.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2006, 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 "WebCore" - -#include "config.h" -#include "RenderSkinAndroid.h" -#include "RenderSkinButton.h" -#include "RenderSkinCombo.h" -#include "RenderSkinMediaButton.h" -#include "RenderSkinRadio.h" -#include "SkImageDecoder.h" - -#include "utils/AssetManager.h" -#include "utils/Asset.h" - -namespace WebCore { - -RenderSkinAndroid::~RenderSkinAndroid() -{ - delete m_button; -} -RenderSkinAndroid::RenderSkinAndroid(android::AssetManager* am, String drawableDirectory) -{ - m_button = new RenderSkinButton(am, drawableDirectory); - RenderSkinCombo::Init(am, drawableDirectory); - RenderSkinMediaButton::Init(am, drawableDirectory); - RenderSkinRadio::Init(am, drawableDirectory); -} - -bool RenderSkinAndroid::DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap) -{ - android::Asset* asset = am->open(fileName, android::Asset::ACCESS_BUFFER); - if (!asset) { - asset = am->openNonAsset(fileName, android::Asset::ACCESS_BUFFER); - if (!asset) { - LOGD("RenderSkinAndroid: File \"%s\" not found.\n", fileName); - return false; - } - } - - bool success = SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(), bitmap); - if (!success) { - LOGD("RenderSkinAndroid: Failed to decode %s\n", fileName); - } - - delete asset; - return success; -} - -} // namespace WebCore diff --git a/WebKit/android/RenderSkinAndroid.h b/WebKit/android/RenderSkinAndroid.h deleted file mode 100644 index 73773ea..0000000 --- a/WebKit/android/RenderSkinAndroid.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2006, 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 RenderSkinAndroid_h -#define RenderSkinAndroid_h - -#include "PlatformString.h" - -namespace android { - class AssetManager; -} - -class SkBitmap; - -namespace WebCore { -class Node; -class RenderSkinButton; - -class RenderSkinAndroid -{ -public: - enum State { - kDisabled, - kNormal, - kFocused, - kPressed, - - kNumStates - }; - - /** - * Initialize the Android skinning system. The AssetManager may be used to find resources used - * in rendering. - */ - RenderSkinAndroid(android::AssetManager*, String drawableDirectory); - ~RenderSkinAndroid(); - - /* DecodeBitmap determines which file to use, with the given fileName of the form - * "images/bitmap.png", and uses the asset manager to select the exact one. It - * returns true if it successfully decoded the bitmap, false otherwise. - */ - static bool DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap); - - const RenderSkinButton* renderSkinButton() const { return m_button; } - -private: - RenderSkinButton* m_button; -}; - -} // WebCore - -#endif diff --git a/WebKit/android/RenderSkinButton.cpp b/WebKit/android/RenderSkinButton.cpp deleted file mode 100644 index 6a0ae54..0000000 --- a/WebKit/android/RenderSkinButton.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2006, 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 "WebCore" - -#include "config.h" -#include "android_graphics.h" -#include "Document.h" -#include "IntRect.h" -#include "Node.h" -#include "RenderSkinButton.h" -#include "RenderSkinNinePatch.h" -#include "SkCanvas.h" -#include "SkNinePatch.h" -#include "SkRect.h" -#include <utils/Asset.h> -#include <utils/AssetManager.h> -#include <utils/Debug.h> -#include <utils/Log.h> -#include <utils/ResourceTypes.h> -#include <wtf/text/CString.h> - -static const char* gFiles[] = { - "btn_default_disabled_holo.9.png", - "btn_default_normal_holo.9.png", - "btn_default_focused_holo.9.png", - "btn_default_pressed_holo.9.png" - }; - -namespace WebCore { - -RenderSkinButton::RenderSkinButton(android::AssetManager* am, String drawableDirectory) -{ - m_decoded = true; - for (size_t i = 0; i < 4; i++) { - String path = String(drawableDirectory.impl()); - path.append(String(gFiles[i])); - if (!RenderSkinNinePatch::decodeAsset(am, path.utf8().data(), &m_buttons[i])) { - m_decoded = false; - LOGE("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw"); - return; - } - } - - // Ensure our enums properly line up with our arrays. - android::CompileTimeAssert<(RenderSkinAndroid::kDisabled == 0)> a1; - android::CompileTimeAssert<(RenderSkinAndroid::kNormal == 1)> a2; - android::CompileTimeAssert<(RenderSkinAndroid::kFocused == 2)> a3; - android::CompileTimeAssert<(RenderSkinAndroid::kPressed == 3)> a4; -} - -void RenderSkinButton::draw(SkCanvas* canvas, const IntRect& r, - RenderSkinAndroid::State newState) const -{ - // If we failed to decode, do nothing. This way the browser still works, - // and webkit will still draw the label and layout space for us. - if (!m_decoded) { - return; - } - - // Ensure that the state is within the valid range of our array. - SkASSERT(static_cast<unsigned>(newState) < - static_cast<unsigned>(RenderSkinAndroid::kNumStates)); - - RenderSkinNinePatch::DrawNinePatch(canvas, SkRect(r), m_buttons[newState]); -} - -} //WebCore diff --git a/WebKit/android/RenderSkinButton.h b/WebKit/android/RenderSkinButton.h deleted file mode 100644 index e9db74c..0000000 --- a/WebKit/android/RenderSkinButton.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2006, 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 RenderSkinButton_h -#define RenderSkinButton_h - -#include "RenderSkinAndroid.h" -#include "RenderSkinNinePatch.h" - -class SkCanvas; - -namespace WebCore { -class IntRect; - -class RenderSkinButton { -public: - /** - * Initialize the class before use. Uses the AssetManager to initialize any - * bitmaps the class may use. - */ - RenderSkinButton(android::AssetManager*, String drawableDirectory); - /** - * 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. - */ - void draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State) const; -private: - bool m_decoded; - NinePatch m_buttons[4]; -}; - -} // WebCore -#endif diff --git a/WebKit/android/RenderSkinCombo.cpp b/WebKit/android/RenderSkinCombo.cpp deleted file mode 100644 index b30dc29..0000000 --- a/WebKit/android/RenderSkinCombo.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2006, 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 "RenderSkinCombo.h" - -#include "Document.h" -#include "Element.h" -#include "Node.h" -#include "NodeRenderStyle.h" -#include "RenderStyle.h" -#include "SkCanvas.h" -#include "SkNinePatch.h" -#include <wtf/text/CString.h> - -namespace WebCore { - -// Indicates if the entire asset is being drawn, or if the border is being -// excluded and just the arrow drawn. -enum BorderStyle { - FullAsset, - NoBorder -}; - -// There are 2.5 different concepts of a 'border' here, which results -// in rather a lot of magic constants. In each case, there are 2 -// numbers, one for medium res and one for high-res. All sizes are in pixels. - -// Firstly, we have the extra padding that webkit needs to know about, -// which defines how much bigger this element is made by the -// asset. This is actually a bit broader than the actual border on the -// asset, to make things look less cramped. The border is the same -// width on all sides, except on the right when it's significantly -// wider to allow for the arrow. -const int RenderSkinCombo::arrowMargin[2] = {22, 34}; -const int RenderSkinCombo::padMargin[2] = {2, 5}; - -// Then we have the borders used for the 9-patch stretch. The -// rectangle at the centre of these borders is entirely below and to -// the left of the arrow in the asset. Hence the border widths are the -// same for the bottom and left, but are different for the top. The -// right hand border width happens to be the same as arrowMargin -// defined above. -static const int stretchMargin[2] = {3, 5}; // border width for the bottom and left of the 9-patch -static const int stretchTop[2] = {15, 23}; // border width for the top of the 9-patch - -// Finally, if the border is defined by the CSS, we only draw the -// arrow and not the border. We do this by drawing the relevant subset -// of the bitmap, which must now be precisely determined by what's in -// the asset with no extra padding to make things look properly -// spaced. The border to remove at the top, right and bottom of the -// image is the same as stretchMargin above, but we need to know the width -// of the arrow. -static const int arrowWidth[2] = {22, 31}; - -RenderSkinCombo::Resolution RenderSkinCombo::resolution = MedRes; - -const SkIRect RenderSkinCombo::margin[2][2] = {{{ stretchMargin[MedRes], stretchTop[MedRes], - RenderSkinCombo::arrowMargin[MedRes] + stretchMargin[MedRes], stretchMargin[MedRes] }, - {0, stretchTop[MedRes], 0, stretchMargin[MedRes]}}, - {{ stretchMargin[HighRes], stretchTop[HighRes], - RenderSkinCombo::arrowMargin[HighRes] + stretchMargin[HighRes], stretchMargin[HighRes] }, - {0, stretchTop[HighRes], 0, stretchMargin[HighRes]}}}; -static SkBitmap bitmaps[2][2]; // Collection of assets for a combo box -static bool isDecoded; // True if all assets were decoded - -void RenderSkinCombo::Init(android::AssetManager* am, String drawableDirectory) -{ - if (isDecoded) - return; - - if (drawableDirectory[drawableDirectory.length() - 5] == 'h') - resolution = HighRes; - - isDecoded = RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_nohighlight.png").utf8().data(), &bitmaps[kNormal][FullAsset]); - isDecoded &= RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_disabled.png").utf8().data(), &bitmaps[kDisabled][FullAsset]); - - int width = bitmaps[kNormal][FullAsset].width(); - int height = bitmaps[kNormal][FullAsset].height(); - SkIRect subset; - subset.set(width - arrowWidth[resolution], 0, width, height); - bitmaps[kNormal][FullAsset].extractSubset(&bitmaps[kNormal][NoBorder], subset); - bitmaps[kDisabled][FullAsset].extractSubset(&bitmaps[kDisabled][NoBorder], subset); -} - - -bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int width, int height) -{ - if (!isDecoded) - return true; - - State state = (element->isElementNode() && static_cast<Element*>(element)->isEnabledFormControl()) ? kNormal : kDisabled; - height = std::max(height, (stretchMargin[resolution]<<1) + 1); - - SkRect bounds; - BorderStyle drawBorder = FullAsset; - - bounds.set(SkIntToScalar(x+1), SkIntToScalar(y+1), SkIntToScalar(x + width-1), SkIntToScalar(y + height-1)); - RenderStyle* style = element->renderStyle(); - SkPaint paint; - paint.setColor(style->visitedDependentColor(CSSPropertyBackgroundColor).rgb()); - canvas->drawRect(bounds, paint); - - bounds.set(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + width), SkIntToScalar(y + height)); - - // If this is an appearance where RenderTheme::paint returns true - // without doing anything, this means that - // RenderBox::PaintBoxDecorationWithSize will end up painting the - // border, so we shouldn't paint a border here. - if (style->appearance() == MenulistButtonPart || - style->appearance() == ListboxPart || - style->appearance() == TextFieldPart || - style->appearance() == TextAreaPart) { - bounds.fLeft += SkIntToScalar(width - RenderSkinCombo::extraWidth()); - bounds.fRight -= SkIntToScalar(style->borderRightWidth()); - bounds.fTop += SkIntToScalar(style->borderTopWidth()); - bounds.fBottom -= SkIntToScalar(style->borderBottomWidth()); - drawBorder = NoBorder; - } - SkNinePatch::DrawNine(canvas, bounds, bitmaps[state][drawBorder], margin[resolution][drawBorder]); - return false; -} - -} //WebCore diff --git a/WebKit/android/RenderSkinCombo.h b/WebKit/android/RenderSkinCombo.h deleted file mode 100644 index 38cd048..0000000 --- a/WebKit/android/RenderSkinCombo.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2006, 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 RenderSkinCombo_h -#define RenderSkinCombo_h - -#include "RenderSkinAndroid.h" -#include "SkRect.h" - -class SkCanvas; - -namespace WebCore { - -// This is very similar to RenderSkinButton - maybe they should be the same class? -class RenderSkinCombo : public RenderSkinAndroid -{ -public: - /** - * Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use. - */ - static void Init(android::AssetManager*, String drawableDirectory); - - /** - * Draw the provided Node on the SkCanvas, using the dimensions provided by - * x,y,w,h. Return true if we did not draw, and WebKit needs to draw it, - * false otherwise. - */ - static bool Draw(SkCanvas* , Node* , int x, int y, int w, int h); - - // The image is wider than the RenderObject, so this accounts for that. - static int extraWidth() { return arrowMargin[resolution]; } - static int padding() { return padMargin[resolution]; } - - enum Resolution { - MedRes, - HighRes - }; -private: - static Resolution resolution; - const static int arrowMargin[2]; - const static int padMargin[2]; - const static SkIRect margin[2][2]; -}; - -} // WebCore - -#endif diff --git a/WebKit/android/RenderSkinMediaButton.cpp b/WebKit/android/RenderSkinMediaButton.cpp deleted file mode 100644 index 090d55e..0000000 --- a/WebKit/android/RenderSkinMediaButton.cpp +++ /dev/null @@ -1,215 +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 "WebCore" - -#include "config.h" -#include "android_graphics.h" -#include "Document.h" -#include "IntRect.h" -#include "Node.h" -#include "RenderObject.h" -#include "RenderSkinMediaButton.h" -#include "RenderSlider.h" -#include "SkCanvas.h" -#include "SkNinePatch.h" -#include "SkRect.h" -#include <utils/Debug.h> -#include <utils/Log.h> -#include <wtf/text/CString.h> - -struct PatchData { - const char* name; - int8_t outset, margin; -}; - -static const PatchData gFiles[] = - { - { "scrubber_primary_holo.9.png", 0, 0 }, // SLIDER_TRACK, left of the SLIDER_THUMB - { "ic_media_pause.png", 0, 0}, // PAUSE - { "ic_media_play.png", 0, 0 }, // PLAY - { "ic_media_pause.png", 0, 0 }, // MUTE - { "ic_media_rew.png", 0, 0 }, // REWIND - { "ic_media_ff.png", 0, 0 }, // FORWARD - { "ic_media_fullscreen.png", 0, 0 }, // FULLSCREEN - { "spinner_76_outer_holo.png", 0, 0 }, // SPINNER_OUTER - { "spinner_76_inner_holo.png", 0, 0 }, // SPINNER_INNER - { "ic_media_video_poster.png", 0, 0 }, // VIDEO - { "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER - { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK - { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB - }; - -static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])]; -static bool gDecoded; -static bool gHighRes; - -namespace WebCore { - -void RenderSkinMediaButton::Init(android::AssetManager* am, String drawableDirectory) -{ - static bool gInited; - if (gInited) - return; - - gInited = true; - gDecoded = true; - gHighRes = drawableDirectory[drawableDirectory.length() - 5] == 'h'; - for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) { - String path = drawableDirectory + gFiles[i].name; - if (!RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &gButton[i])) { - gDecoded = false; - LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw"); - break; - } - } -} - -void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonType, - bool translucent, RenderObject* o) -{ - // If we failed to decode, do nothing. This way the browser still works, - // and webkit will still draw the label and layout space for us. - if (!gDecoded) { - return; - } - - bool drawsNinePatch = false; - bool drawsImage = true; - bool drawsBackgroundColor = true; - - int ninePatchIndex = 0; - int imageIndex = 0; - - SkRect bounds(r); - SkScalar imageMargin = 8; - SkPaint paint; - - int alpha = 255; - if (translucent) - alpha = 190; - - SkColor backgroundColor = SkColorSetARGB(alpha, 34, 34, 34); - SkColor trackBackgroundColor = SkColorSetARGB(255, 100, 100, 100); - paint.setColor(backgroundColor); - paint.setFlags(SkPaint::kFilterBitmap_Flag); - - switch (buttonType) { - case PAUSE: - case PLAY: - case MUTE: - case REWIND: - case FORWARD: - case FULLSCREEN: - { - imageIndex = buttonType + 1; - paint.setColor(backgroundColor); - break; - } - case SPINNER_OUTER: - case SPINNER_INNER: - case VIDEO: - { - drawsBackgroundColor = false; - imageIndex = buttonType + 1; - break; - } - case BACKGROUND_SLIDER: - { - drawsBackgroundColor = false; - drawsImage = false; - break; - } - case SLIDER_TRACK: - { - drawsNinePatch = true; - drawsImage = false; - ninePatchIndex = buttonType + 1; - break; - } - case SLIDER_THUMB: - { - drawsBackgroundColor = false; - imageMargin = 0; - imageIndex = buttonType + 1; - break; - } - default: - return; - } - - if (drawsBackgroundColor) { - canvas->drawRect(r, paint); - } - - if (drawsNinePatch) { - const PatchData& pd = gFiles[ninePatchIndex]; - int marginValue = pd.margin + pd.outset; - - SkIRect margin; - margin.set(marginValue, marginValue, marginValue, marginValue); - if (buttonType == SLIDER_TRACK) { - // Cut the height in half (with some extra slop determined by trial - // and error to get the placement just right. - 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(); - // 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. - SkScalar thumbHalfWidth = SkIntToScalar(thumb.width()/2); - bounds.fLeft += thumbHalfWidth; - bounds.fRight -= thumbHalfWidth; - if (thumb.x() > 0) { - // The video is past the starting point. Show the area to - // left of the thumb as having been played. - SkScalar alreadyPlayed = SkIntToScalar(thumb.center().x() + r.x()); - SkRect playedRect(bounds); - playedRect.fRight = alreadyPlayed; - SkNinePatch::DrawNine(canvas, playedRect, gButton[0], margin); - bounds.fLeft = alreadyPlayed; - } - - } - } - SkNinePatch::DrawNine(canvas, bounds, gButton[ninePatchIndex], margin); - } - - if (drawsImage) { - SkScalar SIZE = gButton[imageIndex].width(); - SkScalar width = r.width(); - SkScalar scale = SkScalarDiv(width - 2*imageMargin, SIZE); - int saveScaleCount = canvas->save(); - canvas->translate(bounds.fLeft + imageMargin, bounds.fTop + imageMargin); - canvas->scale(scale, scale); - canvas->drawBitmap(gButton[imageIndex], 0, 0, &paint); - canvas->restoreToCount(saveScaleCount); - } -} - -} // WebCore diff --git a/WebKit/android/RenderSkinMediaButton.h b/WebKit/android/RenderSkinMediaButton.h deleted file mode 100644 index 6aa9c4e..0000000 --- a/WebKit/android/RenderSkinMediaButton.h +++ /dev/null @@ -1,63 +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 RenderSkinMediaButton_h -#define RenderSkinMediaButton_h - -#include "RenderSkinAndroid.h" - -class SkCanvas; - -namespace WebCore { -class IntRect; -class RenderObject; - -class RenderSkinMediaButton { -public: - /** - * Initialize the class before use. Uses the AssetManager to initialize any - * bitmaps the class may use. - */ - static void Init(android::AssetManager*, String drawableDirectory); - /** - * 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. - */ - static void Draw(SkCanvas* , const IntRect& , int buttonType, bool translucent = false, - RenderObject* o = 0); - /** - * Button types - */ - enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, FULLSCREEN, SPINNER_OUTER, SPINNER_INNER , VIDEO, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB }; - /** - * Slider dimensions - */ - static int sliderThumbWidth() { return 32; } - static int sliderThumbHeight() { return 32; } - -}; - -} // WebCore -#endif // RenderSkinMediaButton_h diff --git a/WebKit/android/RenderSkinNinePatch.cpp b/WebKit/android/RenderSkinNinePatch.cpp deleted file mode 100644 index 0c915c0..0000000 --- a/WebKit/android/RenderSkinNinePatch.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "config.h" - -#include "RenderSkinNinePatch.h" -#include "NinePatchPeeker.h" -#include "SkCanvas.h" -#include "SkImageDecoder.h" -#include "SkRect.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include <utils/Asset.h> -#include <utils/AssetManager.h> -#include <utils/Log.h> -#include <utils/ResourceTypes.h> - -class SkPaint; -class SkRegion; - -using namespace android; - -extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, - const SkBitmap& bitmap, const Res_png_9patch& chunk, - const SkPaint* paint, SkRegion** outRegion); - -bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, NinePatch* ninepatch) { - Asset* asset = am->open(filename, android::Asset::ACCESS_BUFFER); - if (!asset) { - asset = am->openNonAsset(filename, android::Asset::ACCESS_BUFFER); - if (!asset) { - return false; - } - } - - SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode; - SkBitmap::Config prefConfig = SkBitmap::kNo_Config; - SkStream* stream = new SkMemoryStream(asset->getBuffer(false), asset->getLength()); - SkImageDecoder* decoder = SkImageDecoder::Factory(stream); - if (!decoder) { - asset->close(); - LOGE("RenderSkinNinePatch::Failed to create an image decoder"); - return false; - } - - decoder->setSampleSize(1); - decoder->setDitherImage(true); - decoder->setPreferQualityOverSpeed(false); - - NinePatchPeeker peeker(decoder); - - SkAutoTDelete<SkImageDecoder> add(decoder); - - decoder->setPeeker(&peeker); - if (!decoder->decode(stream, &ninepatch->m_bitmap, prefConfig, mode, true)) { - asset->close(); - LOGE("RenderSkinNinePatch::Failed to decode nine patch asset"); - return false; - } - - asset->close(); - if (!peeker.fPatchIsValid) { - LOGE("RenderSkinNinePatch::Patch data not valid"); - return false; - } - void** data = &ninepatch->m_serializedPatchData; - *data = malloc(peeker.fPatch->serializedSize()); - peeker.fPatch->serialize(*data); - return true; -} - -void RenderSkinNinePatch::DrawNinePatch(SkCanvas* canvas, const SkRect& bounds, - const NinePatch& patch) { - Res_png_9patch* data = Res_png_9patch::deserialize(patch.m_serializedPatchData); - NinePatch_Draw(canvas, bounds, patch.m_bitmap, *data, 0, 0); -} diff --git a/WebKit/android/RenderSkinNinePatch.h b/WebKit/android/RenderSkinNinePatch.h deleted file mode 100644 index e4db260..0000000 --- a/WebKit/android/RenderSkinNinePatch.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RenderSkinNinePatch_h -#define RenderSkinNinePatch_h - -#include "SkBitmap.h" -#include "utils/Asset.h" - -namespace android { - class AssetManager; -} - -class SkCanvas; -class SkRect; - -struct NinePatch { - SkBitmap m_bitmap; - void* m_serializedPatchData; - NinePatch() { - m_serializedPatchData = 0; - } - ~NinePatch() { - if (m_serializedPatchData) - free(m_serializedPatchData); - } -}; - -class RenderSkinNinePatch { -public: - static bool decodeAsset(android::AssetManager*, const char* fileName, NinePatch*); - static void DrawNinePatch(SkCanvas*, const SkRect&, const NinePatch&); -}; - -#endif // RenderSkinNinePatch_h diff --git a/WebKit/android/RenderSkinRadio.cpp b/WebKit/android/RenderSkinRadio.cpp deleted file mode 100644 index 5dfee4a..0000000 --- a/WebKit/android/RenderSkinRadio.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2006, 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 "RenderSkinRadio.h" - -#include "android_graphics.h" -#include "Document.h" -#include "Element.h" -#include "InputElement.h" -#include "IntRect.h" -#include "Node.h" -#include "RenderSkinAndroid.h" -#include "SkBitmap.h" -#include "SkCanvas.h" -#include "SkRect.h" -#include <wtf/text/CString.h> - -static const char* checks[] = { "btn_check_off_holo.png", - "btn_check_on_holo.png", - "btn_radio_off_holo.png", - "btn_radio_on_holo.png"}; -// Matches the width of the bitmap -static SkScalar SIZE; - -namespace WebCore { - -static SkBitmap s_bitmap[4]; -static bool s_decoded; - -void RenderSkinRadio::Init(android::AssetManager* am, String drawableDirectory) -{ - if (s_decoded) - return; - String path = drawableDirectory + checks[0]; - s_decoded = RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &s_bitmap[0]); - path = drawableDirectory + checks[1]; - s_decoded = RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &s_bitmap[1]) && s_decoded; - path = drawableDirectory + checks[2]; - s_decoded = RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &s_bitmap[2]) && s_decoded; - path = drawableDirectory + checks[3]; - s_decoded = RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &s_bitmap[3]) && s_decoded; - SIZE = SkIntToScalar(s_bitmap[0].width()); -} - -void RenderSkinRadio::Draw(SkCanvas* canvas, Node* element, const IntRect& ir, - bool isCheckBox) -{ - if (!s_decoded || !element) { - return; - } - SkRect r(ir); - // Set up a paint to with filtering to look better. - SkPaint paint; - paint.setFlags(SkPaint::kFilterBitmap_Flag); - int saveScaleCount = 0; - - if (!element->isElementNode() || - !static_cast<Element*>(element)->isEnabledFormControl()) { - paint.setAlpha(0x80); - } - SkScalar width = r.width(); - SkScalar scale = SkScalarDiv(width, SIZE); - saveScaleCount = canvas->save(); - canvas->translate(r.fLeft, r.fTop); - canvas->scale(scale, scale); - - bool checked = false; - if (InputElement* inputElement = toInputElement(static_cast<Element*>(element))) { - checked = inputElement->isChecked(); - } - - canvas->drawBitmap(s_bitmap[checked + 2*(!isCheckBox)], - 0, 0, &paint); - canvas->restoreToCount(saveScaleCount); -} - -} //WebCore diff --git a/WebKit/android/RenderSkinRadio.h b/WebKit/android/RenderSkinRadio.h deleted file mode 100644 index f77e1be..0000000 --- a/WebKit/android/RenderSkinRadio.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2006, 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 RenderSkinRadio_h -#define RenderSkinRadio_h - -#include "PlatformString.h" - -class SkCanvas; - -namespace android { - class AssetManager; -} - -namespace WebCore { - -class Node; -class IntRect; - -/* RenderSkin for a radio button or a checkbox - */ -class RenderSkinRadio -{ -public: - /** - * Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use. - */ - static void Init(android::AssetManager*, String drawableDirectory); - - /** - * Draw the element to the canvas at the specified size and location. - * param isCheckBox If true, draws a checkbox. Else, draw a radio button. - */ - static void Draw(SkCanvas* canvas, Node* element, const IntRect&, - bool isCheckBox); -}; - -} // WebCore -#endif diff --git a/WebKit/android/TimeCounter.cpp b/WebKit/android/TimeCounter.cpp deleted file mode 100644 index 2393f8a..0000000 --- a/WebKit/android/TimeCounter.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "WebCore" - -#include "config.h" -#include "TimeCounter.h" - -#include "MemoryCache.h" -#include "KURL.h" -#include "Node.h" -#include "SystemTime.h" -#include "StyleBase.h" -#include <sys/time.h> -#include <time.h> -#include <utils/Log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#if USE(JSC) -#include "JSDOMWindow.h" -#include <runtime/JSGlobalObject.h> -#include <runtime/JSLock.h> -#endif - -using namespace WebCore; -using namespace WTF; -using namespace JSC; - -namespace android { - -uint32_t getThreadMsec() -{ -#if defined(HAVE_POSIX_CLOCKS) - struct timespec tm; - - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm); - return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000; -#else - struct timeval now; - struct timezone zone; - - gettimeofday(&now, &zone); - return now.tv_sec * 1000LL + now.tv_usec / 1000; -#endif -} - -#ifdef ANDROID_INSTRUMENT - -static double sStartTotalTime; -static uint32_t sStartThreadTime; -static double sLastTotalTime; -static uint32_t sLastThreadTime; - -uint32_t TimeCounter::sStartWebCoreThreadTime; -uint32_t TimeCounter::sEndWebCoreThreadTime; -bool TimeCounter::sRecordWebCoreTime; -uint32_t TimeCounter::sTotalTimeUsed[TimeCounter::TotalTimeCounterCount]; -uint32_t TimeCounter::sLastTimeUsed[TimeCounter::TotalTimeCounterCount]; -uint32_t TimeCounter::sCounter[TimeCounter::TotalTimeCounterCount]; -uint32_t TimeCounter::sLastCounter[TimeCounter::TotalTimeCounterCount]; -uint32_t TimeCounter::sStartTime[TimeCounter::TotalTimeCounterCount]; - -int QemuTracerAuto::reentry_count = 0; - -static const char* timeCounterNames[] = { - "css parsing", - "javascript", - "javascript init", - "javascript parsing", - "javascript execution", - "calculate style", - "Java callback (frame bridge)", - "parsing (may include calcStyle, Java callback or inline script execution)", - "layout", - "native 1 (frame bridge)", - "native 2 (resource load)", - "native 3 (shared timer)", - "build nav (webview core)", - "record content (webview core)", - "native 4 (webview core)", - "draw content (webview ui)", -}; - -void TimeCounter::record(enum Type type, const char* functionName) -{ - recordNoCounter(type, functionName); - sCounter[type]++; -} - -void TimeCounter::recordNoCounter(enum Type type, const char* functionName) -{ - uint32_t time = sEndWebCoreThreadTime = getThreadMsec(); - uint32_t elapsed = time - sStartTime[type]; - sTotalTimeUsed[type] += elapsed; - if (elapsed > 1000) - LOGW("***** %s() used %d ms\n", functionName, elapsed); -} - -void TimeCounter::report(const KURL& url, int live, int dead, size_t arenaSize) -{ - String urlString = url; - int totalTime = static_cast<int>((currentTime() - sStartTotalTime) * 1000); - int threadTime = getThreadMsec() - sStartThreadTime; - LOGD("*-* Total load time: %d ms, thread time: %d ms for %s\n", - totalTime, threadTime, urlString.utf8().data()); - for (Type type = (Type) 0; type < TotalTimeCounterCount; type - = (Type) (type + 1)) { - char scratch[256]; - int index = sprintf(scratch, "*-* Total %s time: %d ms", - timeCounterNames[type], sTotalTimeUsed[type]); - if (sCounter[type] > 0) - sprintf(&scratch[index], " called %d times", sCounter[type]); - LOGD("%s", scratch); - } - LOGD("Current cache has %d bytes live and %d bytes dead", live, dead); - LOGD("Current render arena takes %d bytes", arenaSize); -#if USE(JSC) - JSLock lock(false); - Heap::Statistics jsHeapStatistics = JSDOMWindow::commonJSGlobalData()->heap.statistics(); - LOGD("Current JavaScript heap size is %d and has %d bytes free", - jsHeapStatistics.size, jsHeapStatistics.free); -#endif - LOGD("Current CSS styles use %d bytes", StyleBase::reportStyleSize()); - LOGD("Current DOM nodes use %d bytes", WebCore::Node::reportDOMNodesSize()); -} - -void TimeCounter::reportNow() -{ - double current = currentTime(); - uint32_t currentThread = getThreadMsec(); - int elapsedTime = static_cast<int>((current - sLastTotalTime) * 1000); - int elapsedThreadTime = currentThread - sLastThreadTime; - LOGD("*-* Elapsed time: %d ms, ui thread time: %d ms, webcore thread time:" - " %d ms\n", elapsedTime, elapsedThreadTime, sEndWebCoreThreadTime - - sStartWebCoreThreadTime); - for (Type type = (Type) 0; type < TotalTimeCounterCount; type - = (Type) (type + 1)) { - if (sTotalTimeUsed[type] == sLastTimeUsed[type]) - continue; - char scratch[256]; - int index = sprintf(scratch, "*-* Diff %s time: %d ms", - timeCounterNames[type], sTotalTimeUsed[type] - sLastTimeUsed[type]); - if (sCounter[type] > sLastCounter[type]) - sprintf(&scratch[index], " called %d times", sCounter[type] - - sLastCounter[type]); - LOGD("%s", scratch); - } - memcpy(sLastTimeUsed, sTotalTimeUsed, sizeof(sTotalTimeUsed)); - memcpy(sLastCounter, sCounter, sizeof(sCounter)); - sLastTotalTime = current; - sLastThreadTime = currentThread; - sRecordWebCoreTime = true; -} - -void TimeCounter::reset() { - bzero(sTotalTimeUsed, sizeof(sTotalTimeUsed)); - bzero(sCounter, sizeof(sCounter)); - LOGD("*-* Start browser instrument\n"); - sStartTotalTime = currentTime(); - sStartThreadTime = getThreadMsec(); -} - -void TimeCounter::start(enum Type type) -{ - uint32_t time = getThreadMsec(); - if (sRecordWebCoreTime) { - sStartWebCoreThreadTime = time; - sRecordWebCoreTime = false; - } - sStartTime[type] = time; -} - -#endif // ANDROID_INSTRUMENT - -} diff --git a/WebKit/android/TimeCounter.h b/WebKit/android/TimeCounter.h deleted file mode 100644 index 64908d1..0000000 --- a/WebKit/android/TimeCounter.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 TIME_COUNTER_H -#define TIME_COUNTER_H - -#include "hardware_legacy/qemu_tracing.h" - -namespace WebCore { - -class KURL; - -} - -namespace android { - -uint32_t getThreadMsec(); - -#ifdef ANDROID_INSTRUMENT - -class TimeCounter { -public: - enum Type { - // function base counters - CSSParseTimeCounter, - JavaScriptTimeCounter, - JavaScriptInitTimeCounter, - JavaScriptParseTimeCounter, - JavaScriptExecuteTimeCounter, - CalculateStyleTimeCounter, - JavaCallbackTimeCounter, - ParsingTimeCounter, - LayoutTimeCounter, - // file base counters - NativeCallbackTimeCounter, // WebCoreFrameBridge.cpp - ResourceTimeCounter, // WebCoreResourceLoader.cpp - SharedTimerTimeCounter, // JavaBridge.cpp - WebViewCoreBuildNavTimeCounter, - WebViewCoreRecordTimeCounter, - WebViewCoreTimeCounter, // WebViewCore.cpp - WebViewUIDrawTimeCounter, - TotalTimeCounterCount - }; - - static void record(enum Type type, const char* functionName); - static void recordNoCounter(enum Type type, const char* functionName); - static void report(const WebCore::KURL& , int live, int dead, size_t arenaSize); - static void reportNow(); - static void reset(); - static void start(enum Type type); -private: - static uint32_t sStartWebCoreThreadTime; - static uint32_t sEndWebCoreThreadTime; - static bool sRecordWebCoreTime; - static uint32_t sTotalTimeUsed[TotalTimeCounterCount]; - static uint32_t sLastTimeUsed[TotalTimeCounterCount]; - static uint32_t sCounter[TotalTimeCounterCount]; - static uint32_t sLastCounter[TotalTimeCounterCount]; - static uint32_t sStartTime[TotalTimeCounterCount]; - friend class TimeCounterAuto; -}; - -class TimeCounterAuto { -public: - TimeCounterAuto(TimeCounter::Type type) : - m_type(type), m_startTime(getThreadMsec()) {} - ~TimeCounterAuto() { - uint32_t time = getThreadMsec(); - TimeCounter::sEndWebCoreThreadTime = time; - TimeCounter::sTotalTimeUsed[m_type] += time - m_startTime; - TimeCounter::sCounter[m_type]++; - } -private: - TimeCounter::Type m_type; - uint32_t m_startTime; -}; - -class QemuTracerAuto { -public: - QemuTracerAuto() { - if (!reentry_count) - qemu_start_tracing(); - reentry_count++; - } - - ~QemuTracerAuto() { - reentry_count--; - if (!reentry_count) - qemu_stop_tracing(); - } -private: - static int reentry_count; -}; -#endif // ANDROID_INSTRUMENT - -} - -#endif diff --git a/WebKit/android/TimerClient.h b/WebKit/android/TimerClient.h deleted file mode 100644 index 0c3c84c..0000000 --- a/WebKit/android/TimerClient.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2007, 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 TIMER_CLIENT_H -#define TIMER_CLIENT_H - -namespace android { - - class TimerClient - { - public: - virtual ~TimerClient() {} - virtual void setSharedTimerCallback(void(*f)()) = 0; - virtual void setSharedTimer(long long timemillis) = 0; - virtual void stopSharedTimer() = 0; - virtual void signalServiceFuncPtrQueue() = 0; - }; - -} -#endif diff --git a/WebKit/android/WebCoreSupport/CacheResult.cpp b/WebKit/android/WebCoreSupport/CacheResult.cpp deleted file mode 100644 index 5309c66..0000000 --- a/WebKit/android/WebCoreSupport/CacheResult.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2011, 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 "CacheResult.h" - -#include "WebResponse.h" -#include "WebUrlLoaderClient.h" -#include <platform/FileSystem.h> -#include <wtf/text/CString.h> - -using namespace base; -using namespace disk_cache; -using namespace net; -using namespace std; - -namespace android { - -// All public methods are called on a UI thread but we do work on the -// Chromium thread. However, because we block the WebCore thread while this -// work completes, we can never receive new public method calls while the -// Chromium thread work is in progress. - -// Copied from HttpCache -enum { - kResponseInfoIndex = 0, - kResponseContentIndex -}; - -CacheResult::CacheResult(disk_cache::Entry* entry, String url) - : m_entry(entry) - , m_onResponseHeadersDoneCallback(this, &CacheResult::onResponseHeadersDone) - , m_onReadNextChunkDoneCallback(this, &CacheResult::onReadNextChunkDone) - , m_url(url) -{ - ASSERT(m_entry); -} - -CacheResult::~CacheResult() -{ - m_entry->Close(); - // TODO: Should we also call DoneReadingFromEntry() on the cache for our - // entry? -} - -int64 CacheResult::contentSize() const -{ - // The android stack does not take the content length from the HTTP response - // headers but calculates it when writing the content to disk. It can never - // overflow a long because we limit the cache size. - return m_entry->GetDataSize(kResponseContentIndex); -} - -bool CacheResult::firstResponseHeader(const char* name, String* result, bool allowEmptyString) const -{ - string value; - if (responseHeaders() && responseHeaders()->EnumerateHeader(NULL, name, &value) && (!value.empty() || allowEmptyString)) { - *result = String(value.c_str()); - return true; - } - return false; -} - -String CacheResult::mimeType() const -{ - string mimeType; - if (responseHeaders()) - responseHeaders()->GetMimeType(&mimeType); - if (!mimeType.length() && m_url.length()) - mimeType = WebResponse::resolveMimeType(std::string(m_url.utf8().data(), m_url.length()), ""); - return String(mimeType.c_str()); -} - -int64 CacheResult::expires() const -{ - // We have to do this manually, rather than using HttpResponseHeaders::GetExpiresValue(), - // to handle the "-1" and "0" special cases. - string expiresString; - if (responseHeaders() && responseHeaders()->EnumerateHeader(NULL, "expires", &expiresString)) { - wstring expiresStringWide(expiresString.begin(), expiresString.end()); // inflate ascii - // We require the time expressed as ms since the epoch. - Time time; - if (Time::FromString(expiresStringWide.c_str(), &time)) { - // Will not overflow for a very long time! - return static_cast<int64>(1000.0 * time.ToDoubleT()); - } - - if (expiresString == "-1" || expiresString == "0") - return 0; - } - - // TODO - // The Android stack applies a heuristic to set an expiry date if the - // expires header is not set or can't be parsed. I'm not sure whether the Chromium cache - // does this, and if so, it may not be possible for us to get hold of it - // anyway to set it on the result. - return -1; -} - -int CacheResult::responseCode() const -{ - return responseHeaders() ? responseHeaders()->response_code() : 0; -} - -bool CacheResult::writeToFile(const String& filePath) const -{ - // Getting the headers is potentially async, so post to the Chromium thread - // and block here. - MutexLocker lock(m_mutex); - - base::Thread* thread = WebUrlLoaderClient::ioThread(); - if (!thread) - return false; - - CacheResult* me = const_cast<CacheResult*>(this); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(me, &CacheResult::writeToFileImpl)); - - m_filePath = filePath.threadsafeCopy(); - m_isAsyncOperationInProgress = true; - while (m_isAsyncOperationInProgress) - m_condition.wait(m_mutex); - - return m_wasWriteToFileSuccessful; -} - -void CacheResult::writeToFileImpl() -{ - m_bufferSize = m_entry->GetDataSize(kResponseContentIndex); - m_readOffset = 0; - m_wasWriteToFileSuccessful = false; - readNextChunk(); -} - -void CacheResult::readNextChunk() -{ - m_buffer = new IOBuffer(m_bufferSize); - int rv = m_entry->ReadData(kResponseInfoIndex, m_readOffset, m_buffer, m_bufferSize, &m_onReadNextChunkDoneCallback); - if (rv == ERR_IO_PENDING) - return; - - onReadNextChunkDone(rv); -}; - -void CacheResult::onReadNextChunkDone(int size) -{ - if (size > 0) { - // Still more reading to be done. - if (writeChunkToFile()) { - // TODO: I assume that we need to clear and resize the buffer for the next read? - m_readOffset += size; - m_bufferSize -= size; - readNextChunk(); - } else - onWriteToFileDone(); - return; - } - - if (!size) { - // Reached end of file. - if (writeChunkToFile()) - m_wasWriteToFileSuccessful = true; - } - onWriteToFileDone(); -} - -bool CacheResult::writeChunkToFile() -{ - PlatformFileHandle file; - file = openFile(m_filePath, OpenForWrite); - if (!isHandleValid(file)) - return false; - return WebCore::writeToFile(file, m_buffer->data(), m_bufferSize) == m_bufferSize; -} - -void CacheResult::onWriteToFileDone() -{ - MutexLocker lock(m_mutex); - m_isAsyncOperationInProgress = false; - m_condition.signal(); -} - -HttpResponseHeaders* CacheResult::responseHeaders() const -{ - MutexLocker lock(m_mutex); - if (m_responseHeaders) - return m_responseHeaders; - - // Getting the headers is potentially async, so post to the Chromium thread - // and block here. - base::Thread* thread = WebUrlLoaderClient::ioThread(); - if (!thread) - return 0; - - CacheResult* me = const_cast<CacheResult*>(this); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(me, &CacheResult::responseHeadersImpl)); - - m_isAsyncOperationInProgress = true; - while (m_isAsyncOperationInProgress) - m_condition.wait(m_mutex); - - return m_responseHeaders; -} - -void CacheResult::responseHeadersImpl() -{ - m_bufferSize = m_entry->GetDataSize(kResponseInfoIndex); - m_buffer = new IOBuffer(m_bufferSize); - - int rv = m_entry->ReadData(kResponseInfoIndex, 0, m_buffer, m_bufferSize, &m_onResponseHeadersDoneCallback); - if (rv == ERR_IO_PENDING) - return; - - onResponseHeadersDone(rv); -}; - -void CacheResult::onResponseHeadersDone(int size) -{ - MutexLocker lock(m_mutex); - // It's OK to throw away the HttpResponseInfo object as we hold our own ref - // to the headers. - HttpResponseInfo response; - bool truncated = false; // TODO: Waht is this param for? - if (size == m_bufferSize && HttpCache::ParseResponseInfo(m_buffer->data(), m_bufferSize, &response, &truncated)) - m_responseHeaders = response.headers; - m_isAsyncOperationInProgress = false; - m_condition.signal(); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/CacheResult.h b/WebKit/android/WebCoreSupport/CacheResult.h deleted file mode 100644 index c39570c..0000000 --- a/WebKit/android/WebCoreSupport/CacheResult.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011, 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 CacheResult_h -#define CacheResult_h - -#include "ChromiumIncludes.h" - -#include <wtf/RefCounted.h> -#include <wtf/ThreadingPrimitives.h> -#include <wtf/text/WTFString.h> - -namespace android { - -// A wrapper around a disk_cache::Entry. Provides fields appropriate for constructing a Java CacheResult object. -class CacheResult : public base::RefCountedThreadSafe<CacheResult> { -public: - // Takes ownership of the Entry passed to the constructor. - CacheResult(disk_cache::Entry*, String url); - ~CacheResult(); - - int64 contentSize() const; - bool firstResponseHeader(const char* name, WTF::String* result, bool allowEmptyString) const; - // The Android stack uses the empty string if no Content-Type headers are - // found, so we use the same default here. - WTF::String mimeType() const; - // Returns the value of the expires header as milliseconds since the epoch. - int64 expires() const; - int responseCode() const; - bool writeToFile(const WTF::String& filePath) const; -private: - net::HttpResponseHeaders* responseHeaders() const; - void responseHeadersImpl(); - void onResponseHeadersDone(int size); - - void writeToFileImpl(); - void readNextChunk(); - void onReadNextChunkDone(int size); - bool writeChunkToFile(); - void onWriteToFileDone(); - - disk_cache::Entry* m_entry; - - scoped_refptr<net::HttpResponseHeaders> m_responseHeaders; - - int m_readOffset; - bool m_wasWriteToFileSuccessful; - mutable String m_filePath; - - int m_bufferSize; - scoped_refptr<net::IOBuffer> m_buffer; - mutable bool m_isAsyncOperationInProgress; - mutable WTF::Mutex m_mutex; - mutable WTF::ThreadCondition m_condition; - - net::CompletionCallbackImpl<CacheResult> m_onResponseHeadersDoneCallback; - net::CompletionCallbackImpl<CacheResult> m_onReadNextChunkDoneCallback; - - String m_url; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.cpp b/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.cpp deleted file mode 100644 index 30f374f..0000000 --- a/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "CachedFramePlatformDataAndroid.h" -#include "Settings.h" - -namespace android { - -CachedFramePlatformDataAndroid::CachedFramePlatformDataAndroid(WebCore::Settings* settings) -{ -#ifdef ANDROID_META_SUPPORT - m_viewport_width = settings->viewportWidth(); - m_viewport_height = settings->viewportHeight(); - m_viewport_initial_scale = settings->viewportInitialScale(); - m_viewport_minimum_scale = settings->viewportMinimumScale(); - m_viewport_maximum_scale = settings->viewportMaximumScale(); - m_viewport_target_densitydpi = settings->viewportTargetDensityDpi(); - m_viewport_user_scalable = settings->viewportUserScalable(); - m_format_detection_address = settings->formatDetectionAddress(); - m_format_detection_email = settings->formatDetectionEmail(); - m_format_detection_telephone = settings->formatDetectionTelephone(); -#endif - -} - -#ifdef ANDROID_META_SUPPORT -void CachedFramePlatformDataAndroid::restoreMetadata(WebCore::Settings* settings) -{ - settings->setViewportWidth(m_viewport_width); - settings->setViewportHeight(m_viewport_height); - settings->setViewportInitialScale(m_viewport_initial_scale); - settings->setViewportMinimumScale(m_viewport_minimum_scale); - settings->setViewportMaximumScale(m_viewport_maximum_scale); - settings->setViewportTargetDensityDpi(m_viewport_target_densitydpi); - settings->setViewportUserScalable(m_viewport_user_scalable); - settings->setFormatDetectionAddress(m_format_detection_address); - settings->setFormatDetectionEmail(m_format_detection_email); - settings->setFormatDetectionTelephone(m_format_detection_telephone); -} -#endif - -} diff --git a/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.h b/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.h deleted file mode 100644 index 20c7be4..0000000 --- a/WebKit/android/WebCoreSupport/CachedFramePlatformDataAndroid.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 CachedFramePlatformDatatAndroid_h -#define CachedFramePlatformDatatAndroid_h - -#include "CachedFramePlatformData.h" - -namespace WebCore { - class Settings; -} - -namespace android { - -class CachedFramePlatformDataAndroid : public WebCore::CachedFramePlatformData { -public: - CachedFramePlatformDataAndroid(WebCore::Settings* settings); - -#ifdef ANDROID_META_SUPPORT - void restoreMetadata(WebCore::Settings* settings); -#endif - -private: -#ifdef ANDROID_META_SUPPORT - // meta data of the frame - int m_viewport_width; - int m_viewport_height; - int m_viewport_initial_scale; - int m_viewport_minimum_scale; - int m_viewport_maximum_scale; - int m_viewport_target_densitydpi; - bool m_viewport_user_scalable : 1; - bool m_format_detection_address : 1; - bool m_format_detection_email : 1; - bool m_format_detection_telephone : 1; -#endif -}; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp deleted file mode 100644 index 6f872b8..0000000 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright 2007, 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 "WebCore" - -#include "config.h" - -#include "ApplicationCacheStorage.h" -#include "ChromeClientAndroid.h" -#include "DatabaseTracker.h" -#include "Document.h" -#include "PlatformString.h" -#include "FloatRect.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "Geolocation.h" -#include "HTMLMediaElement.h" -#include "HTMLNames.h" -#include "Icon.h" -#include "LayerAndroid.h" -#include "Page.h" -#include "PopupMenuAndroid.h" -#include "ScriptController.h" -#include "SearchPopupMenuAndroid.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreViewBridge.h" -#include "WebViewCore.h" -#include "WindowFeatures.h" -#include "Settings.h" -#include "UserGestureIndicator.h" -#include <wtf/text/CString.h> - -namespace android { - -#if ENABLE(DATABASE) -static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedingQuota); -#endif - -#if USE(ACCELERATED_COMPOSITING) - -WebCore::GraphicsLayer* ChromeClientAndroid::layersSync() -{ - if (m_rootGraphicsLayer && m_needsLayerSync && m_webFrame) { - if (FrameView* frameView = m_webFrame->page()->mainFrame()->view()) - frameView->syncCompositingStateRecursive(); - } - m_needsLayerSync = false; - return m_rootGraphicsLayer; -} - -void ChromeClientAndroid::scheduleCompositingLayerSync() -{ - if (m_needsLayerSync) - return; - m_needsLayerSync = true; - WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view()); - if (webViewCore) - webViewCore->layersDraw(); -} - -void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization() -{ - // This should not be needed -} - -void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* layer) -{ - // frame is not used in Android as we should only get root graphics layer for the main frame - m_rootGraphicsLayer = layer; - if (!layer) - return; - scheduleCompositingLayerSync(); -} - -#endif - -void ChromeClientAndroid::setWebFrame(android::WebFrame* webframe) -{ - Release(m_webFrame); - m_webFrame = webframe; - Retain(m_webFrame); -} - -void ChromeClientAndroid::chromeDestroyed() -{ - Release(m_webFrame); - delete this; -} - -void ChromeClientAndroid::setWindowRect(const FloatRect&) { notImplemented(); } - -FloatRect ChromeClientAndroid::windowRect() { - ASSERT(m_webFrame); - if (!m_webFrame) - return FloatRect(); - FrameView* frameView = m_webFrame->page()->mainFrame()->view(); - if (!frameView) - return FloatRect(); - const WebCoreViewBridge* bridge = frameView->platformWidget(); - const IntRect& rect = bridge->getWindowBounds(); - FloatRect fRect(rect.x(), rect.y(), rect.width(), rect.height()); - return fRect; -} - -FloatRect ChromeClientAndroid::pageRect() { notImplemented(); return FloatRect(); } - -float ChromeClientAndroid::scaleFactor() -{ - ASSERT(m_webFrame); - return m_webFrame->density(); -} - -void ChromeClientAndroid::focus() -{ - ASSERT(m_webFrame); - bool isUserGesture = UserGestureIndicator::processingUserGesture(); - - // Ask the application to focus this WebView if the action is intiated by the user - if (isUserGesture) - m_webFrame->requestFocus(); -} -void ChromeClientAndroid::unfocus() { notImplemented(); } - -bool ChromeClientAndroid::canTakeFocus(FocusDirection) { notImplemented(); return false; } -void ChromeClientAndroid::takeFocus(FocusDirection) { notImplemented(); } - -void ChromeClientAndroid::focusedNodeChanged(Node* node) -{ - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->focusNodeChanged(node); -} - -void ChromeClientAndroid::focusedFrameChanged(Frame*) { notImplemented(); } - -Page* ChromeClientAndroid::createWindow(Frame* frame, const FrameLoadRequest&, - const WindowFeatures& features, const NavigationAction&) -{ - ASSERT(frame); -#ifdef ANDROID_MULTIPLE_WINDOWS - if (frame->settings() && !(frame->settings()->supportMultipleWindows())) - // If the client doesn't support multiple windows, just return the current page - return frame->page(); -#endif - - const WebCoreViewBridge* bridge = frame->view()->platformWidget(); - bool dialog = features.dialog || !features.resizable - || (features.heightSet && features.height < bridge->height() - && features.widthSet && features.width < bridge->width()) - || (!features.menuBarVisible && !features.statusBarVisible - && !features.toolBarVisible && !features.locationBarVisible - && !features.scrollbarsVisible); - // fullscreen definitely means no dialog - if (features.fullscreen) - dialog = false; - WebCore::Frame* newFrame = m_webFrame->createWindow(dialog, - ScriptController::processingUserGesture()); - if (newFrame) { - WebCore::Page* page = newFrame->page(); - page->setGroupName(frame->page()->groupName()); - return page; - } - return NULL; -} - -void ChromeClientAndroid::show() { notImplemented(); } - -bool ChromeClientAndroid::canRunModal() { notImplemented(); return false; } -void ChromeClientAndroid::runModal() { notImplemented(); } - -void ChromeClientAndroid::setToolbarsVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::toolbarsVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setStatusbarVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::statusbarVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setScrollbarsVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::scrollbarsVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setMenubarVisible(bool) { notImplemented(); } -bool ChromeClientAndroid::menubarVisible() { notImplemented(); return false; } - -void ChromeClientAndroid::setResizable(bool) { notImplemented(); } - -#if ENABLE(CONTEXT_MENUS) -void ChromeClientAndroid::showContextMenu() { notImplemented(); } -#endif - -// This function is called by the JavaScript bindings to print usually an error to -// a message console. Pass the message to the java side so that the client can -// handle it as it sees fit. -void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, MessageLevel msgLevel, const String& message, unsigned int lineNumber, const String& sourceID) { - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel); -} - -void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) -{ - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node); -} - -bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; } -bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { - String url = frame->document()->documentURI(); - return android::WebViewCore::getWebViewCore(frame->view())->jsUnload(url, message); -} - -void ChromeClientAndroid::closeWindowSoon() -{ - ASSERT(m_webFrame); - Page* page = m_webFrame->page(); - Frame* mainFrame = page->mainFrame(); - // This will prevent javascript cross-scripting during unload - page->setGroupName(String()); - // Stop loading but do not send the unload event - mainFrame->loader()->stopLoading(UnloadEventPolicyNone); - // Cancel all pending loaders - mainFrame->loader()->stopAllLoaders(); - // Remove all event listeners so that no javascript can execute as a result - // of mouse/keyboard events. - mainFrame->document()->removeAllEventListeners(); - // Close the window. - m_webFrame->closeWindow(android::WebViewCore::getWebViewCore(mainFrame->view())); -} - -void ChromeClientAndroid::runJavaScriptAlert(Frame* frame, const String& message) -{ - String url = frame->document()->documentURI(); - - android::WebViewCore::getWebViewCore(frame->view())->jsAlert(url, message); -} - -bool ChromeClientAndroid::runJavaScriptConfirm(Frame* frame, const String& message) -{ - String url = frame->document()->documentURI(); - - return android::WebViewCore::getWebViewCore(frame->view())->jsConfirm(url, message); -} - -/* This function is called for the javascript method Window.prompt(). A dialog should be shown on - * the screen with an input put box. First param is the text, the second is the default value for - * the input box, third is return param. If the function returns true, the value set in the third parameter - * is provided to javascript, else null is returned to the script. - */ -bool ChromeClientAndroid::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result) -{ - String url = frame->document()->documentURI(); - return android::WebViewCore::getWebViewCore(frame->view())->jsPrompt(url, message, defaultValue, result); -} -void ChromeClientAndroid::setStatusbarText(const String&) { notImplemented(); } - -// This is called by the JavaScript interpreter when a script has been running for a long -// time. A dialog should be shown to the user asking them if they would like to cancel the -// Javascript. If true is returned, the script is cancelled. -// To make a device more responsive, we default to return true to disallow long running script. -// This implies that some of scripts will not be completed. -bool ChromeClientAndroid::shouldInterruptJavaScript() { - FrameView* frameView = m_webFrame->page()->mainFrame()->view(); - return android::WebViewCore::getWebViewCore(frameView)->jsInterrupt(); -} - -bool ChromeClientAndroid::tabsToLinks() const { return false; } - -IntRect ChromeClientAndroid::windowResizerRect() const { return IntRect(0, 0, 0, 0); } - -void ChromeClientAndroid::invalidateWindow(const IntRect&, bool) -{ - notImplemented(); -} - -void ChromeClientAndroid::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/) -{ - notImplemented(); -} - -void ChromeClientAndroid::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) -{ - notImplemented(); -} - -// new to change 38068 (Nov 6, 2008) -void ChromeClientAndroid::scroll(const IntSize& scrollDelta, - const IntRect& rectToScroll, const IntRect& clipRect) { - notImplemented(); -} - -// new to change 38068 (Nov 6, 2008) -IntPoint ChromeClientAndroid::screenToWindow(const IntPoint&) const { - notImplemented(); - return IntPoint(); -} - -// new to change 38068 (Nov 6, 2008) -IntRect ChromeClientAndroid::windowToScreen(const IntRect&) const { - notImplemented(); - return IntRect(); -} - -PlatformPageClient ChromeClientAndroid::platformPageClient() const { - Page* page = m_webFrame->page(); - Frame* mainFrame = page->mainFrame(); - FrameView* view = mainFrame->view(); - PlatformWidget viewBridge = view->platformWidget(); - return viewBridge; -} - -void ChromeClientAndroid::contentsSizeChanged(Frame*, const IntSize&) const -{ - notImplemented(); -} - -void ChromeClientAndroid::scrollRectIntoView(const IntRect&, const ScrollView*) const -{ - notImplemented(); -} - -void ChromeClientAndroid::formStateDidChange(const Node*) -{ - notImplemented(); -} - -void ChromeClientAndroid::scrollbarsModeDidChange() const -{ - notImplemented(); -} - -void ChromeClientAndroid::mouseDidMoveOverElement(const HitTestResult&, unsigned int) {} -void ChromeClientAndroid::setToolTip(const String&, TextDirection) {} -void ChromeClientAndroid::print(Frame*) {} - -/* - * This function is called on the main (webcore) thread by SQLTransaction::deliverQuotaIncreaseCallback. - * The way that the callback mechanism is designed inside SQLTransaction means that there must be a new quota - * (which may be equal to the old quota if the user did not allow more quota) when this function returns. As - * we call into the browser thread to ask what to do with the quota, we block here and get woken up when the - * browser calls the native WebViewCore::SetDatabaseQuota method with the new quota value. - */ -#if ENABLE(DATABASE) -void ChromeClientAndroid::exceededDatabaseQuota(Frame* frame, const String& name) -{ - SecurityOrigin* origin = frame->document()->securityOrigin(); - DatabaseTracker& tracker = WebCore::DatabaseTracker::tracker(); - - // We want to wait on a new quota from the UI thread. Reset the m_newQuota variable to represent we haven't received a new quota. - m_newQuota = -1; - - // This origin is being tracked and has exceeded it's quota. Call into - // the Java side of things to inform the user. - unsigned long long currentQuota = 0; - if (tracker.hasEntryForOrigin(origin)) - currentQuota = tracker.quotaForOrigin(origin); - - unsigned long long estimatedSize = 0; - - // Only update estimatedSize if we are trying to create a a new database, i.e. the usage for the database is 0. - if (tracker.usageForDatabase(name, origin) == 0) - estimatedSize = tracker.detailsForNameAndOrigin(name, origin).expectedUsage(); - - android::WebViewCore::getWebViewCore(frame->view())->exceededDatabaseQuota(frame->document()->documentURI(), name, currentQuota, estimatedSize); - - // We've sent notification to the browser so now wait for it to come back. - m_quotaThreadLock.lock(); - while (m_newQuota == -1) { - m_quotaThreadCondition.wait(m_quotaThreadLock); - } - m_quotaThreadLock.unlock(); - - // If new quota is unavailable, we may be able to resolve the situation by shrinking the quota of an origin that asked for a lot but is only using a little. - // If we find such a site, shrink it's quota and ask Java to try again. - - if ((unsigned long long) m_newQuota == currentQuota && !m_triedToReclaimDBQuota) { - m_triedToReclaimDBQuota = true; // we should only try this once per quota overflow. - unsigned long long reclaimedQuotaBytes = tryToReclaimDatabaseQuota(origin); - - // If we were able to free up enough space, try asking Java again. - // Otherwise, give up and deny the new database. :( - if (reclaimedQuotaBytes >= estimatedSize) { - exceededDatabaseQuota(frame, name); - return; - } - } - - // Update the DatabaseTracker with the new quota value (if the user declined - // new quota, this may equal the old quota) - tracker.setQuota(origin, m_newQuota); - m_triedToReclaimDBQuota = false; -} - -static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedingQuota) { - DatabaseTracker& tracker = WebCore::DatabaseTracker::tracker(); - Vector<RefPtr<SecurityOrigin> > origins; - tracker.origins(origins); - unsigned long long reclaimedQuotaBytes = 0; - for (unsigned i = 0; i < origins.size(); i++) { - SecurityOrigin* originToReclaimFrom = origins[i].get(); - - // Don't try to reclaim from the origin that has exceeded its quota. - if (originToReclaimFrom->equal(originNeedingQuota)) - continue; - - unsigned long long originUsage = tracker.usageForOrigin(originToReclaimFrom); - unsigned long long originQuota = tracker.quotaForOrigin(originToReclaimFrom); - // If the origin has a quota that is more than it's current usage +1MB, shrink it. - static const int ONE_MB = 1 * 1024 * 1024; - if (originUsage + ONE_MB < originQuota) { - unsigned long long newQuota = originUsage + ONE_MB; - tracker.setQuota(originToReclaimFrom, newQuota); - reclaimedQuotaBytes += originQuota - newQuota; - } - } - return reclaimedQuotaBytes; -} -#endif - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) -void ChromeClientAndroid::reachedMaxAppCacheSize(int64_t spaceNeeded) -{ - // Set m_newQuota before calling into the Java side. If we do this after, - // we could overwrite the result passed from the Java side and deadlock in the - // wait call below. - m_newQuota = -1; - Page* page = m_webFrame->page(); - Frame* mainFrame = page->mainFrame(); - FrameView* view = mainFrame->view(); - android::WebViewCore::getWebViewCore(view)->reachedMaxAppCacheSize(spaceNeeded); - - // We've sent notification to the browser so now wait for it to come back. - m_quotaThreadLock.lock(); - while (m_newQuota == -1) { - m_quotaThreadCondition.wait(m_quotaThreadLock); - } - m_quotaThreadLock.unlock(); - if (m_newQuota > 0) { - WebCore::cacheStorage().setMaximumSize(m_newQuota); - // Now the app cache will retry the saving the previously failed cache. - } -} -#endif - -void ChromeClientAndroid::populateVisitedLinks() -{ - Page* page = m_webFrame->page(); - Frame* mainFrame = page->mainFrame(); - FrameView* view = mainFrame->view(); - 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) -{ - android::WebViewCore* core = android::WebViewCore::getWebViewCore( - frame->view()); - core->openFileChooser(chooser); -} - -void ChromeClientAndroid::chooseIconForFiles(const Vector<WTF::String>&, FileChooser*) -{ - notImplemented(); -} - -void ChromeClientAndroid::setCursor(const Cursor&) -{ - notImplemented(); -} - -void ChromeClientAndroid::wakeUpMainThreadWithNewQuota(long newQuota) { - MutexLocker locker(m_quotaThreadLock); - m_newQuota = newQuota; - m_quotaThreadCondition.signal(); -} - -#if ENABLE(TOUCH_EVENTS) -void ChromeClientAndroid::needTouchEvents(bool needTouchEvents) -{ - FrameView* frameView = m_webFrame->page()->mainFrame()->view(); - android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView); - if (core) - core->needTouchEvents(needTouchEvents); -} -#endif - -bool ChromeClientAndroid::selectItemWritingDirectionIsNatural() -{ - return false; -} - -PassRefPtr<PopupMenu> ChromeClientAndroid::createPopupMenu(PopupMenuClient* client) const -{ - return adoptRef(new PopupMenuAndroid(static_cast<ListPopupMenuClient*>(client))); -} - -PassRefPtr<SearchPopupMenu> ChromeClientAndroid::createSearchPopupMenu(PopupMenuClient*) const -{ - return adoptRef(new SearchPopupMenuAndroid); -} - -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) -{ - return node->hasTagName(HTMLNames::videoTag); -} - -void ChromeClientAndroid::enterFullscreenForNode(Node* node) -{ - if (!node->hasTagName(HTMLNames::videoTag)) - 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); -} - -void ChromeClientAndroid::exitFullscreenForNode(Node* node) -{ -} -#endif - -#if ENABLE(FULLSCREEN_API) -void ChromeClientAndroid::exitFullScreenForElement(Element* element) -{ - if (!element) - return; - - HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(element); - videoElement->exitFullscreen(); -} -#endif - -} diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h deleted file mode 100644 index d49cec8..0000000 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2007, 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 ChromeClientAndroid_h -#define ChromeClientAndroid_h - -#include "ChromeClient.h" - -#include "GeolocationPermissions.h" -#include "PopupMenu.h" -#include "SearchPopupMenu.h" -#include "Timer.h" -#include <wtf/PassRefPtr.h> -#include <wtf/Threading.h> - -namespace WebCore { -class PopupMenuClient; -class Geolocation; -} - -using namespace WebCore; - -namespace android { - class WebFrame; - - class ChromeClientAndroid : public ChromeClient { - public: - ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0) -#if USE(ACCELERATED_COMPOSITING) - , m_rootGraphicsLayer(0) - , m_needsLayerSync(false) -#endif - , m_triedToReclaimDBQuota(false) - { } - virtual void chromeDestroyed(); - - virtual void setWindowRect(const FloatRect&); - virtual FloatRect windowRect(); - - virtual FloatRect pageRect(); - - virtual float scaleFactor(); - - virtual void focus(); - virtual void unfocus(); - virtual void formDidBlur(const WebCore::Node*); - virtual bool canTakeFocus(FocusDirection); - virtual void takeFocus(FocusDirection); - - virtual void focusedNodeChanged(Node*); - virtual void focusedFrameChanged(Frame*); - - // The Frame pointer provides the ChromeClient with context about which - // Frame wants to create the new Page. Also, the newly created window - // should not be shown to the user until the ChromeClient of the newly - // created Page has its show method called. - virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); - virtual void show(); - - virtual bool canRunModal(); - virtual void runModal(); - - virtual void setToolbarsVisible(bool); - virtual bool toolbarsVisible(); - - virtual void setStatusbarVisible(bool); - virtual bool statusbarVisible(); - - virtual void setScrollbarsVisible(bool); - virtual bool scrollbarsVisible(); - - virtual void setMenubarVisible(bool); - virtual bool menubarVisible(); - - virtual void setResizable(bool); - - virtual void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID); - - virtual bool canRunBeforeUnloadConfirmPanel(); - virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame); - - virtual void closeWindowSoon(); - - virtual void runJavaScriptAlert(Frame*, const String&); - virtual bool runJavaScriptConfirm(Frame*, const String&); - virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result); - virtual void setStatusbarText(const String&); - virtual bool shouldInterruptJavaScript(); - virtual bool tabsToLinks() const; - - virtual IntRect windowResizerRect() const; - - // Methods used by HostWindow. - virtual void invalidateWindow(const WebCore::IntRect&, bool); - virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); - virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); - virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); - virtual IntPoint screenToWindow(const IntPoint&) const; - virtual IntRect windowToScreen(const IntRect&) const; - virtual PlatformPageClient platformPageClient() const; - virtual void contentsSizeChanged(Frame*, const IntSize&) const; - virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const; - // End methods used by HostWindow. - - virtual void scrollbarsModeDidChange() const; - virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned int); - - virtual void setToolTip(const String&, TextDirection); - - virtual void print(Frame*); -#if ENABLE(DATABASE) - virtual void exceededDatabaseQuota(Frame*, const String&); -#endif -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); - virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); -#endif - - virtual void populateVisitedLinks(); - -#if ENABLE(TOUCH_EVENTS) - virtual void needTouchEvents(bool); -#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(); - - virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); - virtual void setCursor(const Cursor&); - virtual void chooseIconForFiles(const WTF::Vector<WTF::String>&, FileChooser*); - - // Notification that the given form element has changed. This function - // will be called frequently, so handling should be very fast. - virtual void formStateDidChange(const Node*); - - virtual PassOwnPtr<HTMLParserQuirks> createHTMLParserQuirks() { return 0; } - - // Android-specific - void setWebFrame(android::WebFrame* webframe); - android::WebFrame* webFrame() { return m_webFrame; } - void wakeUpMainThreadWithNewQuota(long newQuota); - -#if USE(ACCELERATED_COMPOSITING) - virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g); - virtual void setNeedsOneShotDrawingSynchronization(); - virtual void scheduleCompositingLayerSync(); - virtual bool allowsAcceleratedCompositing() const { return true; } - WebCore::GraphicsLayer* layersSync(); -#endif - - virtual bool selectItemWritingDirectionIsNatural(); - virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const; - virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const; - -#if ENABLE(CONTEXT_MENUS) - virtual void showContextMenu(); -#endif - -#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS) - virtual void webAppCanBeInstalled(); -#endif - -#if ENABLE(FULLSCREEN_API) - virtual void exitFullScreenForElement(Element*); -#endif - -#if ENABLE(VIDEO) - virtual bool supportsFullscreenForNode(const WebCore::Node*); - virtual void enterFullscreenForNode(WebCore::Node*); - virtual void exitFullscreenForNode(WebCore::Node*); -#endif - - private: - android::WebFrame* m_webFrame; - // The Geolocation permissions manager. - OwnPtr<GeolocationPermissions> m_geolocationPermissions; -#if USE(ACCELERATED_COMPOSITING) - WebCore::GraphicsLayer* m_rootGraphicsLayer; - bool m_needsLayerSync; -#endif - WTF::ThreadCondition m_quotaThreadCondition; - WTF::Mutex m_quotaThreadLock; - long m_newQuota; - bool m_triedToReclaimDBQuota; - }; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/ChromiumIncludes.h b/WebKit/android/WebCoreSupport/ChromiumIncludes.h deleted file mode 100644 index 8166eb7..0000000 --- a/WebKit/android/WebCoreSupport/ChromiumIncludes.h +++ /dev/null @@ -1,104 +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 ChromiumIncludes_h -#define ChromiumIncludes_h - -#include "config.h" - -// Include all external/chromium files in this file so the problems with the LOG -// and LOG_ASSERT defines can be handled in one place. - -// Undefine LOG and LOG_ASSERT before including chrome code, and if they were -// defined attempt to set the macros to the Android logging macros (which are -// the only ones that actually log). - -#ifdef LOG -#define LOG_WAS_DEFINED LOG -#undef LOG -#endif - -#ifdef LOG_ASSERT -#define LOG_ASSERT_WAS_DEFINED LOG_ASSERT -#undef LOG_ASSERT -#endif - -#include <android/net/android_network_library_impl.h> -#include <base/callback.h> -#include <base/condition_variable.h> -#include <base/lock.h> -#include <base/message_loop_proxy.h> -#include <base/ref_counted.h> -#include <base/string_util.h> -#include <base/sys_string_conversions.h> -#include <base/thread.h> -#include <base/time.h> -#include <base/tuple.h> -#include <chrome/browser/net/sqlite_persistent_cookie_store.h> -#include <net/base/auth.h> -#include <net/base/cookie_monster.h> -#include <net/base/cookie_policy.h> -#include <net/base/data_url.h> -#include <net/base/host_resolver.h> -#include <net/base/io_buffer.h> -#include <net/base/load_flags.h> -#include <net/base/net_errors.h> -#include <net/base/mime_util.h> -#include <net/base/ssl_config_service.h> -#include <net/disk_cache/disk_cache.h> -#include <net/http/http_auth_handler_factory.h> -#include <net/http/http_cache.h> -#include <net/http/http_network_layer.h> -#include <net/http/http_response_headers.h> -#include <net/proxy/proxy_config_service_android.h> -#include <net/proxy/proxy_service.h> -#include <net/url_request/url_request.h> -#include <net/url_request/url_request_context.h> - -#if ENABLE(WEB_AUTOFILL) -#include <autofill/autofill_manager.h> -#include <autofill/autofill_profile.h> -#include <autofill/personal_data_manager.h> -#include <base/logging.h> -#include <base/scoped_vector.h> -#include <base/string16.h> -#include <base/utf_string_conversions.h> -#include <chrome/browser/autofill/autofill_host.h> -#include <chrome/browser/profile.h> -#include <chrome/browser/tab_contents/tab_contents.h> -#include <webkit/glue/form_data.h> -#endif - -#undef LOG -#if defined(LOG_WAS_DEFINED) && defined(LOG_PRI) -#define LOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) -#endif - -#undef LOG_ASSERT -#if defined(LOG_ASSERT_WAS_DEFINED) && defined(LOG_FATAL_IF) -#define LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__) -#endif - -#endif diff --git a/WebKit/android/WebCoreSupport/ChromiumInit.cpp b/WebKit/android/WebCoreSupport/ChromiumInit.cpp deleted file mode 100644 index 1872fb9..0000000 --- a/WebKit/android/WebCoreSupport/ChromiumInit.cpp +++ /dev/null @@ -1,74 +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. - */ - -#include "config.h" -#include "ChromiumInit.h" - -#include "ChromiumIncludes.h" - -#include <cutils/log.h> -#include <string> - -namespace android { - -bool logMessageHandler(int severity, const char* file, int line, size_t message_start, const std::string& str) { - int androidSeverity = ANDROID_LOG_VERBOSE; - switch(severity) { - case logging::LOG_FATAL: - androidSeverity = ANDROID_LOG_FATAL; - break; - case logging::LOG_ERROR_REPORT: - case logging::LOG_ERROR: - androidSeverity = ANDROID_LOG_ERROR; - break; - case logging::LOG_WARNING: - androidSeverity = ANDROID_LOG_WARN; - break; - default: - androidSeverity = ANDROID_LOG_VERBOSE; - break; - } - android_printLog(androidSeverity, "chromium", "%s:%d: %s", file, line, str.c_str()); - return false; -} - -namespace { - scoped_ptr<net::NetworkChangeNotifier> networkChangeNotifier; -} - -void initChromium() -{ - static Lock lock; - AutoLock aLock(lock); - static bool initCalled = false; - if (!initCalled) { - logging::SetLogMessageHandler(logMessageHandler); - networkChangeNotifier.reset(net::NetworkChangeNotifier::Create()); - net::HttpNetworkLayer::EnableSpdy("npn"); - initCalled = true; - } -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/ChromiumInit.h b/WebKit/android/WebCoreSupport/ChromiumInit.h deleted file mode 100644 index 235c3dc..0000000 --- a/WebKit/android/WebCoreSupport/ChromiumInit.h +++ /dev/null @@ -1,38 +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 ChromiumLogging_h -#define ChromiumLogging_h - -namespace android { - -// Sends chromium logs to logcat -// -// This only calls into chromium once, but can be called multiple times. -// It should be called before any other calls into external/chromium. -void initChromium(); -} - -#endif diff --git a/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.cpp b/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.cpp deleted file mode 100644 index 3dc4b00..0000000 --- a/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2007, 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 "ContextMenuClientAndroid.h" - -#include "NotImplemented.h" -#include <wtf/Assertions.h> - -namespace WebCore { - -void ContextMenuClientAndroid::contextMenuDestroyed() { delete this; } - -PlatformMenuDescription ContextMenuClientAndroid::getCustomMenuFromDefaultItems(ContextMenu*) { notImplemented(); return 0; } -void ContextMenuClientAndroid::contextMenuItemSelected(ContextMenuItem*, const ContextMenu*) { notImplemented(); } - -void ContextMenuClientAndroid::downloadURL(const KURL& url) { notImplemented(); } -void ContextMenuClientAndroid::copyImageToClipboard(const HitTestResult&) { notImplemented(); } -void ContextMenuClientAndroid::searchWithGoogle(const Frame*) { notImplemented(); } -void ContextMenuClientAndroid::lookUpInDictionary(Frame*) { notImplemented(); } -void ContextMenuClientAndroid::speak(const String&) { notImplemented(); } -void ContextMenuClientAndroid::stopSpeaking() { notImplemented(); } -bool ContextMenuClientAndroid::isSpeaking() -{ - notImplemented(); - return false; -} - -} diff --git a/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.h b/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.h deleted file mode 100644 index 4563829..0000000 --- a/WebKit/android/WebCoreSupport/ContextMenuClientAndroid.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2007, 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 ContextMenuClientAndroid_h -#define ContextMenuClientAndroid_h - -#include "ContextMenuClient.h" - -namespace WebCore { - -class ContextMenuClientAndroid : public ContextMenuClient { -public: - virtual void contextMenuDestroyed(); - - virtual PlatformMenuDescription getCustomMenuFromDefaultItems(ContextMenu*); - virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*); - - virtual void downloadURL(const KURL& url); - virtual void copyImageToClipboard(const HitTestResult&); - virtual void searchWithGoogle(const Frame*); - virtual void lookUpInDictionary(Frame*); - virtual void speak(const String&); - virtual void stopSpeaking(); - virtual bool isSpeaking(); -}; - -} // namespace WebCore - -#endif // ContextMenuClientAndroid_h diff --git a/WebKit/android/WebCoreSupport/CookieClient.h b/WebKit/android/WebCoreSupport/CookieClient.h deleted file mode 100644 index 56d9382..0000000 --- a/WebKit/android/WebCoreSupport/CookieClient.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2007, 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 COOKIE_CLIENT_H -#define COOKIE_CLIENT_H - -#include <KURL.h> -#include <PlatformString.h> - -using namespace WebCore; - -namespace android { - -class CookieClient { - -public: - virtual ~CookieClient() {} - virtual void setCookies(const KURL& url, const String& value) = 0; - virtual String cookies(const KURL& url) = 0; - virtual bool cookiesEnabled() = 0; -}; - -} -#endif diff --git a/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.cpp b/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.cpp deleted file mode 100644 index f8de733..0000000 --- a/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.cpp +++ /dev/null @@ -1,84 +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. - */ - -#include "config.h" -#include "DeviceMotionClientAndroid.h" - -#include "WebViewCore.h" - -using namespace WebCore; - -namespace android { - -DeviceMotionClientAndroid::DeviceMotionClientAndroid() - : m_client(0) -{ -} - -void DeviceMotionClientAndroid::setWebViewCore(WebViewCore* webViewCore) -{ - m_webViewCore = webViewCore; - ASSERT(m_webViewCore); -} - -void DeviceMotionClientAndroid::setController(DeviceMotionController* controller) -{ - // This will be called by the Page constructor before the WebViewCore - // has been configured regarding the mock. We cache the controller for - // later use. - m_controller = controller; - ASSERT(m_controller); -} - -void DeviceMotionClientAndroid::startUpdating() -{ - client()->startUpdating(); -} - -void DeviceMotionClientAndroid::stopUpdating() -{ - client()->stopUpdating(); -} - -DeviceMotionData* DeviceMotionClientAndroid::currentDeviceMotion() const -{ - return client()->currentDeviceMotion(); -} - -void DeviceMotionClientAndroid::deviceMotionControllerDestroyed() -{ - delete this; -} - -DeviceMotionClient* DeviceMotionClientAndroid::client() const -{ - if (!m_client) { - m_client = m_webViewCore->deviceMotionAndOrientationManager()->motionClient(); - m_client->setController(m_controller); - } - return m_client; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.h b/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.h deleted file mode 100644 index 98d4709..0000000 --- a/WebKit/android/WebCoreSupport/DeviceMotionClientAndroid.h +++ /dev/null @@ -1,65 +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 DeviceMotionClientAndroid_h -#define DeviceMotionClientAndroid_h - -#include <DeviceMotionClient.h> - -namespace WebCore { -class DeviceMotionController; -} - -namespace android { - -class WebViewCore; - -// The Android implementation of DeviceMotionClient. Acts as a proxy to -// the real or mock impl, which is owned by the WebViewCore. -class DeviceMotionClientAndroid : public WebCore::DeviceMotionClient { -public: - DeviceMotionClientAndroid(); - - void setWebViewCore(WebViewCore*); - - // DeviceMotionClient methods - virtual void setController(WebCore::DeviceMotionController*); - virtual void startUpdating(); - virtual void stopUpdating(); - virtual WebCore::DeviceMotionData* currentDeviceMotion() const; - virtual void deviceMotionControllerDestroyed(); - -private: - WebCore::DeviceMotionClient* client() const; - - WebViewCore* m_webViewCore; - WebCore::DeviceMotionController* m_controller; - // Lazily obtained cache of the client owned by the WebViewCore. - mutable WebCore::DeviceMotionClient* m_client; -}; - -} // namespace android - -#endif // DeviceMotionClientAndroid_h diff --git a/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.cpp b/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.cpp deleted file mode 100644 index 9d7145c..0000000 --- a/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.cpp +++ /dev/null @@ -1,84 +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. - */ - -#include "config.h" -#include "DeviceOrientationClientAndroid.h" - -#include "WebViewCore.h" - -using namespace WebCore; - -namespace android { - -DeviceOrientationClientAndroid::DeviceOrientationClientAndroid() - : m_client(0) -{ -} - -void DeviceOrientationClientAndroid::setWebViewCore(WebViewCore* webViewCore) -{ - m_webViewCore = webViewCore; - ASSERT(m_webViewCore); -} - -void DeviceOrientationClientAndroid::setController(DeviceOrientationController* controller) -{ - // This will be called by the Page constructor before the WebViewCore - // has been configured regarding the mock. We cache the controller for - // later use. - m_controller = controller; - ASSERT(m_controller); -} - -void DeviceOrientationClientAndroid::startUpdating() -{ - client()->startUpdating(); -} - -void DeviceOrientationClientAndroid::stopUpdating() -{ - client()->stopUpdating(); -} - -DeviceOrientation* DeviceOrientationClientAndroid::lastOrientation() const -{ - return client()->lastOrientation(); -} - -void DeviceOrientationClientAndroid::deviceOrientationControllerDestroyed() -{ - delete this; -} - -DeviceOrientationClient* DeviceOrientationClientAndroid::client() const -{ - if (!m_client) { - m_client = m_webViewCore->deviceMotionAndOrientationManager()->orientationClient(); - m_client->setController(m_controller); - } - return m_client; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.h b/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.h deleted file mode 100644 index 7842b95..0000000 --- a/WebKit/android/WebCoreSupport/DeviceOrientationClientAndroid.h +++ /dev/null @@ -1,65 +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 DeviceOrientationClientAndroid_h -#define DeviceOrientationClientAndroid_h - -#include <DeviceOrientationClient.h> - -namespace WebCore { -class DeviceOrientationController; -} - -namespace android { - -class WebViewCore; - -// The Android implementation of DeviceOrientationClient. Acts as a proxy to -// the real or mock impl, which is owned by the WebViewCore. -class DeviceOrientationClientAndroid : public WebCore::DeviceOrientationClient { -public: - DeviceOrientationClientAndroid(); - - void setWebViewCore(WebViewCore*); - - // DeviceOrientationClient methods - virtual void setController(WebCore::DeviceOrientationController*); - virtual void startUpdating(); - virtual void stopUpdating(); - virtual WebCore::DeviceOrientation* lastOrientation() const; - virtual void deviceOrientationControllerDestroyed(); - -private: - WebCore::DeviceOrientationClient* client() const; - - WebViewCore* m_webViewCore; - WebCore::DeviceOrientationController* m_controller; - // Lazily obtained cache of the client owned by the WebViewCore. - mutable WebCore::DeviceOrientationClient* m_client; -}; - -} // namespace android - -#endif // DeviceOrientationClientAndroid_h diff --git a/WebKit/android/WebCoreSupport/DragClientAndroid.cpp b/WebKit/android/WebCoreSupport/DragClientAndroid.cpp deleted file mode 100644 index f64b80c..0000000 --- a/WebKit/android/WebCoreSupport/DragClientAndroid.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2007, 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 "WebCore" - -#include "config.h" -#include "DragClientAndroid.h" -#include "NotImplemented.h" - -namespace android { - -void DragClientAndroid::dragControllerDestroyed() { notImplemented(); delete this; } - -void DragClientAndroid::willPerformDragDestinationAction(DragDestinationAction, DragData*) { notImplemented(); } - -DragDestinationAction DragClientAndroid::actionMaskForDrag(DragData*) { notImplemented(); return DragDestinationActionNone; } - -DragSourceAction DragClientAndroid::dragSourceActionMaskForPoint(const IntPoint&) { notImplemented(); return DragSourceActionNone; } - -void* DragClientAndroid::createDragImageForLink(KURL&, String const&, Frame*) { return NULL; } -void DragClientAndroid::willPerformDragSourceAction(DragSourceAction, IntPoint const&, Clipboard*) {} -void DragClientAndroid::startDrag(void*, IntPoint const&, IntPoint const&, Clipboard*, Frame*, bool) {} - -} diff --git a/WebKit/android/WebCoreSupport/DragClientAndroid.h b/WebKit/android/WebCoreSupport/DragClientAndroid.h deleted file mode 100644 index 020e1f1..0000000 --- a/WebKit/android/WebCoreSupport/DragClientAndroid.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2007, 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 DragClientAndroid_h -#define DragClientAndroid_h - -#include "DragClient.h" - -using namespace WebCore; - -namespace android { - - class DragClientAndroid : public DragClient { - public: - virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*); - virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*); - virtual DragDestinationAction actionMaskForDrag(DragData*); - //We work in window rather than view coordinates here - virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint&); - - virtual void startDrag(DragImageRef dragImage, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false); - virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*); - - virtual void dragControllerDestroyed(); - }; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp b/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp deleted file mode 100644 index 250fdbf..0000000 --- a/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2007, 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 "WebCore" - -#include "config.h" -#include "Editor.h" -#include "EditorClientAndroid.h" -#include "Event.h" -#include "EventNames.h" -#include "FocusController.h" -#include "Frame.h" -#include "HTMLNames.h" -#include "KeyboardEvent.h" -#include "NotImplemented.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformString.h" -#include "WebViewCore.h" -#include "WindowsKeyboardCodes.h" - -using namespace WebCore::HTMLNames; - -namespace android { - -void EditorClientAndroid::pageDestroyed() { - delete this; -} - -bool EditorClientAndroid::shouldDeleteRange(Range*) { return true; } -bool EditorClientAndroid::shouldShowDeleteInterface(HTMLElement*) { notImplemented(); return false; } -bool EditorClientAndroid::smartInsertDeleteEnabled() { notImplemented(); return false; } -bool EditorClientAndroid::isSelectTrailingWhitespaceEnabled(){ notImplemented(); return false; } -bool EditorClientAndroid::isContinuousSpellCheckingEnabled() { notImplemented(); return false; } -void EditorClientAndroid::toggleContinuousSpellChecking() { notImplemented(); } -bool EditorClientAndroid::isGrammarCheckingEnabled() { notImplemented(); return false; } -void EditorClientAndroid::toggleGrammarChecking() { notImplemented(); } -int EditorClientAndroid::spellCheckerDocumentTag() { notImplemented(); return -1; } - -bool EditorClientAndroid::isEditable() { /* notImplemented(); */ return false; } - -// Following Qt's implementation. For shouldBeginEditing and shouldEndEditing. -// Returning true for these fixes issue http://b/issue?id=735185 -bool EditorClientAndroid::shouldBeginEditing(Range*) -{ - return true; -} - -bool EditorClientAndroid::shouldEndEditing(Range*) -{ - return true; -} - -bool EditorClientAndroid::shouldInsertNode(Node*, Range*, EditorInsertAction) { notImplemented(); return true; } -bool EditorClientAndroid::shouldInsertText(const String&, Range*, EditorInsertAction) { return true; } -bool EditorClientAndroid::shouldApplyStyle(CSSStyleDeclaration*, Range*) { notImplemented(); return true; } - -void EditorClientAndroid::didBeginEditing() { notImplemented(); } - -// This function is called so that the platform can handle changes to content. It is called -// after the contents have been edited or unedited (ie undo) -void EditorClientAndroid::respondToChangedContents() { notImplemented(); } - -void EditorClientAndroid::didEndEditing() { notImplemented(); } -void EditorClientAndroid::didWriteSelectionToPasteboard() { notImplemented(); } -void EditorClientAndroid::didSetSelectionTypesForPasteboard() { notImplemented(); } - -// Copied from the Window's port of WebKit. -static const unsigned AltKey = 1 << 0; -static const unsigned ShiftKey = 1 << 1; - -struct KeyDownEntry { - unsigned virtualKey; - unsigned modifiers; - const char* name; -}; - -struct KeyPressEntry { - unsigned charCode; - unsigned modifiers; - const char* name; -}; - -static const KeyDownEntry keyDownEntries[] = { - { VK_LEFT, 0, "MoveLeft" }, - { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" }, - { VK_LEFT, AltKey, "MoveWordLeft" }, - { VK_LEFT, AltKey | ShiftKey, "MoveWordLeftAndModifySelection" }, - { VK_RIGHT, 0, "MoveRight" }, - { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" }, - { VK_RIGHT, AltKey, "MoveWordRight" }, - { VK_RIGHT, AltKey | ShiftKey, "MoveWordRightAndModifySelection" }, - { VK_UP, 0, "MoveUp" }, - { VK_UP, ShiftKey, "MoveUpAndModifySelection" }, - { VK_DOWN, 0, "MoveDown" }, - { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" }, - - { VK_BACK, 0, "BackwardDelete" }, - { VK_BACK, ShiftKey, "ForwardDelete" }, - { VK_BACK, AltKey, "DeleteWordBackward" }, - { VK_BACK, AltKey | ShiftKey, "DeleteWordForward" }, - - { VK_ESCAPE, 0, "Cancel" }, - { VK_TAB, 0, "InsertTab" }, - { VK_TAB, ShiftKey, "InsertBacktab" }, - { VK_RETURN, 0, "InsertNewline" }, - { VK_RETURN, AltKey, "InsertNewline" }, - { VK_RETURN, AltKey | ShiftKey, "InsertNewline" } -}; - -static const KeyPressEntry keyPressEntries[] = { - { '\t', 0, "InsertTab" }, - { '\t', ShiftKey, "InsertBackTab" }, - { '\r', 0, "InsertNewline" }, - { '\r', AltKey, "InsertNewline" }, - { '\r', AltKey | ShiftKey, "InsertNewline" } -}; - -static const char* interpretKeyEvent(const KeyboardEvent* evt) -{ - const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); - - static HashMap<int, const char*>* keyDownCommandsMap = 0; - static HashMap<int, const char*>* keyPressCommandsMap = 0; - - if (!keyDownCommandsMap) { - keyDownCommandsMap = new HashMap<int, const char*>; - keyPressCommandsMap = new HashMap<int, const char*>; - - for (unsigned i = 0; i < sizeof(keyDownEntries)/sizeof(KeyDownEntry); i++) - keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); - - for (unsigned i = 0; i < sizeof(keyPressEntries)/sizeof(KeyPressEntry); i++) - keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name); - } - - unsigned modifiers = 0; - if (keyEvent->shiftKey()) - modifiers |= ShiftKey; - if (keyEvent->altKey()) - modifiers |= AltKey; - - if (evt->type() == eventNames().keydownEvent) { - int mapKey = modifiers << 16 | evt->keyCode(); - return mapKey ? keyDownCommandsMap->get(mapKey) : 0; - } - - int mapKey = modifiers << 16 | evt->charCode(); - return mapKey ? keyPressCommandsMap->get(mapKey) : 0; -} - -void EditorClientAndroid::handleKeyboardEvent(KeyboardEvent* event) { - ASSERT(m_page); - Frame* frame = m_page->focusController()->focusedOrMainFrame(); - if (!frame) - return; - - const PlatformKeyboardEvent* keyEvent = event->keyEvent(); - // TODO: If the event is not coming from Android Java, e.g. from JavaScript, - // PlatformKeyboardEvent is null. We should support this later. - if (!keyEvent) - return; - - Editor::Command command = frame->editor()->command(interpretKeyEvent(event)); - if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { - if (!command.isTextInsertion() && command.execute(event)) { - // This function mimics the Windows version. However, calling event->setDefaultHandled() - // prevents the javascript key events for the delete key from happening. - // Update: Safari doesn't send delete key events to javascript so - // we will mimic that behavior. - event->setDefaultHandled(); - } - return; - } - - if (command.execute(event)) { - event->setDefaultHandled(); - return; - } - - // Don't insert null or control characters as they can result in unexpected behaviour - if (event->charCode() < ' ') - return; - - if (frame->editor()->insertText(keyEvent->text(), event)) - event->setDefaultHandled(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -// we just don't support Undo/Redo at the moment - -void EditorClientAndroid::registerCommandForUndo(PassRefPtr<EditCommand>) {} -void EditorClientAndroid::registerCommandForRedo(PassRefPtr<EditCommand>) {} -void EditorClientAndroid::clearUndoRedoOperations() {} -bool EditorClientAndroid::canUndo() const { return false; } -bool EditorClientAndroid::canRedo() const { return false; } -void EditorClientAndroid::undo() {} -void EditorClientAndroid::redo() {} - -// functions new to Jun-07 tip of tree merge: -void EditorClientAndroid::showSpellingUI(bool) {} -void EditorClientAndroid::getGuessesForWord(String const&, const String&, WTF::Vector<String>&) {} -bool EditorClientAndroid::spellingUIIsShowing() { return false; } -void EditorClientAndroid::checkGrammarOfString(unsigned short const*, int, WTF::Vector<GrammarDetail>&, int*, int*) {} -void EditorClientAndroid::checkSpellingOfString(unsigned short const*, int, int*, int*) {} -String EditorClientAndroid::getAutoCorrectSuggestionForMisspelledWord(const String&) { return String(); } -void EditorClientAndroid::textFieldDidEndEditing(Element*) {} -void EditorClientAndroid::textDidChangeInTextArea(Element*) {} -void EditorClientAndroid::textDidChangeInTextField(Element*) {} -void EditorClientAndroid::textFieldDidBeginEditing(Element*) {} -void EditorClientAndroid::ignoreWordInSpellDocument(String const&) {} - -// We need to pass the selection up to the WebTextView -void EditorClientAndroid::respondToChangedSelection() { - if (m_uiGeneratedSelectionChange) - return; - Frame* frame = m_page->focusController()->focusedOrMainFrame(); - if (!frame || !frame->view()) - return; - WebViewCore* webViewCore = WebViewCore::getWebViewCore(frame->view()); - webViewCore->updateTextSelection(); -} - -bool EditorClientAndroid::shouldChangeSelectedRange(Range*, Range*, EAffinity, - bool) { - return m_shouldChangeSelectedRange; -} - -bool EditorClientAndroid::doTextFieldCommandFromEvent(Element*, KeyboardEvent*) { return false; } -void EditorClientAndroid::textWillBeDeletedInTextField(Element*) {} -void EditorClientAndroid::updateSpellingUIWithGrammarString(String const&, GrammarDetail const&) {} -void EditorClientAndroid::updateSpellingUIWithMisspelledWord(String const&) {} -void EditorClientAndroid::learnWord(String const&) {} - -// functions new to the Nov-16-08 tip of tree merge: -bool EditorClientAndroid::shouldMoveRangeAfterDelete(Range*, Range*) { return true; } -void EditorClientAndroid::setInputMethodState(bool) {} - -// functions new to Feb-19 tip of tree merge: -void EditorClientAndroid::handleInputMethodKeydown(KeyboardEvent*) {} - -void EditorClientAndroid::willSetInputMethodState() -{ - notImplemented(); -} - -void EditorClientAndroid::requestCheckingOfString(SpellChecker*, int, const String&) {} - -#if ENABLE(WEB_AUTOFILL) -WebAutoFill* EditorClientAndroid::getAutoFill() -{ - if (!m_autoFill) - m_autoFill.set(new WebAutoFill()); - - return m_autoFill.get(); -} -#endif - -} diff --git a/WebKit/android/WebCoreSupport/EditorClientAndroid.h b/WebKit/android/WebCoreSupport/EditorClientAndroid.h deleted file mode 100644 index 94a6518..0000000 --- a/WebKit/android/WebCoreSupport/EditorClientAndroid.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2007, 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 EditorClientAndroid_h -#define EditorClientAndroid_h - -#include "config.h" - - -#include "EditorClient.h" -#include "Page.h" -#include "autofill/WebAutoFill.h" - -#include <wtf/OwnPtr.h> - -using namespace WebCore; - -namespace android { - -class EditorClientAndroid : public EditorClient { -public: - EditorClientAndroid() { - m_shouldChangeSelectedRange = true; - m_uiGeneratedSelectionChange = false; - } - virtual void pageDestroyed(); - - virtual bool shouldDeleteRange(Range*); - virtual bool shouldShowDeleteInterface(HTMLElement*); - virtual bool smartInsertDeleteEnabled(); - virtual bool isSelectTrailingWhitespaceEnabled(); - virtual bool isContinuousSpellCheckingEnabled(); - virtual void toggleContinuousSpellChecking(); - virtual bool isGrammarCheckingEnabled(); - virtual void toggleGrammarChecking(); - virtual int spellCheckerDocumentTag(); - - virtual bool isEditable(); - - virtual bool shouldBeginEditing(Range*); - virtual bool shouldEndEditing(Range*); - virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction); - virtual bool shouldInsertText(const String&, Range*, EditorInsertAction); - virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting); - - virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*); -// virtual bool shouldChangeTypingStyle(CSSStyleDeclaration* fromStyle, CSSStyleDeclaration* toStyle); -// virtual bool doCommandBySelector(SEL selector); - virtual bool shouldMoveRangeAfterDelete(Range*, Range*); - - virtual void didBeginEditing(); - virtual void respondToChangedContents(); - virtual void respondToChangedSelection(); - virtual void didEndEditing(); - virtual void didWriteSelectionToPasteboard(); - virtual void didSetSelectionTypesForPasteboard(); -// virtual void didChangeTypingStyle:(NSNotification *)notification; -// virtual void didChangeSelection:(NSNotification *)notification; -// virtual NSUndoManager* undoManager:(WebView *)webView; - - virtual void registerCommandForUndo(PassRefPtr<EditCommand>); - virtual void registerCommandForRedo(PassRefPtr<EditCommand>); - virtual void clearUndoRedoOperations(); - - virtual bool canUndo() const; - virtual bool canRedo() const; - - virtual void undo(); - virtual void redo(); - - virtual void handleKeyboardEvent(KeyboardEvent*); - virtual void handleInputMethodKeydown(KeyboardEvent*); - - virtual void textFieldDidBeginEditing(Element*); - virtual void textFieldDidEndEditing(Element*); - virtual void textDidChangeInTextField(Element*); - virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*); - virtual void textWillBeDeletedInTextField(Element*); - virtual void textDidChangeInTextArea(Element*); - - virtual void ignoreWordInSpellDocument(const String&); - virtual void learnWord(const String&); - virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength); - virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWorld); - virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); - virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail); - virtual void updateSpellingUIWithMisspelledWord(const String&); - virtual void showSpellingUI(bool show); - virtual bool spellingUIIsShowing(); - virtual void getGuessesForWord(const String&, const String& context, WTF::Vector<String>& guesses); - virtual void willSetInputMethodState(); - virtual void setInputMethodState(bool); - virtual void requestCheckingOfString(SpellChecker*, int, const String&); - - // Android specific: - void setPage(Page* page) { m_page = page; } - void setShouldChangeSelectedRange(bool shouldChangeSelectedRange) { m_shouldChangeSelectedRange = shouldChangeSelectedRange; } - void setUiGeneratedSelectionChange(bool uiGenerated) { m_uiGeneratedSelectionChange = uiGenerated; } -#if ENABLE(WEB_AUTOFILL) - WebAutoFill* getAutoFill(); -#endif -private: - Page* m_page; - bool m_shouldChangeSelectedRange; - bool m_uiGeneratedSelectionChange; -#if ENABLE(WEB_AUTOFILL) - OwnPtr<WebAutoFill> m_autoFill; -#endif -}; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/FileSystemClient.h b/WebKit/android/WebCoreSupport/FileSystemClient.h deleted file mode 100644 index 5bde18a..0000000 --- a/WebKit/android/WebCoreSupport/FileSystemClient.h +++ /dev/null @@ -1,41 +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 FILESYSTEM_CLIENT_H -#define FILESYSTEM_CLIENT_H - -#include "PlatformString.h" - -using namespace WebCore; - -namespace android { - -class FileSystemClient { -public: - virtual ~FileSystemClient() { } - virtual String resolveFilePathForContentUri(const String&) = 0; -}; -} -#endif diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp deleted file mode 100644 index 946a4a7..0000000 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ /dev/null @@ -1,1351 +0,0 @@ -/* - * Copyright 2007, 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 "WebCore" - -#include "config.h" -#include "FrameLoaderClientAndroid.h" - -#include "BackForwardList.h" -#include "CachedFrame.h" -#include "CachedFramePlatformDataAndroid.h" -#include "Chrome.h" -#include "ChromeClientAndroid.h" -#include "DOMImplementation.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "EditorClientAndroid.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameNetworkingContextAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HTMLFrameOwnerElement.h" -#include "HTMLPlugInElement.h" -#include "HistoryItem.h" -#include "IconDatabase.h" -#include "MIMETypeRegistry.h" -#include "NotImplemented.h" -#include "PackageNotifier.h" -#include "Page.h" -#include "PlatformBridge.h" -#include "PlatformGraphicsContext.h" -#include "PlatformString.h" -#include "PluginDatabase.h" -#include "PluginView.h" -#include "PluginViewBase.h" -#include "ProgressTracker.h" -#include "RenderPart.h" -#include "RenderView.h" -#include "RenderWidget.h" -#include "ResourceError.h" -#include "ResourceHandle.h" -#include "ResourceHandleInternal.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SkCanvas.h" -#include "SkRect.h" -#include "TextEncoding.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreResourceLoader.h" -#include "WebHistory.h" -#include "WebIconDatabase.h" -#include "WebFrameView.h" -#include "WebViewClientError.h" -#include "WebViewCore.h" -#include "autofill/WebAutoFill.h" -#include "android_graphics.h" - -#include <utils/AssetManager.h> -#include <wtf/text/CString.h> - -extern android::AssetManager* globalAssetManager(); - -namespace android { - -static const int EXTRA_LAYOUT_DELAY = 1000; - -FrameLoaderClientAndroid::FrameLoaderClientAndroid(WebFrame* webframe) - : m_frame(NULL) - , m_webFrame(webframe) - , m_manualLoader(NULL) - , m_hasSentResponseToPlugin(false) - , m_onDemandPluginsEnabled(false) { - Retain(m_webFrame); -} - -FrameLoaderClientAndroid* FrameLoaderClientAndroid::get(const WebCore::Frame* frame) -{ - return static_cast<FrameLoaderClientAndroid*> (frame->loader()->client()); -} - -void FrameLoaderClientAndroid::frameLoaderDestroyed() { - registerForIconNotification(false); - m_frame = 0; - Release(m_webFrame); - delete this; -} - -bool FrameLoaderClientAndroid::hasWebView() const { - // FIXME, - // there is one web view per page, or top frame. - // as android's view is created from Java side, it is always there. - return true; -} - -void FrameLoaderClientAndroid::makeRepresentation(DocumentLoader*) { - m_onDemandPluginsEnabled = false; - // don't use representation - verifiedOk(); -} - -void FrameLoaderClientAndroid::forceLayout() { - ASSERT(m_frame); - m_frame->view()->forceLayout(); - // FIXME, should we adjust view size here? - m_frame->view()->adjustViewSize(); -} - -void FrameLoaderClientAndroid::forceLayoutForNonHTML() { - notImplemented(); -} - -void FrameLoaderClientAndroid::setCopiesOnScroll() { - // this is a hint about whether we need to force redraws, or can - // just copy the scrolled content. Since we always force a redraw - // anyways, we can ignore this call. - verifiedOk(); -} - -void FrameLoaderClientAndroid::detachedFromParent2() { - // FIXME, ready to detach frame from view -} - -void FrameLoaderClientAndroid::detachedFromParent3() { - // FIXME, ready to release view - notImplemented(); -} - -// This function is responsible for associating the "id" with a given -// subresource load. The following functions that accept an "id" are -// called for each subresource, so they should not be dispatched to the m_frame. -void FrameLoaderClientAndroid::assignIdentifierToInitialRequest(unsigned long id, - DocumentLoader*, const ResourceRequest&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillSendRequest(DocumentLoader*, unsigned long id, - ResourceRequest&, const ResourceResponse&) { - lowPriority_notImplemented(); -} - -bool FrameLoaderClientAndroid::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier) -{ - notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, - unsigned long id, const AuthenticationChallenge&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, - unsigned long id, const AuthenticationChallenge&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveResponse(DocumentLoader*, - unsigned long id, const ResourceResponse&) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveContentLength(DocumentLoader*, - unsigned long id, int lengthReceived) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFinishLoading(DocumentLoader*, - unsigned long id) { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFailLoading(DocumentLoader* docLoader, - unsigned long id, const ResourceError&) { - lowPriority_notImplemented(); -} - -bool FrameLoaderClientAndroid::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, - const ResourceRequest&, const ResourceResponse&, int length) { - notImplemented(); - return false; -} - -void FrameLoaderClientAndroid::dispatchDidHandleOnloadEvents() { -} - -void FrameLoaderClientAndroid::dispatchDidReceiveServerRedirectForProvisionalLoad() { - ASSERT(m_frame); - // Tell the load it was a redirect. - m_webFrame->loadStarted(m_frame); -} - -void FrameLoaderClientAndroid::dispatchDidCancelClientRedirect() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillPerformClientRedirect(const KURL&, - double interval, double fireDate) { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidChangeLocationWithinPage() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidPushStateWithinPage() -{ - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReplaceStateWithinPage() -{ - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidPopStateWithinPage() -{ - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchWillClose() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveIcon() { - ASSERT(m_frame); - if (m_frame->tree() && m_frame->tree()->parent()) - return; - WTF::String url(m_frame->loader()->url().string()); - // Try to obtain the icon image. - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL( - url, WebCore::IntSize(16, 16)); - // If the request fails, try the original request url. - if (!icon) { - DocumentLoader* docLoader = m_frame->loader()->activeDocumentLoader(); - KURL originalURL = docLoader->originalRequest().url(); - icon = WebCore::iconDatabase()->iconForPageURL( - originalURL, WebCore::IntSize(16, 16)); - } - // There is a bug in webkit where cancelling an icon load is treated as a - // failure. When this is fixed, we can ASSERT again that we have an icon. - if (icon) { - LOGV("Received icon (%p) for %s", icon, - url.utf8().data()); - m_webFrame->didReceiveIcon(icon); - } else { - LOGV("Icon data for %s unavailable, registering for notification...", - url.utf8().data()); - registerForIconNotification(); - } -} - -void FrameLoaderClientAndroid::dispatchDidReceiveTouchIconURL(const String& url, bool precomposed) { - ASSERT(m_frame); - // Do not report sub frame touch icons - if (m_frame->tree() && m_frame->tree()->parent()) - return; - m_webFrame->didReceiveTouchIconURL(url, precomposed); -} - -void FrameLoaderClientAndroid::dispatchDidStartProvisionalLoad() { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidReceiveTitle(const String& title) { - ASSERT(m_frame); - // Used to check for FrameLoadTypeStandard but we only want to send the title for - // the top frame and not sub-frames. - if (!m_frame->tree() || !m_frame->tree()->parent()) { - m_webFrame->setTitle(title); - } -} - -void FrameLoaderClientAndroid::dispatchDidCommitLoad() { -#if ENABLE(WEB_AUTOFILL) - if (m_frame == m_frame->page()->mainFrame()) { - EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(m_frame->page()->editorClient()); - WebAutoFill* autoFill = editorC->getAutoFill(); - autoFill->reset(); - } -#endif - verifiedOk(); -} - -static void loadDataIntoFrame(Frame* frame, KURL baseUrl, const String& url, - const String& data) { - if (baseUrl.isEmpty()) { - baseUrl = blankURL(); - } - ResourceRequest request(baseUrl); - CString cstr = data.utf8(); - RefPtr<WebCore::SharedBuffer> buf = WebCore::SharedBuffer::create(cstr.data(), cstr.length()); - SubstituteData subData(buf, String("text/html"), String("utf-8"), - KURL(KURL(), url)); - frame->loader()->load(request, subData, false); -} - -void FrameLoaderClientAndroid::dispatchDidFailProvisionalLoad(const ResourceError& error) { - ASSERT(m_frame); - // Ignore ErrorInterrupted since it is due to a policy interruption. This - // is caused by a decision to download the main resource rather than - // display it. - if (error.errorCode() == InternalErrorInterrupted - || error.errorCode() == InternalErrorCancelled) { - // If we decided to download the main resource or if the user cancelled - // it, make sure we report that the load is done. - didFinishLoad(); - return; - } - - AssetManager* am = globalAssetManager(); - - // Check to see if the error code was not generated internally - WebCore::PlatformBridge::rawResId id = WebCore::PlatformBridge::NoDomain; - if ((error.errorCode() == ErrorFile || - error.errorCode() == ErrorFileNotFound) && - (!error.localizedDescription().isEmpty())) { - id = WebCore::PlatformBridge::LoadError; - } - String filename = m_webFrame->getRawResourceFilename(id); - if (filename.isEmpty()) - return; - - // Grab the error page from the asset manager - Asset* a = am->openNonAsset( - filename.utf8().data(), Asset::ACCESS_BUFFER); - if (!a) - return; - - // Take the failing url and encode html entities so javascript urls are not - // executed. - CString failingUrl = error.failingURL().utf8(); - WTF::Vector<char> url; - int len = failingUrl.length(); - const char* data = failingUrl.data(); - for (int i = 0; i < len; i++) { - char c = data[i]; - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') - || (c >= '0' && c <= '9')) - url.append(c); - else { - char buf[16]; - int res = sprintf(buf, "&#%d;", c); - buf[res] = 0; - url.append(buf, res); - } - } - - // Replace all occurances of %s with the failing url. - String s = UTF8Encoding().decode((const char*)a->getBuffer(false), a->getLength()); - s = s.replace("%s", String(url.data(), url.size())); - - // Replace all occurances of %e with the error text - s = s.replace("%e", error.localizedDescription()); - - // Create the request and the substitute data and tell the FrameLoader to - // load with the replacement data. - // use KURL(const char*) as KURL(const String& url) can trigger ASSERT for - // invalidate URL string. - loadDataIntoFrame(m_frame, KURL(ParsedURLString, data), error.failingURL(), s); - - // Delete the asset. - delete a; - - // Report that the load is finished, since it failed. - didFinishLoad(); -} - -void FrameLoaderClientAndroid::dispatchDidFailLoad(const ResourceError&) { - // called when page is completed with error - didFinishLoad(); -} - -void FrameLoaderClientAndroid::dispatchDidFinishDocumentLoad() { - // called when finishedParsing - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDidFinishLoad() { - didFinishLoad(); -} - -void FrameLoaderClientAndroid::dispatchDidFirstLayout() { - ASSERT(m_frame); - // set EXTRA_LAYOUT_DELAY if the loader is not completed yet - if (!m_frame->loader()->isComplete()) - m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY); - // we need to do this here instead of dispatchDidFirstVisuallyNonEmptyLayout - // so that about:blank will update the screen. - if (!m_frame->tree()->parent()) { - // Only need to notify Java side for the top frame - WebViewCore::getWebViewCore(m_frame->view())->didFirstLayout(); - } -} - -void FrameLoaderClientAndroid::dispatchDidFirstVisuallyNonEmptyLayout() -{ - notImplemented(); -} - -Frame* FrameLoaderClientAndroid::dispatchCreatePage(const NavigationAction&) { - ASSERT(m_frame); -#ifdef ANDROID_MULTIPLE_WINDOWS - if (m_frame->settings() && m_frame->settings()->supportMultipleWindows()) - // Always a user gesture since window.open maps to - // ChromeClientAndroid::createWindow - return m_webFrame->createWindow(false, true); - else -#endif - // If the client doesn't support multiple windows, just replace the - // current frame's contents. - return m_frame; -} - -void FrameLoaderClientAndroid::dispatchShow() { - ASSERT(m_frame); - m_frame->view()->invalidate(); -} - - -static bool TreatAsAttachment(const String& content_disposition) { - // Some broken sites just send - // Content-Disposition: ; filename="file" - // screen those out here. - if (content_disposition.startsWith(";")) - return false; - - if (content_disposition.startsWith("inline", false)) - return false; - - // Some broken sites just send - // Content-Disposition: filename="file" - // without a disposition token... screen those out. - if (content_disposition.startsWith("filename", false)) - return false; - - // Also in use is Content-Disposition: name="file" - if (content_disposition.startsWith("name", false)) - return false; - - // We have a content-disposition of "attachment" or unknown. - // RFC 2183, section 2.8 says that an unknown disposition - // value should be treated as "attachment" - return true; -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForMIMEType(FramePolicyFunction func, - const String& MIMEType, const ResourceRequest& request) { - ASSERT(m_frame); - ASSERT(func); - if (!func) - return; - - PolicyChecker* policy = m_frame->loader()->policyChecker(); - - if (request.isNull()) { - (policy->*func)(PolicyIgnore); - return; - } - // Default to Use (display internally). - PolicyAction action = PolicyUse; - // Check if we should Download instead. - const ResourceResponse& response = m_frame->loader()->activeDocumentLoader()->response(); - const String& content_disposition = response.httpHeaderField("Content-Disposition"); - if (!content_disposition.isEmpty() && - TreatAsAttachment(content_disposition)) { - // Server wants to override our normal policy. - // Check to see if we are a sub frame (main frame has no owner element) - if (m_frame->ownerElement() != 0) - action = PolicyIgnore; - else - action = PolicyDownload; - (policy->*func)(action); - return; - } - - // Ask if it can be handled internally. - if (!canShowMIMEType(MIMEType)) { - // Check to see if we are a sub frame (main frame has no owner element) - if (m_frame->ownerElement() != 0) - action = PolicyIgnore; - else - action = PolicyDownload; - (policy->*func)(action); - return; - } - // A status code of 204 indicates no content change. Ignore the result. - WebCore::DocumentLoader* docLoader = m_frame->loader()->activeDocumentLoader(); - if (docLoader->response().httpStatusCode() == 204) - action = PolicyIgnore; - (policy->*func)(action); -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction func, - const NavigationAction& action, const ResourceRequest& request, - PassRefPtr<FormState> formState, const String& frameName) { - ASSERT(m_frame); - ASSERT(func); - if (!func) - return; - - if (request.isNull()) { - (m_frame->loader()->policyChecker()->*func)(PolicyIgnore); - return; - } - - if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) - m_frame->loader()->resetMultipleFormSubmissionProtection(); - - // If we get to this point it means that a link has a target that was not - // found by the frame tree. Instead of creating a new frame, return the - // current frame in dispatchCreatePage. - if (canHandleRequest(request)) - (m_frame->loader()->policyChecker()->*func)(PolicyUse); - else - (m_frame->loader()->policyChecker()->*func)(PolicyIgnore); -} - -void FrameLoaderClientAndroid::cancelPolicyCheck() { - lowPriority_notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchUnableToImplementPolicy(const ResourceError&) { - notImplemented(); -} - -void FrameLoaderClientAndroid::dispatchDecidePolicyForNavigationAction(FramePolicyFunction func, - const NavigationAction& action, const ResourceRequest& request, - PassRefPtr<FormState> formState) { - ASSERT(m_frame); - ASSERT(func); - if (!func) - return; - if (request.isNull()) { - (m_frame->loader()->policyChecker()->*func)(PolicyIgnore); - return; - } - - // Reset multiple form submission protection. If this is a resubmission, we check with the - // user and reset the protection if they choose to resubmit the form (see WebCoreFrameBridge.cpp) - if (action.type() == NavigationTypeFormSubmitted) - m_frame->loader()->resetMultipleFormSubmissionProtection(); - - if (action.type() == NavigationTypeFormResubmitted) { - m_webFrame->decidePolicyForFormResubmission(func); - return; - } else - (m_frame->loader()->policyChecker()->*func)(PolicyUse); -} - -void FrameLoaderClientAndroid::dispatchWillSubmitForm(FramePolicyFunction func, PassRefPtr<FormState>) { - ASSERT(m_frame); - ASSERT(func); - (m_frame->loader()->policyChecker()->*func)(PolicyUse); -} - -void FrameLoaderClientAndroid::dispatchWillSendSubmitEvent(HTMLFormElement* form) -{ - if (m_webFrame->shouldSaveFormData()) - m_webFrame->saveFormData(form); -} - -void FrameLoaderClientAndroid::dispatchDidLoadMainResource(DocumentLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::revertToProvisionalState(DocumentLoader*) { - notImplemented(); -} - -void FrameLoaderClientAndroid::setMainDocumentError(DocumentLoader* docLoader, const ResourceError& error) { - ASSERT(m_frame); - if (m_manualLoader) { - m_manualLoader->didFail(error); - m_manualLoader = NULL; - m_hasSentResponseToPlugin = false; - } else { - if (!error.isNull() && error.errorCode() >= InternalErrorLast && error.errorCode() != ERROR_OK) - m_webFrame->reportError(error.errorCode(), - error.localizedDescription(), error.failingURL()); - } -} - -// This function is called right before the progress is updated. -void FrameLoaderClientAndroid::willChangeEstimatedProgress() { - verifiedOk(); -} - -// This function is called after the progress has been updated. The bad part -// about this is that when a page is completed, this function is called after -// the progress has been reset to 0. -void FrameLoaderClientAndroid::didChangeEstimatedProgress() { - verifiedOk(); -} - -// This will give us the initial estimate when the page first starts to load. -void FrameLoaderClientAndroid::postProgressStartedNotification() { - ASSERT(m_frame); - if (m_frame->page()) - m_webFrame->setProgress(m_frame->page()->progress()->estimatedProgress()); -} - -// This will give us any updated progress including the final progress. -void FrameLoaderClientAndroid::postProgressEstimateChangedNotification() { - ASSERT(m_frame); - if (m_frame->page()) - m_webFrame->setProgress(m_frame->page()->progress()->estimatedProgress()); -} - -// This is just a notification that the progress has finished. Don't call -// setProgress(1) because postProgressEstimateChangedNotification will do so. -void FrameLoaderClientAndroid::postProgressFinishedNotification() { - WebViewCore* core = WebViewCore::getWebViewCore(m_frame->view()); - if (!m_frame->tree()->parent()) { - // only need to notify Java for the top frame - core->notifyProgressFinished(); - } - // notify plugins that the frame has loaded - core->notifyPluginsOnFrameLoad(m_frame); -} - -void FrameLoaderClientAndroid::setMainFrameDocumentReady(bool) { - // this is only interesting once we provide an external API for the DOM - notImplemented(); -} - -void FrameLoaderClientAndroid::startDownload(const ResourceRequest&) { - notImplemented(); -} - -void FrameLoaderClientAndroid::willChangeTitle(DocumentLoader*) { - verifiedOk(); -} - -void FrameLoaderClientAndroid::didChangeTitle(DocumentLoader* loader) { - verifiedOk(); -} - -void FrameLoaderClientAndroid::finishedLoading(DocumentLoader* docLoader) { - // Telling the frame we received some data and passing 0 as the data is our - // way to get work done that is normally done when the first bit of data is - // received, even for the case of a document with no data (like about:blank) - if (!m_manualLoader) { - committedLoad(docLoader, 0, 0); - return; - } - - m_manualLoader->didFinishLoading(); - m_manualLoader = NULL; - m_hasSentResponseToPlugin = false; -} - -void FrameLoaderClientAndroid::updateGlobalHistory() { - ASSERT(m_frame); - - DocumentLoader* docLoader = m_frame->loader()->documentLoader(); - ASSERT(docLoader); - - // Code copied from FrameLoader.cpp:createHistoryItem - // Only add this URL to the database if it is a valid page - if (docLoader->unreachableURL().isEmpty() - && docLoader->response().httpStatusCode() < 400) { - m_webFrame->updateVisitedHistory(docLoader->urlForHistory(), false); - if (!docLoader->serverRedirectSourceForHistory().isNull()) - m_webFrame->updateVisitedHistory(KURL(ParsedURLString, docLoader->serverRedirectDestinationForHistory()), false); - } -} - -void FrameLoaderClientAndroid::updateGlobalHistoryRedirectLinks() { - // Note, do we need to do anything where there is no HistoryItem? If we call - // updateGlobalHistory(), we will add bunch of "data:xxx" urls for gmail.com - // which is not what we want. Opt to do nothing now. -} - -bool FrameLoaderClientAndroid::shouldGoToHistoryItem(HistoryItem* item) const { - // hmmm, seems like we might do a more thoughtful check - ASSERT(m_frame); - return item != NULL; -} - -void FrameLoaderClientAndroid::didDisplayInsecureContent() -{ - notImplemented(); -} - -void FrameLoaderClientAndroid::didRunInsecureContent(SecurityOrigin*) -{ - notImplemented(); -} - -void FrameLoaderClientAndroid::committedLoad(DocumentLoader* loader, const char* data, int length) { - if (!m_manualLoader) - loader->commitData(data, length); - - // commit data may have created a manual plugin loader - if (m_manualLoader) { - if (!m_hasSentResponseToPlugin) { - m_manualLoader->didReceiveResponse(loader->response()); - // Failure could cause the main document to have an error causing - // the manual loader to be reset. - if (!m_manualLoader) - return; - m_hasSentResponseToPlugin = true; - } - m_manualLoader->didReceiveData(data, length); - } -} - -ResourceError FrameLoaderClientAndroid::cancelledError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorCancelled, request.url(), String()); -} - -ResourceError FrameLoaderClientAndroid::cannotShowURLError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorCannotShowUrl, request.url(), String()); -} - -ResourceError FrameLoaderClientAndroid::interruptForPolicyChangeError(const ResourceRequest& request) { - return ResourceError(String(), InternalErrorInterrupted, request.url(), String()); -} - -ResourceError FrameLoaderClientAndroid::cannotShowMIMETypeError(const ResourceResponse& request) { - return ResourceError(String(), InternalErrorCannotShowMimeType, request.url(), String()); -} - -ResourceError FrameLoaderClientAndroid::fileDoesNotExistError(const ResourceResponse& request) { - return ResourceError(String(), InternalErrorFileDoesNotExist, request.url(), String()); -} - -ResourceError FrameLoaderClientAndroid::pluginWillHandleLoadError(const ResourceResponse& request) { - return ResourceError(String(), InternalErrorPluginWillHandleLoadError, request.url(), String()); -} - -bool FrameLoaderClientAndroid::shouldFallBack(const ResourceError&) { - notImplemented(); - return false; -} - -bool FrameLoaderClientAndroid::canHandleRequest(const ResourceRequest& request) const { - ASSERT(m_frame); - // Don't allow hijacking of intrapage navigation - if (WebCore::equalIgnoringFragmentIdentifier(request.url(), m_frame->loader()->url())) - return true; - - // Don't allow hijacking of iframe urls that are http or https - if (request.url().protocol().startsWith("http", false) && - m_frame->tree() && m_frame->tree()->parent()) - return true; - - return m_webFrame->canHandleRequest(request); -} - -bool FrameLoaderClientAndroid::canShowMIMEType(const String& mimeType) const { - // FIXME: This looks like it has to do with whether or not a type can be - // shown "internally" (i.e. inside the browser) regardless of whether - // or not the browser is doing the rendering, e.g. a full page plugin. - if (MIMETypeRegistry::isSupportedImageResourceMIMEType(mimeType) || - MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || - MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || - (m_frame && m_frame->settings() - && m_frame->settings()->arePluginsEnabled() - && PluginDatabase::installedPlugins()->isMIMETypeRegistered( - mimeType)) || - (DOMImplementation::isTextMIMEType(mimeType) && - !mimeType.startsWith("text/vnd")) || - DOMImplementation::isXMLMIMEType(mimeType)) - return true; - return false; -} - -bool FrameLoaderClientAndroid::canShowMIMETypeAsHTML(const String& mimeType) const { - return false; -} - -bool FrameLoaderClientAndroid::representationExistsForURLScheme(const String&) const { - // don't use representation - verifiedOk(); - return false; -} - -String FrameLoaderClientAndroid::generatedMIMETypeForURLScheme(const String& URLScheme) const { - // FIXME, copy from Apple's port - String mimetype("x-apple-web-kit/"); - mimetype.append(URLScheme.lower()); - return mimetype; -} - -void FrameLoaderClientAndroid::frameLoadCompleted() { - // copied from Apple port, without this back with sub-frame will trigger ASSERT - ASSERT(m_frame); -} - -void FrameLoaderClientAndroid::saveViewStateToItem(HistoryItem* item) { - ASSERT(m_frame); - ASSERT(item); - // store the current scale (only) for the top frame - if (!m_frame->tree()->parent()) { - // We should have added a bridge when the child item was added to its - // parent. - AndroidWebHistoryBridge* bridge = item->bridge(); - ASSERT(bridge); - WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view()); - bridge->setScale(webViewCore->scale()); - bridge->setTextWrapScale(webViewCore->textWrapScale()); - } - - WebCore::notifyHistoryItemChanged(item); -} - -void FrameLoaderClientAndroid::restoreViewState() { - WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view()); - HistoryItem* item = m_frame->loader()->history()->currentItem(); - AndroidWebHistoryBridge* bridge = item->bridge(); - // restore the scale (only) for the top frame - if (!m_frame->tree()->parent()) { - webViewCore->restoreScale(bridge->scale(), bridge->textWrapScale()); - } -} - -void FrameLoaderClientAndroid::dispatchDidAddBackForwardItem(HistoryItem* item) const { - ASSERT(m_frame); - m_webFrame->addHistoryItem(item); -} - -void FrameLoaderClientAndroid::dispatchDidRemoveBackForwardItem(HistoryItem* item) const { - ASSERT(m_frame); - m_webFrame->removeHistoryItem(0); -} - -void FrameLoaderClientAndroid::dispatchDidChangeBackForwardIndex() const { - ASSERT(m_frame); - BackForwardList* list = m_frame->page()->backForwardList(); - ASSERT(list); - m_webFrame->updateHistoryIndex(list->backListCount()); -} - -void FrameLoaderClientAndroid::provisionalLoadStarted() { - ASSERT(m_frame); - m_webFrame->loadStarted(m_frame); -} - -void FrameLoaderClientAndroid::didFinishLoad() { - ASSERT(m_frame); - m_frame->document()->setExtraLayoutDelay(0); - m_webFrame->didFinishLoad(m_frame); -} - -void FrameLoaderClientAndroid::prepareForDataSourceReplacement() { - verifiedOk(); -} - -PassRefPtr<DocumentLoader> FrameLoaderClientAndroid::createDocumentLoader( - const ResourceRequest& request, const SubstituteData& data) { - RefPtr<DocumentLoader> loader = DocumentLoader::create(request, data); - return loader.release(); -} - -void FrameLoaderClientAndroid::setTitle(const String& title, const KURL& url) { - // Not needed. dispatchDidReceiveTitle is called immediately after this. - // url is used to update the Apple port history items. - verifiedOk(); -} - -String FrameLoaderClientAndroid::userAgent(const KURL& u) { - return m_webFrame->userAgentForURL(&u); -} - -void FrameLoaderClientAndroid::savePlatformDataToCachedFrame(WebCore::CachedFrame* cachedFrame) { - CachedFramePlatformDataAndroid* platformData = new CachedFramePlatformDataAndroid(m_frame->settings()); - cachedFrame->setCachedFramePlatformData(platformData); -} - -void FrameLoaderClientAndroid::transitionToCommittedFromCachedFrame(WebCore::CachedFrame* cachedFrame) { - CachedFramePlatformDataAndroid* platformData = reinterpret_cast<CachedFramePlatformDataAndroid*>(cachedFrame->cachedFramePlatformData()); -#ifdef ANDROID_META_SUPPORT - platformData->restoreMetadata(m_frame->settings()); -#endif - m_webFrame->transitionToCommitted(m_frame); -} - -void FrameLoaderClientAndroid::transitionToCommittedForNewPage() { - ASSERT(m_frame); - -#ifdef ANDROID_META_SUPPORT - // reset metadata settings for the main frame as they are not preserved cross page - if (m_frame == m_frame->page()->mainFrame() && m_frame->settings()) - m_frame->settings()->resetMetadataSettings(); -#endif - - // Save the old WebViewCore before creating a new FrameView. There is one - // WebViewCore per page. Each frame, including the main frame and sub frame, - // has a 1:1 FrameView and WebFrameView. - WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view()); - Retain(webViewCore); - - // Save the old WebFrameView's bounds and apply them to the new WebFrameView - WebFrameView* oldWebFrameView = static_cast<WebFrameView*> (m_frame->view()->platformWidget()); - IntRect bounds = oldWebFrameView->getBounds(); - IntRect visBounds = oldWebFrameView->getVisibleBounds(); - IntRect windowBounds = oldWebFrameView->getWindowBounds(); - WebCore::FrameView* oldFrameView = oldWebFrameView->view(); - const float oldZoomFactor = oldFrameView->frame()->textZoomFactor(); - m_frame->createView(bounds.size(), oldFrameView->baseBackgroundColor(), oldFrameView->isTransparent(), - oldFrameView->fixedLayoutSize(), oldFrameView->useFixedLayout()); - if (oldZoomFactor != 1.0f && oldZoomFactor != m_frame->textZoomFactor()) { - m_frame->setTextZoomFactor(oldZoomFactor); - } - - // Create a new WebFrameView for the new FrameView - WebFrameView* newFrameView = new WebFrameView(m_frame->view(), webViewCore); - newFrameView->setLocation(bounds.x(), bounds.y()); - newFrameView->setSize(bounds.width(), bounds.height()); - newFrameView->setVisibleSize(visBounds.width(), visBounds.height()); - newFrameView->setWindowBounds(windowBounds.x(), windowBounds.y(), windowBounds.width(), windowBounds.height()); - // newFrameView attaches itself to FrameView which Retains the reference, so - // call Release for newFrameView - Release(newFrameView); - // WebFrameView Retains webViewCore, so call Release for webViewCore - Release(webViewCore); - - m_webFrame->transitionToCommitted(m_frame); -} - -void FrameLoaderClientAndroid::dispatchDidBecomeFrameset(bool) -{ -} - -bool FrameLoaderClientAndroid::canCachePage() const { - return true; -} - -void FrameLoaderClientAndroid::download(ResourceHandle* handle, const ResourceRequest&, - const ResourceRequest&, const ResourceResponse&) { - // Get the C++ side of the load listener and tell it to handle the download - handle->getInternal()->m_loader->downloadFile(); -} - -WTF::PassRefPtr<WebCore::Frame> FrameLoaderClientAndroid::createFrame(const KURL& url, const String& name, - HTMLFrameOwnerElement* ownerElement, const String& referrer, - bool allowsScrolling, int marginWidth, int marginHeight) -{ - Frame* parent = ownerElement->document()->frame(); - FrameLoaderClientAndroid* loaderC = new FrameLoaderClientAndroid(m_webFrame); - RefPtr<Frame> pFrame = Frame::create(parent->page(), ownerElement, loaderC); - Frame* newFrame = pFrame.get(); - loaderC->setFrame(newFrame); - // Append the subframe to the parent and set the name of the subframe. The name must be set after - // appending the child so that the name becomes unique. - parent->tree()->appendChild(newFrame); - newFrame->tree()->setName(name); - // Create a new FrameView and WebFrameView for the child frame to draw into. - RefPtr<FrameView> frameView = FrameView::create(newFrame); - WebFrameView* webFrameView = new WebFrameView(frameView.get(), - WebViewCore::getWebViewCore(parent->view())); - // frameView Retains webFrameView, so call Release for webFrameView - Release(webFrameView); - // Attach the frameView to the newFrame. - newFrame->setView(frameView); - newFrame->init(); - newFrame->selection()->setFocused(true); - LOGV("::WebCore:: createSubFrame returning %p", newFrame); - - // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. - if (!pFrame->page()) - return 0; - - parent->loader()->loadURLIntoChildFrame(url, referrer, pFrame.get()); - - // onLoad may cuase the frame to be removed from the document. Allow the RefPtr to delete the child frame. - if (!pFrame->tree()->parent()) - return NULL; - - return pFrame.release(); -} - -// YouTube flash url path starts with /v/ -static const char slash_v_slash[] = { '/', 'v', '/' }; -static const char slash_e_slash[] = { '/', 'e', '/' }; - -static bool isValidYouTubeVideo(const String& path) -{ - if (!charactersAreAllASCII(path.characters(), path.length())) - return false; - unsigned int len = path.length(); - if (len <= sizeof(slash_v_slash)) // check for more than just /v/ - return false; - CString str = path.lower().utf8(); - const char* data = str.data(); - // Youtube flash url can start with /v/ or /e/ - if (memcmp(data, slash_v_slash, sizeof(slash_v_slash)) != 0) - if (memcmp(data, slash_e_slash, sizeof(slash_e_slash)) != 0) - return false; - // Start after /v/ - for (unsigned int i = sizeof(slash_v_slash); i < len; i++) { - char c = data[i]; - // Check for alpha-numeric characters only. - if (WTF::isASCIIAlphanumeric(c) || c == '_' || c == '-') - continue; - // The url can have more parameters such as &hl=en after the video id. - // Once we start seeing extra parameters we can return true. - return c == '&' && i > sizeof(slash_v_slash); - } - return true; -} - -static bool isYouTubeUrl(const KURL& url, const String& mimeType) -{ - String host = url.host(); - bool youtube = host.endsWith("youtube.com") - || host.endsWith("youtube-nocookie.com"); - return youtube && isValidYouTubeVideo(url.path()) - && equalIgnoringCase(mimeType, "application/x-shockwave-flash"); -} - -static bool isYouTubeInstalled() { - return WebCore::packageNotifier().isPackageInstalled("com.google.android.youtube"); -} - -// Use PluginViewBase rather than an Android specific sub class as we do not require any -// Android specific functionality; this just renders a placeholder which will later -// activate the real plugin. -class PluginToggleWidget : public PluginViewBase { -public: - PluginToggleWidget(Frame* parent, const IntSize& size, - HTMLPlugInElement* elem, const KURL& url, - const WTF::Vector<String>& paramNames, - const WTF::Vector<String>& paramValues, const String& mimeType, - bool loadManually) - : PluginViewBase(0) - , m_parent(parent) - , m_size(size) - , m_element(elem) - , m_url(url) - , m_paramNames(paramNames) - , m_paramValues(paramValues) - , m_mimeType(mimeType) - , m_loadManually(loadManually) - { - resize(size); - } - - virtual void paint(GraphicsContext* ctx, const IntRect& rect) - { - // Most of this code is copied from PluginView::paintMissingPluginIcon - // with slight modification. - - static RefPtr<Image> image; - if (!image) { - image = Image::loadPlatformResource("togglePlugin"); - } - - IntRect imageRect(x(), y(), image->width(), image->height()); - - int xOffset = (width() - imageRect.width()) >> 1; - int yOffset = (height() - imageRect.height()) >> 1; - - imageRect.move(xOffset, yOffset); - - if (!rect.intersects(imageRect)) - return; - - // FIXME: We need to clip similarly to paintMissingPluginIcon but it is - // way screwed up right now. It has something to do with how we tell - // webkit the scroll position and it causes the placeholder to get - // clipped very badly. http://b/issue?id=2533303 - - ctx->save(); - ctx->clip(frameRect()); - - ctx->setFillColor(Color::white, ColorSpaceDeviceRGB); - ctx->fillRect(frameRect()); - if (frameRect().contains(imageRect)) { - // Leave a 2 pixel padding. - const int pixelWidth = 2; - IntRect innerRect = frameRect(); - innerRect.inflate(-pixelWidth); - // Draw a 2 pixel light gray border. - ctx->setStrokeColor(Color::lightGray, ColorSpaceDeviceRGB); - ctx->strokeRect(innerRect, pixelWidth); - } - - // Draw the image in the center - ctx->drawImage(image.get(), ColorSpaceDeviceRGB, imageRect.location()); - ctx->restore(); - } - - virtual void handleEvent(Event* event) - { - if (event->type() != eventNames().clickEvent) - return; - - Frame* frame = m_parent->page()->mainFrame(); - while (frame) { - RenderView* view = frame->contentRenderer(); - const HashSet<RenderWidget*> widgets = view->widgets(); - HashSet<RenderWidget*>::const_iterator it = widgets.begin(); - HashSet<RenderWidget*>::const_iterator end = widgets.end(); - for (; it != end; ++it) { - Widget* widget = (*it)->widget(); - // PluginWidget is used only with PluginToggleWidget - if (widget && widget->isPluginViewBase()) { - PluginToggleWidget* ptw = - static_cast<PluginToggleWidget*>(widget); - ptw->swapPlugin(*it); - } - } - frame = frame->tree()->traverseNext(); - } - } - - void swapPlugin(RenderWidget* renderer) { - typedef FrameLoaderClientAndroid FLCA; - FLCA* client = static_cast<FLCA*>(m_parent->loader()->client()); - client->enableOnDemandPlugins(); - WTF::PassRefPtr<PluginView> prpWidget = - PluginView::create(m_parent.get(), - m_size, - m_element, - m_url, - m_paramNames, - m_paramValues, - m_mimeType, - m_loadManually); - RefPtr<Widget> myProtector(this); - prpWidget->focusPluginElement(); - renderer->setWidget(prpWidget); - } - -private: - void invalidateRect(const IntRect& rect) { } - - RefPtr<Frame> m_parent; - IntSize m_size; - HTMLPlugInElement* m_element; - KURL m_url; - WTF::Vector<String> m_paramNames; - WTF::Vector<String> m_paramValues; - String m_mimeType; - bool m_loadManually; -}; - -WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createPlugin( - const IntSize& size, - HTMLPlugInElement* element, - const KURL& url, - const WTF::Vector<String>& names, - const WTF::Vector<String>& values, - const String& mimeType, - bool loadManually) { - WTF::PassRefPtr<PluginView> prpWidget = 0; -#ifdef ANDROID_PLUGINS - // This is copied from PluginView.cpp. We need to determine if a plugin - // will be found before doing some of the work in PluginView. - String mimeTypeCopy = mimeType; - PluginPackage* plugin = - PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy); - if (!plugin && PluginDatabase::installedPlugins()->refresh()) { - mimeTypeCopy = mimeType; - plugin = PluginDatabase::installedPlugins()->findPlugin(url, - mimeTypeCopy); - } - Settings* settings = m_frame->settings(); - // Do the placeholder if plugins are on-demand and there is a plugin for the - // given mime type. - if (settings && settings->arePluginsOnDemand() && plugin && - !m_onDemandPluginsEnabled) { - return adoptRef(new PluginToggleWidget(m_frame, size, element, url, - names, values, mimeType, loadManually)); - } - prpWidget = PluginView::create(m_frame, - size, - element, - url, - names, - values, - mimeType, - loadManually); - // Return the plugin if it was loaded successfully. Otherwise, fallback to - // the youtube placeholder if possible. No need to check prpWidget as - // PluginView::create will create a PluginView for missing plugins. - // Note: this check really only checks if the plugin was found and not if - // the plugin was loaded. - if (prpWidget->status() == PluginStatusLoadedSuccessfully) - return prpWidget; -#endif - // Create an iframe for youtube urls. - if (isYouTubeUrl(url, mimeType) && isYouTubeInstalled()) { - WTF::RefPtr<Frame> frame = createFrame(blankURL(), String(), element, - String(), false, 0, 0); - if (frame) { - // grab everything after /v/ - String videoId = url.path().substring(sizeof(slash_v_slash)); - // Extract just the video id - unsigned videoIdEnd = 0; - for (; videoIdEnd < videoId.length(); videoIdEnd++) { - if (videoId[videoIdEnd] == '&') { - videoId = videoId.left(videoIdEnd); - break; - } - } - AssetManager* am = globalAssetManager(); - Asset* a = am->open("webkit/youtube.html", - Asset::ACCESS_BUFFER); - if (!a) - return NULL; - String s = String((const char*)a->getBuffer(false), a->getLength()); - s = s.replace("VIDEO_ID", videoId); - delete a; - loadDataIntoFrame(frame.get(), - KURL(ParsedURLString, "file:///android_asset/webkit/"), String(), s); - // Transfer ownership to a local refptr. - WTF::RefPtr<Widget> widget(frame->view()); - return widget.release(); - } - } - return prpWidget; -} - -void FrameLoaderClientAndroid::redirectDataToPlugin(Widget* pluginWidget) { - // Do not redirect data if the Widget is our plugin placeholder. - if (pluginWidget->isPluginView()) { - m_manualLoader = static_cast<PluginView*>(pluginWidget); - } -} - -WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, - const KURL& baseURL, const WTF::Vector<String>& paramNames, - const WTF::Vector<String>& paramValues) { - // don't support widget yet - notImplemented(); - return 0; -} - -void FrameLoaderClientAndroid::didTransferChildFrameToNewDocument(WebCore::Page*) -{ - ASSERT(m_frame); - // m_webFrame points to the WebFrame for the page that our frame previously - // belonged to. If the frame now belongs to a new page, we need to update - // m_webFrame to point to the WebFrame for the new page. - Page* newPage = m_frame->page(); - if (newPage != m_webFrame->page()) { - ChromeClientAndroid* chromeClient = static_cast<ChromeClientAndroid*>(newPage->chrome()->client()); - Release(m_webFrame); - m_webFrame = chromeClient->webFrame(); - Retain(m_webFrame); - } -} - -void FrameLoaderClientAndroid::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) -{ - notImplemented(); -} - -// This function is used by the <OBJECT> element to determine the type of -// the contents and work out if it can render it. -ObjectContentType FrameLoaderClientAndroid::objectContentType(const KURL& url, - const String& mimeType) { - return FrameLoader::defaultObjectContentType(url, mimeType); -} - -// This function allows the application to set the correct CSS media -// style. Android could use it to set the media style 'handheld'. Safari -// may use it to set the media style to 'print' when the user wants to print -// a particular web page. -String FrameLoaderClientAndroid::overrideMediaType() const { - lowPriority_notImplemented(); - return String(); -} - -// This function is used to re-attach Javascript<->native code classes. -void FrameLoaderClientAndroid::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) -{ - if (world != mainThreadNormalWorld()) - return; - - ASSERT(m_frame); - LOGV("::WebCore:: windowObjectCleared called on frame %p for %s\n", - m_frame, m_frame->loader()->url().string().ascii().data()); - m_webFrame->windowObjectCleared(m_frame); -} - -void FrameLoaderClientAndroid::documentElementAvailable() { -} - -// functions new to Jun-07 tip of tree merge: -ResourceError FrameLoaderClientAndroid::blockedError(ResourceRequest const& request) { - return ResourceError(String(), InternalErrorFileDoesNotExist, String(), String()); -} - -// functions new to Nov-07 tip of tree merge: -void FrameLoaderClientAndroid::didPerformFirstNavigation() const { - // This seems to be just a notification that the UI can listen to, to - // know if the user has performed first navigation action. - // It is called from - // void FrameLoader::addBackForwardItemClippedAtTarget(bool doClip) - // "Navigation" here means a transition from one page to another that - // ends up in the back/forward list. -} - -void FrameLoaderClientAndroid::registerForIconNotification(bool listen) { - if (listen) - WebIconDatabase::RegisterForIconNotification(this); - else - WebIconDatabase::UnregisterForIconNotification(this); -} - -// This is the WebIconDatabaseClient method for receiving a notification when we -// get the icon for the page. -void FrameLoaderClientAndroid::didAddIconForPageUrl(const String& pageUrl) { - // This call must happen before dispatchDidReceiveIcon since that method - // may register for icon notifications again since the icon data may have - // to be read from disk. - registerForIconNotification(false); - KURL u(ParsedURLString, pageUrl); - if (equalIgnoringFragmentIdentifier(u, m_frame->loader()->url())) { - dispatchDidReceiveIcon(); - } -} - -void FrameLoaderClientAndroid::dispatchDidChangeIcons() { - notImplemented(); -} - -PassRefPtr<FrameNetworkingContext> FrameLoaderClientAndroid::createNetworkingContext() -{ - return FrameNetworkingContextAndroid::create(getFrame()); -} - -} diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h deleted file mode 100644 index 25561a8..0000000 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2007, 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 FrameLoaderClientAndroid_h -#define FrameLoaderClientAndroid_h - -#include "CacheBuilder.h" -#include "FrameLoaderClient.h" -#include "ResourceResponse.h" -#include "WebIconDatabase.h" -#include <wtf/Forward.h> - -namespace WebCore { -class PluginManualLoader; -} - -using namespace WebCore; - -namespace android { - class WebFrame; - - class FrameLoaderClientAndroid : public FrameLoaderClient, - WebIconDatabaseClient { - public: - FrameLoaderClientAndroid(WebFrame* webframe); - - Frame* getFrame() { return m_frame; } - static FrameLoaderClientAndroid* get(const Frame* frame); - - void setFrame(Frame* frame) { m_frame = frame; } - WebFrame* webFrame() const { return m_webFrame; } - - virtual void frameLoaderDestroyed(); - - virtual bool hasWebView() const; // mainly for assertions - - virtual void makeRepresentation(DocumentLoader*); - virtual void forceLayout(); - virtual void forceLayoutForNonHTML(); - - virtual void setCopiesOnScroll(); - - virtual void detachedFromParent2(); - virtual void detachedFromParent3(); - - virtual void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&); - - virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); - virtual bool shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier); - virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&); - virtual void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived); - virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier); - virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&); - virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length); - - virtual void dispatchDidHandleOnloadEvents(); - virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); - virtual void dispatchDidCancelClientRedirect(); - virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate); - virtual void dispatchDidChangeLocationWithinPage(); - virtual void dispatchDidPushStateWithinPage(); - virtual void dispatchDidReplaceStateWithinPage(); - virtual void dispatchDidPopStateWithinPage(); - virtual void dispatchWillClose(); - virtual void dispatchDidReceiveIcon(); - virtual void dispatchDidStartProvisionalLoad(); - virtual void dispatchDidReceiveTitle(const String& title); - virtual void dispatchDidCommitLoad(); - virtual void dispatchDidFailProvisionalLoad(const ResourceError&); - virtual void dispatchDidFailLoad(const ResourceError&); - virtual void dispatchDidFinishDocumentLoad(); - virtual void dispatchDidFinishLoad(); - virtual void dispatchDidFirstLayout(); - virtual void dispatchDidFirstVisuallyNonEmptyLayout(); - - virtual Frame* dispatchCreatePage(const NavigationAction&); - virtual void dispatchShow(); - - virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction, const String& MIMEType, const ResourceRequest&); - virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName); - virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, PassRefPtr<FormState>); - virtual void cancelPolicyCheck(); - - virtual void dispatchUnableToImplementPolicy(const ResourceError&); - - virtual void dispatchWillSubmitForm(FramePolicyFunction, PassRefPtr<FormState>); - - virtual void dispatchDidLoadMainResource(DocumentLoader*); - virtual void revertToProvisionalState(DocumentLoader*); - virtual void setMainDocumentError(DocumentLoader*, const ResourceError&); - - virtual void willChangeEstimatedProgress(); - virtual void didChangeEstimatedProgress(); - virtual void postProgressStartedNotification(); - virtual void postProgressEstimateChangedNotification(); - virtual void postProgressFinishedNotification(); - - virtual void setMainFrameDocumentReady(bool); - - virtual void startDownload(const ResourceRequest&); - - virtual void willChangeTitle(DocumentLoader*); - virtual void didChangeTitle(DocumentLoader*); - - virtual void committedLoad(DocumentLoader*, const char*, int); - virtual void finishedLoading(DocumentLoader*); - - virtual void updateGlobalHistory(); - virtual void updateGlobalHistoryRedirectLinks(); - - virtual bool shouldGoToHistoryItem(HistoryItem*) const; - - virtual void didDisplayInsecureContent(); - virtual void didRunInsecureContent(SecurityOrigin*); - - virtual void dispatchDidAddBackForwardItem(HistoryItem*) const; - virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const; - virtual void dispatchDidChangeBackForwardIndex() const; - - virtual ResourceError cancelledError(const ResourceRequest&); - virtual ResourceError blockedError(const ResourceRequest&); - virtual ResourceError cannotShowURLError(const ResourceRequest&); - virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&); - - virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&); - virtual ResourceError fileDoesNotExistError(const ResourceResponse&); - virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&); - - virtual bool shouldFallBack(const ResourceError&); - - virtual bool canHandleRequest(const ResourceRequest&) const; - virtual bool canShowMIMEType(const String& MIMEType) const; - virtual bool canShowMIMETypeAsHTML(const String& MIMEType) const; - virtual bool representationExistsForURLScheme(const String& URLScheme) const; - virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const; - - virtual void frameLoadCompleted(); - virtual void saveViewStateToItem(HistoryItem*); - virtual void restoreViewState(); - virtual void provisionalLoadStarted(); - virtual void didFinishLoad(); - virtual void prepareForDataSourceReplacement(); - - virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&); - virtual void setTitle(const String& title, const KURL&); - - // This provides the userAgent to WebCore. It is used by WebCore to - // populate navigator.userAgent and to set the HTTP header in - // ResourceRequest objects. We also set a userAgent on WebRequestContext - // for the Chromium HTTP stack, which overrides the value on the - // ResourceRequest. - virtual String userAgent(const KURL&); - - virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*); - virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); - virtual void transitionToCommittedForNewPage(); - - virtual void dispatchDidBecomeFrameset(bool isFrameSet); - - virtual bool canCachePage() const; - virtual void download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&); - - virtual WTF::PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); - virtual void didTransferChildFrameToNewDocument(WebCore::Page*); - virtual void transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader*, const ResourceRequest&, Page* oldPage); - virtual WTF::PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const WTF::Vector<String>&, const WTF::Vector<String>&, const String&, bool loadManually); - virtual void redirectDataToPlugin(Widget* pluginWidget); - - virtual WTF::PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const WTF::Vector<String>& paramNames, const WTF::Vector<String>& paramValues); - - virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); - virtual String overrideMediaType() const; - - virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); - virtual void documentElementAvailable(); - virtual void didPerformFirstNavigation() const; - -#if USE(V8) - // TODO(benm): Implement - virtual void didCreateScriptContextForFrame() { } - virtual void didDestroyScriptContextForFrame() { } - virtual void didCreateIsolatedScriptContext() { } - - virtual bool allowScriptExtension(const String& extensionName, int extensionGroup) { return false; } -#endif - - virtual void registerForIconNotification(bool listen = true); - - virtual void dispatchDidReceiveTouchIconURL(const String& url, bool precomposed); - - virtual PassRefPtr<FrameNetworkingContext> createNetworkingContext(); - - // WebIconDatabaseClient api - virtual void didAddIconForPageUrl(const String& pageUrl); - - // FIXME: this doesn't really go here, but it's better than Frame - CacheBuilder& getCacheBuilder() { return m_cacheBuilder; } - - void enableOnDemandPlugins() { m_onDemandPluginsEnabled = true; } - - void dispatchDidChangeIcons(); - void dispatchWillSendSubmitEvent(HTMLFormElement*); - - virtual void didSaveToPageCache() { } - virtual void didRestoreFromPageCache() { } - private: - CacheBuilder m_cacheBuilder; - Frame* m_frame; - WebFrame* m_webFrame; - PluginManualLoader* m_manualLoader; - bool m_hasSentResponseToPlugin; - bool m_onDemandPluginsEnabled; - - enum ResourceErrors { - InternalErrorCancelled = -99, - InternalErrorCannotShowUrl, - InternalErrorInterrupted, - InternalErrorCannotShowMimeType, - InternalErrorFileDoesNotExist, - InternalErrorPluginWillHandleLoadError, - InternalErrorLast - }; - - /* XXX: These must match android.net.http.EventHandler */ - enum EventHandlerErrors { - Error = -1, - ErrorLookup = -2, - ErrorUnsupportedAuthScheme = -3, - ErrorAuth = -4, - ErrorProxyAuth = -5, - ErrorConnect = -6, - ErrorIO = -7, - ErrorTimeout = -8, - ErrorRedirectLoop = -9, - ErrorUnsupportedScheme = -10, - ErrorFailedSslHandshake = -11, - ErrorBadUrl = -12, - ErrorFile = -13, - ErrorFileNotFound = -14, - ErrorTooManyRequests = -15 - }; - friend class CacheBuilder; - }; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.cpp b/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.cpp deleted file mode 100644 index a5fe494..0000000 --- a/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.cpp +++ /dev/null @@ -1,52 +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. - */ - -#include "config.h" -#include "FrameNetworkingContextAndroid.h" - -#include "DocumentLoader.h" -#include "MainResourceLoader.h" -#include "Settings.h" - -using namespace WebCore; - -namespace android { - -FrameNetworkingContextAndroid::FrameNetworkingContextAndroid(WebCore::Frame* frame) - : WebCore::FrameNetworkingContext(frame) -{ -} - -MainResourceLoader* FrameNetworkingContextAndroid::mainResourceLoader() const -{ - return frame()->loader()->activeDocumentLoader()->mainResourceLoader(); -} - -FrameLoaderClient* FrameNetworkingContextAndroid::frameLoaderClient() const -{ - return frame()->loader()->client(); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.h b/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.h deleted file mode 100644 index d0ff979..0000000 --- a/WebKit/android/WebCoreSupport/FrameNetworkingContextAndroid.h +++ /dev/null @@ -1,54 +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 FrameNetworkingContextAndroid_h -#define FrameNetworkingContextAndroid_h - -#include "FrameNetworkingContext.h" - -namespace WebCore { -class MainResourceLoader; -class FrameLoaderClient; -} - -namespace android { - -class FrameNetworkingContextAndroid : public WebCore::FrameNetworkingContext { -public: - static PassRefPtr<FrameNetworkingContextAndroid> create(WebCore::Frame* frame) - { - return adoptRef(new FrameNetworkingContextAndroid(frame)); - } - -private: - FrameNetworkingContextAndroid(WebCore::Frame*); - - virtual WebCore::MainResourceLoader* mainResourceLoader() const; - virtual WebCore::FrameLoaderClient* frameLoaderClient() const; -}; - -} // namespace android - -#endif // FrameNetworkingContextAndroid_h diff --git a/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp b/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp deleted file mode 100755 index 36a9b61..0000000 --- a/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "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 <text/CString.h> - -using namespace WebCore; - -namespace android { - -GeolocationPermissions::PermissionsMap GeolocationPermissions::s_permanentPermissions; -GeolocationPermissions::GeolocationPermissionsVector GeolocationPermissions::s_instances; -bool GeolocationPermissions::s_alwaysDeny = false; -bool GeolocationPermissions::s_permanentPermissionsLoaded = false; -bool GeolocationPermissions::s_permanentPermissionsModified = false; -String GeolocationPermissions::s_databasePath; - -static const char* databaseName = "GeolocationPermissions.db"; - -GeolocationPermissions::GeolocationPermissions(WebViewCore* webViewCore, Frame* mainFrame) - : m_webViewCore(webViewCore) - , m_mainFrame(mainFrame) - , m_timer(this, &GeolocationPermissions::timerFired) - -{ - ASSERT(m_webViewCore); - maybeLoadPermanentPermissions(); - s_instances.append(this); -} - -GeolocationPermissions::~GeolocationPermissions() -{ - size_t index = s_instances.find(this); - s_instances.remove(index); -} - -void GeolocationPermissions::queryPermissionState(Frame* frame) -{ - ASSERT(s_permanentPermissionsLoaded); - - // We use SecurityOrigin::toString to key the map. Note that testing - // the SecurityOrigin pointer for equality is insufficient. - String originString = frame->document()->securityOrigin()->toString(); - - // If we've been told to always deny requests, do so. - if (s_alwaysDeny) { - makeAsynchronousCallbackToGeolocation(originString, false); - return; - } - - // See if we have a record for this origin in the permanent permissions. - // These take precedence over temporary permissions so that changes made - // from the browser settings work as intended. - PermissionsMap::const_iterator iter = s_permanentPermissions.find(originString); - PermissionsMap::const_iterator end = s_permanentPermissions.end(); - if (iter != end) { - bool allow = iter->second; - makeAsynchronousCallbackToGeolocation(originString, allow); - return; - } - - // Check the temporary permisions. - iter = m_temporaryPermissions.find(originString); - end = m_temporaryPermissions.end(); - if (iter != end) { - bool allow = iter->second; - makeAsynchronousCallbackToGeolocation(originString, allow); - return; - } - - // If there's no pending request, prompt the user. - if (nextOriginInQueue().isEmpty()) { - // Although multiple tabs may request permissions for the same origin - // simultaneously, the routing in WebViewCore/CallbackProxy ensures that - // the result of the request will make it back to this object, so - // there's no need for a globally unique ID for the request. - m_webViewCore->geolocationPermissionsShowPrompt(originString); - } - - // Add this request to the queue so we can track which frames requested it. - if (m_queuedOrigins.find(originString) == WTF::notFound) { - m_queuedOrigins.append(originString); - FrameSet frameSet; - frameSet.add(frame); - m_queuedOriginsToFramesMap.add(originString, frameSet); - } else { - ASSERT(m_queuedOriginsToFramesMap.contains(originString)); - m_queuedOriginsToFramesMap.find(originString)->second.add(frame); - } -} - -void GeolocationPermissions::cancelPermissionStateQuery(WebCore::Frame* frame) -{ - // We cancel any queued request for the given frame. There can be at most - // one of these, since each frame maps to a single origin. We only cancel - // the request if this frame is the only one reqesting permission for this - // origin. - // - // We can use the origin string to avoid searching the map. - String originString = frame->document()->securityOrigin()->toString(); - size_t index = m_queuedOrigins.find(originString); - if (index == WTF::notFound) - return; - - ASSERT(m_queuedOriginsToFramesMap.contains(originString)); - OriginToFramesMap::iterator iter = m_queuedOriginsToFramesMap.find(originString); - ASSERT(iter->second.contains(frame)); - iter->second.remove(frame); - if (!iter->second.isEmpty()) - return; - - m_queuedOrigins.remove(index); - m_queuedOriginsToFramesMap.remove(iter); - - // If this is the origin currently being shown, cancel the prompt - // and show the next in the queue, if present. - if (index == 0) { - m_webViewCore->geolocationPermissionsHidePrompt(); - if (!nextOriginInQueue().isEmpty()) - m_webViewCore->geolocationPermissionsShowPrompt(nextOriginInQueue()); - } -} - -void GeolocationPermissions::makeAsynchronousCallbackToGeolocation(String origin, bool allow) -{ - m_callbackData.origin = origin; - m_callbackData.allow = allow; - m_timer.startOneShot(0); -} - -void GeolocationPermissions::providePermissionState(String origin, bool allow, bool remember) -{ - ASSERT(s_permanentPermissionsLoaded); - - // It's possible that this method is called with an origin that doesn't - // match m_originInProgress. This can occur if this object is reset - // while a permission result is in the process of being marshalled back to - // the WebCore thread from the browser. In this case, we simply ignore the - // call. - if (origin != nextOriginInQueue()) - return; - - maybeCallbackFrames(origin, allow); - recordPermissionState(origin, allow, remember); - - // If the permissions are set to be remembered, cancel any queued requests - // for this domain in other tabs. - if (remember) - cancelPendingRequestsInOtherTabs(origin); - - // Clear the origin from the queue. - ASSERT(!m_queuedOrigins.isEmpty()); - m_queuedOrigins.remove(0); - ASSERT(m_queuedOriginsToFramesMap.contains(origin)); - m_queuedOriginsToFramesMap.remove(origin); - - // If there are other requests queued, start the next one. - if (!nextOriginInQueue().isEmpty()) - m_webViewCore->geolocationPermissionsShowPrompt(nextOriginInQueue()); -} - -void GeolocationPermissions::recordPermissionState(String origin, bool allow, bool remember) -{ - if (remember) { - s_permanentPermissions.set(origin, allow); - s_permanentPermissionsModified = true; - } else { - // It's possible that another tab recorded a permanent permission for - // this origin while our request was in progress, but we record it - // anyway. - m_temporaryPermissions.set(origin, allow); - } -} - -void GeolocationPermissions::cancelPendingRequestsInOtherTabs(String origin) -{ - for (GeolocationPermissionsVector::const_iterator iter = s_instances.begin(); - iter != s_instances.end(); - ++iter) - (*iter)->cancelPendingRequests(origin); -} - -void GeolocationPermissions::cancelPendingRequests(String origin) -{ - size_t index = m_queuedOrigins.find(origin); - - // Don't cancel the request if it's currently being shown, in which case - // it's at index 0. - if (index == WTF::notFound || !index) - return; - - // Get the permission from the permanent list. - ASSERT(s_permanentPermissions.contains(origin)); - PermissionsMap::const_iterator iter = s_permanentPermissions.find(origin); - bool allow = iter->second; - - maybeCallbackFrames(origin, allow); - - m_queuedOrigins.remove(index); - ASSERT(m_queuedOriginsToFramesMap.contains(origin)); - m_queuedOriginsToFramesMap.remove(origin); -} - -void GeolocationPermissions::timerFired(Timer<GeolocationPermissions>* timer) -{ - ASSERT_UNUSED(timer, timer == &m_timer); - maybeCallbackFrames(m_callbackData.origin, m_callbackData.allow); -} - -void GeolocationPermissions::resetTemporaryPermissionStates() -{ - ASSERT(s_permanentPermissionsLoaded); - m_queuedOrigins.clear(); - m_queuedOriginsToFramesMap.clear(); - m_temporaryPermissions.clear(); - // If any permission results are being marshalled back to this thread, this - // will render them inefective. - m_timer.stop(); - - m_webViewCore->geolocationPermissionsHidePrompt(); -} - -const WTF::String& GeolocationPermissions::nextOriginInQueue() -{ - static const String emptyString = ""; - return m_queuedOrigins.isEmpty() ? emptyString : m_queuedOrigins[0]; -} - -void GeolocationPermissions::maybeCallbackFrames(String origin, bool allow) -{ - // We can't track which frame issued the request, as frames can be deleted - // 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()) { - if (origin == frame->document()->securityOrigin()->toString()) { - // If the page has changed, it may no longer have a Geolocation - // object. - Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation(); - if (geolocation) - geolocation->setIsAllowed(allow); - } - } -} - -GeolocationPermissions::OriginSet GeolocationPermissions::getOrigins() -{ - maybeLoadPermanentPermissions(); - OriginSet origins; - PermissionsMap::const_iterator end = s_permanentPermissions.end(); - for (PermissionsMap::const_iterator iter = s_permanentPermissions.begin(); iter != end; ++iter) - origins.add(iter->first); - return origins; -} - -bool GeolocationPermissions::getAllowed(String origin) -{ - maybeLoadPermanentPermissions(); - bool allowed = false; - PermissionsMap::const_iterator iter = s_permanentPermissions.find(origin); - PermissionsMap::const_iterator end = s_permanentPermissions.end(); - if (iter != end) - allowed = iter->second; - return allowed; -} - -void GeolocationPermissions::clear(String origin) -{ - maybeLoadPermanentPermissions(); - PermissionsMap::iterator iter = s_permanentPermissions.find(origin); - if (iter != s_permanentPermissions.end()) { - s_permanentPermissions.remove(iter); - s_permanentPermissionsModified = true; - } -} - -void GeolocationPermissions::allow(String origin) -{ - maybeLoadPermanentPermissions(); - // We replace any existing permanent permission. - s_permanentPermissions.set(origin, true); - s_permanentPermissionsModified = true; -} - -void GeolocationPermissions::clearAll() -{ - maybeLoadPermanentPermissions(); - s_permanentPermissions.clear(); - s_permanentPermissionsModified = true; -} - -void GeolocationPermissions::maybeLoadPermanentPermissions() -{ - if (s_permanentPermissionsLoaded) - return; - s_permanentPermissionsLoaded = true; - - SQLiteDatabase database; - if (!openDatabase(&database)) - return; - - // Create the table here, such that even if we've just created the DB, the - // commands below should succeed. - if (!database.executeCommand("CREATE TABLE IF NOT EXISTS Permissions (origin TEXT UNIQUE NOT NULL, allow INTEGER NOT NULL)")) { - database.close(); - return; - } - - SQLiteStatement statement(database, "SELECT * FROM Permissions"); - if (statement.prepare() != SQLResultOk) { - database.close(); - return; - } - - ASSERT(s_permanentPermissions.size() == 0); - while (statement.step() == SQLResultRow) - s_permanentPermissions.set(statement.getColumnText(0), statement.getColumnInt64(1)); - - database.close(); -} - -void GeolocationPermissions::maybeStorePermanentPermissions() -{ - // If the permanent permissions haven't been modified, there's no need to - // save them to the DB. (If we haven't even loaded them, writing them now - // would overwrite the stored permissions with the empty set.) - if (!s_permanentPermissionsModified) - return; - - SQLiteDatabase database; - if (!openDatabase(&database)) - return; - - SQLiteTransaction transaction(database); - - // The number of entries should be small enough that it's not worth trying - // to perform a diff. Simply clear the table and repopulate it. - if (!database.executeCommand("DELETE FROM Permissions")) { - database.close(); - return; - } - - PermissionsMap::const_iterator end = s_permanentPermissions.end(); - for (PermissionsMap::const_iterator iter = s_permanentPermissions.begin(); iter != end; ++iter) { - SQLiteStatement statement(database, "INSERT INTO Permissions (origin, allow) VALUES (?, ?)"); - if (statement.prepare() != SQLResultOk) - continue; - statement.bindText(1, iter->first); - statement.bindInt64(2, iter->second); - statement.executeCommand(); - } - - transaction.commit(); - database.close(); - - s_permanentPermissionsModified = false; -} - -void GeolocationPermissions::setDatabasePath(String path) -{ - // Take the first non-empty value. - if (s_databasePath.length() > 0) - return; - s_databasePath = path; -} - -bool GeolocationPermissions::openDatabase(SQLiteDatabase* database) -{ - ASSERT(database); - String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(s_databasePath, databaseName); - if (!database->open(filename)) - return false; - if (chmod(filename.utf8().data(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) { - database->close(); - return false; - } - return true; -} - -void GeolocationPermissions::setAlwaysDeny(bool deny) -{ - s_alwaysDeny = deny; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/GeolocationPermissions.h b/WebKit/android/WebCoreSupport/GeolocationPermissions.h deleted file mode 100644 index fb31dfe..0000000 --- a/WebKit/android/WebCoreSupport/GeolocationPermissions.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 GeolocationPermissions_h -#define GeolocationPermissions_h - -#include "PlatformString.h" -#include "Timer.h" - -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> -#include <wtf/text/StringHash.h> - -namespace WebCore { - class Frame; - class Geolocation; - class SQLiteDatabase; -} - -namespace android { - - class WebViewCore; - - // The GeolocationPermissions class manages Geolocation permissions for the - // browser. Permissions are managed on a per-origin basis, as required by - // the Geolocation spec - http://dev.w3.org/geo/api/spec-source.html. An - // origin specifies the scheme, host and port of particular frame. An - // origin is represented here as a string, using the output of - // WebCore::SecurityOrigin::toString. - // - // Each instance handles permissions for a given main frame. The class - // enforces the following policy. - // - Non-remembered permissions last for the dureation of the main frame. - // - Remembered permissions last indefinitely. - // - All permissions are shared between child frames of a main frame. - // - Only remembered permissions are shared between main frames. - // - Remembered permissions are made available for use in the browser - // settings menu. - 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); - virtual ~GeolocationPermissions(); - - // Queries the permission state for the specified frame. If the - // permission state has not yet been set, prompts the user. Once the - // permission state has been determined, asynchronously calls back to - // the Geolocation objects in all frames in this WebView that are from - // the same origin as the requesting frame. - void queryPermissionState(WebCore::Frame* frame); - void cancelPermissionStateQuery(WebCore::Frame*); - - // Provides this object with a permission state set by the user. The - // permission is specified by 'allow' and applied to 'origin'. If - // 'remember' is set, the permission state is remembered permanently. - // The new permission state is recorded and will trigger callbacks to - // geolocation objects as described above. If any other permission - // requests are queued, the next is started. - void providePermissionState(WTF::String origin, bool allow, bool remember); - - // Clears the temporary permission state and any pending requests. Used - // when the main frame is refreshed or navigated to a new URL. - void resetTemporaryPermissionStates(); - - // Static methods for use from Java. These are used to interact with the - // browser settings menu and to update the permanent permissions when - // system settings are changed. - // Gets the list of all origins for which permanent permissions are - // recorded. - typedef HashSet<WTF::String> OriginSet; - static OriginSet getOrigins(); - // Gets whether the specified origin is allowed. - static bool getAllowed(WTF::String origin); - // Clears the permission state for the specified origin. - static void clear(WTF::String origin); - // Sets the permission state for the specified origin to allowed. - static void allow(WTF::String origin); - // Clears the permission state for all origins. - static void clearAll(); - // Sets whether the GeolocationPermissions object should always deny - // permission requests, irrespective of previously recorded permission - // states. - static void setAlwaysDeny(bool deny); - - static void setDatabasePath(WTF::String path); - static bool openDatabase(WebCore::SQLiteDatabase*); - - // Saves the permanent permissions to the DB if required. - static void maybeStorePermanentPermissions(); - - private: - // Records the permission state for the specified origin and whether - // this should be remembered. - void recordPermissionState(WTF::String origin, bool allow, bool remember); - - // Used to make an asynchronous callback to the Geolocation objects. - void makeAsynchronousCallbackToGeolocation(WTF::String origin, bool allow); - void timerFired(WebCore::Timer<GeolocationPermissions>* timer); - - // Calls back to the Geolocation objects in all frames from the - // specified origin. There may be no such objects, as the frames using - // Geolocation from the specified origin may no longer use Geolocation, - // or may have been navigated to a different origin.. - void maybeCallbackFrames(WTF::String origin, bool allow); - - // Cancels pending permission requests for the specified origin in - // other main frames (ie browser tabs). This is used when the user - // specifies permission to be remembered. - static void cancelPendingRequestsInOtherTabs(WTF::String origin); - void cancelPendingRequests(WTF::String origin); - - static void maybeLoadPermanentPermissions(); - - 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; - OriginVector m_queuedOrigins; - // A map from a queued origin to the set of frames that have requested - // permission for that origin. - typedef HashSet<WebCore::Frame*> FrameSet; - typedef HashMap<WTF::String, FrameSet> OriginToFramesMap; - OriginToFramesMap m_queuedOriginsToFramesMap; - - typedef WTF::HashMap<WTF::String, bool> PermissionsMap; - PermissionsMap m_temporaryPermissions; - static PermissionsMap s_permanentPermissions; - - typedef WTF::Vector<GeolocationPermissions*> GeolocationPermissionsVector; - static GeolocationPermissionsVector s_instances; - - WebCore::Timer<GeolocationPermissions> m_timer; - - struct CallbackData { - WTF::String origin; - bool allow; - }; - CallbackData m_callbackData; - - static bool s_alwaysDeny; - - static bool s_permanentPermissionsLoaded; - static bool s_permanentPermissionsModified; - static WTF::String s_databasePath; - }; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/InspectorClientAndroid.h b/WebKit/android/WebCoreSupport/InspectorClientAndroid.h deleted file mode 100644 index 9d734e8..0000000 --- a/WebKit/android/WebCoreSupport/InspectorClientAndroid.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2007, 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 InspectorClientAndroid_h -#define InspectorClientAndroid_h - -#include "InspectorClient.h" - -#include <wtf/Forward.h> - -namespace android { - -class InspectorClientAndroid : public InspectorClient { -public: - virtual ~InspectorClientAndroid() { } - - virtual void inspectorDestroyed() { delete this; } - - virtual void openInspectorFrontend(WebCore::InspectorController*) {} - - virtual void highlight(Node*) {} - virtual void hideHighlight() {} - - virtual void populateSetting(const String& key, String* value) {} - virtual void storeSetting(const String& key, const String& value) {} - - virtual bool sendMessageToFrontend(const WTF::String&) { return false; } -}; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/KeyGeneratorClient.h b/WebKit/android/WebCoreSupport/KeyGeneratorClient.h deleted file mode 100644 index 1bcd8e8..0000000 --- a/WebKit/android/WebCoreSupport/KeyGeneratorClient.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 KEY_GENERATOR_CLIENT_H -#define KEY_GENERATOR_CLIENT_H - -#include "KURL.h" -#include "PlatformString.h" - -#include <wtf/Vector.h> - -using namespace WebCore; - -namespace android { - -class KeyGeneratorClient { -public: - virtual ~KeyGeneratorClient() { } - virtual WTF::Vector<String> getSupportedKeyStrengthList() = 0; - virtual String getSignedPublicKeyAndChallengeString(unsigned index, - const String& challenge, const KURL& url) = 0; - }; -} -#endif diff --git a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp deleted file mode 100644 index e6a2710..0000000 --- a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "MediaPlayerPrivateAndroid.h" - -#if ENABLE(VIDEO) - -#include "BaseLayerAndroid.h" -#include "DocumentLoader.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "SkiaUtils.h" -#include "VideoLayerAndroid.h" -#include "WebCoreJni.h" -#include "WebViewCore.h" -#include <GraphicsJNI.h> -#include <JNIHelp.h> -#include <JNIUtility.h> -#include <SkBitmap.h> -#include <gui/SurfaceTexture.h> - -using namespace android; -// Forward decl -namespace android { -sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz); -}; - -namespace WebCore { - -static const char* g_ProxyJavaClass = "android/webkit/HTML5VideoViewProxy"; -static const char* g_ProxyJavaClassAudio = "android/webkit/HTML5Audio"; - -struct MediaPlayerPrivate::JavaGlue { - jobject m_javaProxy; - jmethodID m_play; - jmethodID m_teardown; - jmethodID m_seek; - jmethodID m_pause; - // Audio - jmethodID m_newInstance; - jmethodID m_setDataSource; - jmethodID m_getMaxTimeSeekable; - // Video - jmethodID m_getInstance; - jmethodID m_loadPoster; -}; - -MediaPlayerPrivate::~MediaPlayerPrivate() -{ - // m_videoLayer is reference counted, unref is enough here. - m_videoLayer->unref(); - if (m_glue->m_javaProxy) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (env) { - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_teardown); - env->DeleteGlobalRef(m_glue->m_javaProxy); - } - } - delete m_glue; -} - -void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) -{ - registrar(create, getSupportedTypes, supportsType); -} - -MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs) -{ - if (WebViewCore::isSupportedMediaMimeType(type)) - return MediaPlayer::MayBeSupported; - return MediaPlayer::IsNotSupported; -} - -void MediaPlayerPrivate::pause() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_glue->m_javaProxy || !m_url.length()) - return; - - m_paused = true; - m_player->playbackStateChanged(); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_pause); - checkException(env); -} - -void MediaPlayerPrivate::setVisible(bool visible) -{ - m_isVisible = visible; - if (m_isVisible) - createJavaPlayerIfNeeded(); -} - -void MediaPlayerPrivate::seek(float time) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_url.length()) - return; - - if (m_glue->m_javaProxy) { - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_seek, static_cast<jint>(time * 1000.0f)); - m_currentTime = time; - } - checkException(env); -} - -void MediaPlayerPrivate::prepareToPlay() -{ - // We are about to start playing. Since our Java VideoView cannot - // buffer any data, we just simply transition to the HaveEnoughData - // state in here. This will allow the MediaPlayer to transition to - // the "play" state, at which point our VideoView will start downloading - // the content and start the playback. - m_networkState = MediaPlayer::Loaded; - m_player->networkStateChanged(); - m_readyState = MediaPlayer::HaveEnoughData; - m_player->readyStateChanged(); -} - -MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) - : m_player(player), - m_glue(0), - m_duration(1), // keep this minimal to avoid initial seek problem - m_currentTime(0), - m_paused(true), - m_readyState(MediaPlayer::HaveNothing), - m_networkState(MediaPlayer::Empty), - m_poster(0), - m_naturalSize(100, 100), - m_naturalSizeUnknown(true), - m_isVisible(false), - m_videoLayer(new VideoLayerAndroid()) -{ -} - -void MediaPlayerPrivate::onEnded() -{ - m_currentTime = duration(); - m_player->timeChanged(); - m_paused = true; - m_player->playbackStateChanged(); - m_networkState = MediaPlayer::Idle; -} - -void MediaPlayerPrivate::onPaused() -{ - m_paused = true; - m_player->playbackStateChanged(); - m_networkState = MediaPlayer::Idle; - m_player->playbackStateChanged(); -} - -void MediaPlayerPrivate::onTimeupdate(int position) -{ - m_currentTime = position / 1000.0f; - m_player->timeChanged(); -} - -void MediaPlayerPrivate::onStopFullscreen() -{ - if (m_player && m_player->mediaPlayerClient() - && m_player->mediaPlayerClient()->mediaPlayerOwningDocument()) { - m_player->mediaPlayerClient()->mediaPlayerOwningDocument()->webkitCancelFullScreen(); - } -} - -class MediaPlayerVideoPrivate : public MediaPlayerPrivate { -public: - void load(const String& url) - { - m_url = url; - // Cheat a bit here to make sure Window.onLoad event can be triggered - // at the right time instead of real video play time, since only full - // screen video play is supported in Java's VideoView. - // See also comments in prepareToPlay function. - m_networkState = MediaPlayer::Loading; - m_player->networkStateChanged(); - m_readyState = MediaPlayer::HaveCurrentData; - m_player->readyStateChanged(); - } - - void play() - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_url.length() || !m_glue->m_javaProxy) - return; - - // We only play video fullscreen on Android, so stop sites playing fullscreen video in the onload handler. - Frame* frame = m_player->frameView()->frame(); - if (frame && !frame->loader()->documentLoader()->wasOnloadHandled()) - return; - - m_paused = false; - m_player->playbackStateChanged(); - - if (m_currentTime == duration()) - m_currentTime = 0; - - jstring jUrl = wtfStringToJstring(env, m_url); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_play, jUrl, - static_cast<jint>(m_currentTime * 1000.0f), - m_videoLayer->uniqueId()); - env->DeleteLocalRef(jUrl); - - checkException(env); - } - bool canLoadPoster() const { return true; } - void setPoster(const String& url) - { - if (m_posterUrl == url) - return; - - m_posterUrl = url; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_glue->m_javaProxy || !m_posterUrl.length()) - return; - // Send the poster - jstring jUrl = wtfStringToJstring(env, m_posterUrl); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_loadPoster, jUrl); - env->DeleteLocalRef(jUrl); - } - void paint(GraphicsContext* ctxt, const IntRect& r) - { - if (ctxt->paintingDisabled()) - return; - - if (!m_isVisible) - return; - - if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef())) - return; - - SkCanvas* canvas = ctxt->platformContext()->mCanvas; - // We paint with the following rules in mind: - // - only downscale the poster, never upscale - // - maintain the natural aspect ratio of the poster - // - the poster should be centered in the target rect - float originalRatio = static_cast<float>(m_poster->width()) / static_cast<float>(m_poster->height()); - int posterWidth = r.width() > m_poster->width() ? m_poster->width() : r.width(); - int posterHeight = posterWidth / originalRatio; - 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); - } - - void onPosterFetched(SkBitmap* poster) - { - m_poster = poster; - if (m_naturalSizeUnknown) { - // We had to fake the size at startup, or else our paint - // method would not be called. If we haven't yet received - // the onPrepared event, update the intrinsic size to the size - // of the poster. That will be overriden when onPrepare comes. - // In case of an error, we should report the poster size, rather - // than our initial fake value. - m_naturalSize = IntSize(poster->width(), poster->height()); - m_player->sizeChanged(); - } - } - - void onPrepared(int duration, int width, int height) - { - m_duration = duration / 1000.0f; - m_naturalSize = IntSize(width, height); - m_naturalSizeUnknown = false; - m_player->durationChanged(); - m_player->sizeChanged(); - } - - virtual bool hasAudio() const { return false; } // do not display the audio UI - virtual bool hasVideo() const { return true; } - virtual bool supportsFullscreen() const { return true; } - - MediaPlayerVideoPrivate(MediaPlayer* player) : MediaPlayerPrivate(player) - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - - jclass clazz = env->FindClass(g_ProxyJavaClass); - - if (!clazz) - return; - - m_glue = new JavaGlue; - 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_teardown = env->GetMethodID(clazz, "teardown", "()V"); - m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V"); - m_glue->m_pause = env->GetMethodID(clazz, "pause", "()V"); - m_glue->m_javaProxy = 0; - env->DeleteLocalRef(clazz); - // An exception is raised if any of the above fails. - checkException(env); - } - - void createJavaPlayerIfNeeded() - { - // Check if we have been already created. - if (m_glue->m_javaProxy) - return; - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - - jclass clazz = env->FindClass(g_ProxyJavaClass); - - if (!clazz) - return; - - jobject obj = 0; - - FrameView* frameView = m_player->frameView(); - if (!frameView) - return; - WebViewCore* webViewCore = WebViewCore::getWebViewCore(frameView); - ASSERT(webViewCore); - - // Get the HTML5VideoViewProxy instance - obj = env->CallStaticObjectMethod(clazz, m_glue->m_getInstance, webViewCore->getJavaObject().get(), this); - m_glue->m_javaProxy = env->NewGlobalRef(obj); - // Send the poster - jstring jUrl = 0; - if (m_posterUrl.length()) - jUrl = wtfStringToJstring(env, m_posterUrl); - // Sending a NULL jUrl allows the Java side to try to load the default poster. - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_loadPoster, jUrl); - if (jUrl) - env->DeleteLocalRef(jUrl); - - // Clean up. - if (obj) - env->DeleteLocalRef(obj); - env->DeleteLocalRef(clazz); - checkException(env); - } - - float maxTimeSeekable() const - { - return m_duration; - } -}; - -class MediaPlayerAudioPrivate : public MediaPlayerPrivate { -public: - void load(const String& url) - { - m_url = url; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_url.length()) - return; - - createJavaPlayerIfNeeded(); - - if (!m_glue->m_javaProxy) - return; - - jstring jUrl = wtfStringToJstring(env, m_url); - // start loading the data asynchronously - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_setDataSource, jUrl); - env->DeleteLocalRef(jUrl); - checkException(env); - } - - void play() - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env || !m_url.length()) - return; - - createJavaPlayerIfNeeded(); - - if (!m_glue->m_javaProxy) - return; - - m_paused = false; - m_player->playbackStateChanged(); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_play); - checkException(env); - } - - virtual bool hasAudio() const { return true; } - virtual bool hasVideo() const { return false; } - virtual bool supportsFullscreen() const { return false; } - - float maxTimeSeekable() const - { - if (m_glue->m_javaProxy) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (env) { - float maxTime = env->CallFloatMethod(m_glue->m_javaProxy, - m_glue->m_getMaxTimeSeekable); - checkException(env); - return maxTime; - } - } - return 0; - } - - MediaPlayerAudioPrivate(MediaPlayer* player) : MediaPlayerPrivate(player) - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - - jclass clazz = env->FindClass(g_ProxyJavaClassAudio); - - if (!clazz) - return; - - m_glue = new JavaGlue; - m_glue->m_newInstance = env->GetMethodID(clazz, "<init>", "(I)V"); - m_glue->m_setDataSource = env->GetMethodID(clazz, "setDataSource", "(Ljava/lang/String;)V"); - m_glue->m_play = env->GetMethodID(clazz, "play", "()V"); - m_glue->m_getMaxTimeSeekable = env->GetMethodID(clazz, "getMaxTimeSeekable", "()F"); - m_glue->m_teardown = env->GetMethodID(clazz, "teardown", "()V"); - m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V"); - m_glue->m_pause = env->GetMethodID(clazz, "pause", "()V"); - m_glue->m_javaProxy = 0; - env->DeleteLocalRef(clazz); - // An exception is raised if any of the above fails. - checkException(env); - } - - void createJavaPlayerIfNeeded() - { - // Check if we have been already created. - if (m_glue->m_javaProxy) - return; - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - - jclass clazz = env->FindClass(g_ProxyJavaClassAudio); - - if (!clazz) - return; - - jobject obj = 0; - - // Get the HTML5Audio instance - obj = env->NewObject(clazz, m_glue->m_newInstance, this); - m_glue->m_javaProxy = env->NewGlobalRef(obj); - - // Clean up. - if (obj) - env->DeleteLocalRef(obj); - env->DeleteLocalRef(clazz); - checkException(env); - } - - void onPrepared(int duration, int width, int height) - { - // Android media player gives us a duration of 0 for a live - // stream, so in that case set the real duration to infinity. - // We'll still be able to handle the case that we genuinely - // get an audio clip with a duration of 0s as we'll get the - // ended event when it stops playing. - if (duration > 0) { - m_duration = duration / 1000.0f; - } else { - m_duration = std::numeric_limits<float>::infinity(); - } - m_player->durationChanged(); - m_player->sizeChanged(); - m_player->prepareToPlay(); - } -}; - -MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) -{ - if (player->mediaElementType() == MediaPlayer::Video) - return new MediaPlayerVideoPrivate(player); - return new MediaPlayerAudioPrivate(player); -} - -} - -namespace android { - -static void OnPrepared(JNIEnv* env, jobject obj, int duration, int width, int height, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onPrepared(duration, width, height); - } -} - -static void OnEnded(JNIEnv* env, jobject obj, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onEnded(); - } -} - -static void OnPaused(JNIEnv* env, jobject obj, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onPaused(); - } -} - -static void OnPosterFetched(JNIEnv* env, jobject obj, jobject poster, int pointer) -{ - if (!pointer || !poster) - return; - - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - SkBitmap* posterNative = GraphicsJNI::getNativeBitmap(env, poster); - if (!posterNative) - return; - player->onPosterFetched(posterNative); -} - -static void OnBuffering(JNIEnv* env, jobject obj, int percent, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - // TODO: player->onBuffering(percent); - } -} - -static void OnTimeupdate(JNIEnv* env, jobject obj, int position, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onTimeupdate(position); - } -} - -// This is called on the UI thread only. -// The video layers are composited on the webkit thread and then copied over -// to the UI thread with the same ID. For rendering, we are only using the -// video layers on the UI thread. Therefore, on the UI thread, we have to use -// the videoLayerId from Java side to find the exact video layer in the tree -// to set the surface texture. -// Every time a play call into Java side, the videoLayerId will be sent and -// saved in Java side. Then every time setBaseLayer call, the saved -// videoLayerId will be passed to this function to find the Video Layer. -// Return value: true when the video layer is found. -static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex, - int baseLayer, int videoLayerId, - int textureName, int playerState) { - if (!surfTex) - return false; - - sp<SurfaceTexture> texture = android::SurfaceTexture_getSurfaceTexture(env, surfTex); - if (!texture.get()) - return false; - - BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(baseLayer); - if (!layerImpl) - return false; - if (!layerImpl->countChildren()) - return false; - LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(layerImpl->getChild(0)); - if (!compositedRoot) - return false; - - VideoLayerAndroid* videoLayer = - static_cast<VideoLayerAndroid*>(compositedRoot->findById(videoLayerId)); - if (!videoLayer) - return false; - - // Set the SurfaceTexture to the layer we found - videoLayer->setSurfaceTexture(texture, textureName, static_cast<PlayerState>(playerState)); - return true; -} - -static void OnStopFullscreen(JNIEnv* env, jobject obj, int pointer) -{ - if (pointer) { - WebCore::MediaPlayerPrivate* player = - reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onStopFullscreen(); - } -} - -/* - * JNI registration - */ -static JNINativeMethod g_MediaPlayerMethods[] = { - { "nativeOnPrepared", "(IIII)V", - (void*) OnPrepared }, - { "nativeOnEnded", "(I)V", - (void*) OnEnded }, - { "nativeOnStopFullscreen", "(I)V", - (void*) OnStopFullscreen }, - { "nativeOnPaused", "(I)V", - (void*) OnPaused }, - { "nativeOnPosterFetched", "(Landroid/graphics/Bitmap;I)V", - (void*) OnPosterFetched }, - { "nativeSendSurfaceTexture", "(Landroid/graphics/SurfaceTexture;IIII)Z", - (void*) SendSurfaceTexture }, - { "nativeOnTimeupdate", "(II)V", - (void*) OnTimeupdate }, -}; - -static JNINativeMethod g_MediaAudioPlayerMethods[] = { - { "nativeOnBuffering", "(II)V", - (void*) OnBuffering }, - { "nativeOnEnded", "(I)V", - (void*) OnEnded }, - { "nativeOnPrepared", "(IIII)V", - (void*) OnPrepared }, - { "nativeOnTimeupdate", "(II)V", - (void*) OnTimeupdate }, -}; - -int registerMediaPlayerVideo(JNIEnv* env) -{ - return jniRegisterNativeMethods(env, g_ProxyJavaClass, - g_MediaPlayerMethods, NELEM(g_MediaPlayerMethods)); -} - -int registerMediaPlayerAudio(JNIEnv* env) -{ - return jniRegisterNativeMethods(env, g_ProxyJavaClassAudio, - g_MediaAudioPlayerMethods, NELEM(g_MediaAudioPlayerMethods)); -} - -} -#endif // VIDEO diff --git a/WebKit/android/WebCoreSupport/MemoryUsage.cpp b/WebKit/android/WebCoreSupport/MemoryUsage.cpp deleted file mode 100644 index 32cdebf..0000000 --- a/WebKit/android/WebCoreSupport/MemoryUsage.cpp +++ /dev/null @@ -1,81 +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. - */ - -#include "config.h" -#include "MemoryUsage.h" - -#include <malloc.h> -#include <wtf/CurrentTime.h> - -#if USE(V8) -#include <v8.h> -#endif // USE(V8) - -using namespace WTF; - -class MemoryUsageCache { -public: - MemoryUsageCache() - : m_cachedMemoryUsage(0) - , m_cacheTime(0) - { - } - - int getCachedMemoryUsage(bool forceFresh); - -private: - unsigned m_cachedMemoryUsage; - double m_cacheTime; - static const int CACHE_VALIDITY_MS = 2000; -}; - -int MemoryUsageCache::getCachedMemoryUsage(bool forceFresh) -{ - if (!forceFresh && currentTimeMS() <= m_cacheTime + CACHE_VALIDITY_MS) - return m_cachedMemoryUsage; - - struct mallinfo minfo = mallinfo(); - m_cachedMemoryUsage = (minfo.hblkhd + minfo.arena) >> 20; - -#if USE(V8) - v8::HeapStatistics stat; - v8::V8::GetHeapStatistics(&stat); - unsigned v8Usage = stat.total_heap_size() >> 20; - m_cachedMemoryUsage += v8Usage; -#endif // USE(V8) - - m_cacheTime = currentTimeMS(); - return m_cachedMemoryUsage; -} - -int MemoryUsage::memoryUsageMb(bool forceFresh) -{ - static MemoryUsageCache cache; - return cache.getCachedMemoryUsage(forceFresh); -} - -int MemoryUsage::m_lowMemoryUsageMb = 0; -int MemoryUsage::m_highMemoryUsageMb = 0; -int MemoryUsage::m_highUsageDeltaMb = 0; diff --git a/WebKit/android/WebCoreSupport/MemoryUsage.h b/WebKit/android/WebCoreSupport/MemoryUsage.h deleted file mode 100644 index 2a3d7ed..0000000 --- a/WebKit/android/WebCoreSupport/MemoryUsage.h +++ /dev/null @@ -1,45 +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 MemoryUsage_h -#define MemoryUsage_h - -class MemoryUsage { -public: - static int memoryUsageMb(bool forceFresh); - static int lowMemoryUsageMb() { return m_lowMemoryUsageMb; } - static int highMemoryUsageMb() { return m_highMemoryUsageMb; } - static int highUsageDeltaMb() { return m_highUsageDeltaMb; } - static void setHighMemoryUsageMb(int highMemoryUsageMb) { m_highMemoryUsageMb = highMemoryUsageMb; } - static void setLowMemoryUsageMb(int lowMemoryUsageMb) { m_lowMemoryUsageMb = lowMemoryUsageMb; } - static void setHighUsageDeltaMb(int highUsageDeltaMb) { m_highUsageDeltaMb = highUsageDeltaMb; } - -private: - static int m_lowMemoryUsageMb; - static int m_highMemoryUsageMb; - static int m_highUsageDeltaMb; -}; - -#endif diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp deleted file mode 100644 index 8d8d809..0000000 --- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 <PlatformBridge.h> - -#include "CookieClient.h" -#include "Document.h" -#include "FileSystemClient.h" -#include "FrameView.h" -#include "JavaSharedClient.h" -#include "KeyGeneratorClient.h" -#include "MemoryUsage.h" -#include "PluginView.h" -#include "Settings.h" -#include "WebCookieJar.h" -#include "WebRequestContext.h" -#include "WebViewCore.h" -#include "npruntime.h" - -#include <surfaceflinger/SurfaceComposerClient.h> -#include <ui/DisplayInfo.h> -#include <ui/PixelFormat.h> -#include <wtf/android/AndroidThreading.h> -#include <wtf/MainThread.h> - -using namespace android; - -namespace WebCore { - -WTF::Vector<String> PlatformBridge::getSupportedKeyStrengthList() -{ - KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient(); - if (!client) - return WTF::Vector<String>(); - - return client->getSupportedKeyStrengthList(); -} - -String PlatformBridge::getSignedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url) -{ - KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient(); - if (!client) - return String(); - - return client->getSignedPublicKeyAndChallengeString(index, challenge, url); -} - -void PlatformBridge::setCookies(const Document* document, const KURL& url, const String& value) -{ -#if USE(CHROME_NETWORK_STACK) - std::string cookieValue(value.utf8().data()); - GURL cookieGurl(url.string().utf8().data()); - bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled(); - WebCookieJar::get(isPrivateBrowsing)->cookieStore()->SetCookie(cookieGurl, cookieValue); -#else - CookieClient* client = JavaSharedClient::GetCookieClient(); - if (!client) - return; - - client->setCookies(url, value); -#endif -} - -String PlatformBridge::cookies(const Document* document, const KURL& url) -{ -#if USE(CHROME_NETWORK_STACK) - GURL cookieGurl(url.string().utf8().data()); - bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled(); - std::string cookies = WebCookieJar::get(isPrivateBrowsing)->cookieStore()->GetCookies(cookieGurl); - String cookieString(cookies.c_str()); - return cookieString; -#else - CookieClient* client = JavaSharedClient::GetCookieClient(); - if (!client) - return String(); - - return client->cookies(url); -#endif -} - -bool PlatformBridge::cookiesEnabled(const Document* document) -{ -#if USE(CHROME_NETWORK_STACK) - bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled(); - return WebCookieJar::get(isPrivateBrowsing)->allowCookies(); -#else - CookieClient* client = JavaSharedClient::GetCookieClient(); - if (!client) - return false; - - return client->cookiesEnabled(); -#endif -} - -NPObject* PlatformBridge::pluginScriptableObject(Widget* widget) -{ -#if USE(V8) - if (!widget->isPluginView()) - return 0; - - PluginView* pluginView = static_cast<PluginView*>(widget); - return pluginView->getNPObject(); -#else - return 0; -#endif -} - -bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView) -{ - android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - return webViewCore->isPaused(); -} - -bool PlatformBridge::popupsAllowed(NPP) -{ - return false; -} - -String PlatformBridge::resolveFilePathForContentUri(const String& contentUri) -{ - FileSystemClient* client = JavaSharedClient::GetFileSystemClient(); - return client->resolveFilePathForContentUri(contentUri); -} - -int PlatformBridge::PlatformBridge::screenDepth() -{ - android::DisplayInfo info; - android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info); - return info.pixelFormatInfo.bitsPerPixel; -} - -FloatRect PlatformBridge::screenRect() -{ - android::DisplayInfo info; - android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info); - return FloatRect(0.0, 0.0, info.w, info.h); -} - -// The visible size on screen in document coordinate -int PlatformBridge::screenWidthInDocCoord(const WebCore::FrameView* frameView) -{ - android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - return webViewCore->screenWidth(); -} - -int PlatformBridge::screenHeightInDocCoord(const WebCore::FrameView* frameView) -{ - android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - return webViewCore->screenHeight(); -} - -String PlatformBridge::computeDefaultLanguage() -{ -#if USE(CHROME_NETWORK_STACK) - String acceptLanguages = WebRequestContext::acceptLanguage(); - size_t length = acceptLanguages.find(','); - if (length == std::string::npos) - length = acceptLanguages.length(); - return acceptLanguages.substring(0, length); -#else - return "en"; -#endif -} - -void PlatformBridge::updateViewport(FrameView* frameView) -{ - android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - webViewCore->updateViewport(); -} - -void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, bool changeToPassword, const WTF::String& text) -{ - android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - webViewCore->updateTextfield(nodePtr, changeToPassword, text); -} - -void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) { - // Check to make sure the view is the main FrameView. - android::WebViewCore *webViewCore = android::WebViewCore::getWebViewCore(scrollView); - if (webViewCore->mainFrame()->view() == scrollView) - webViewCore->scrollTo(x, y); -} - -int PlatformBridge::lowMemoryUsageMB() -{ - return MemoryUsage::lowMemoryUsageMb(); -} - -int PlatformBridge::highMemoryUsageMB() -{ - return MemoryUsage::highMemoryUsageMb(); -} - -int PlatformBridge::highUsageDeltaMB() -{ - return MemoryUsage::highUsageDeltaMb(); -} - -int PlatformBridge::memoryUsageMB() -{ - return MemoryUsage::memoryUsageMb(false); -} - -int PlatformBridge::actualMemoryUsageMB() -{ - return MemoryUsage::memoryUsageMb(true); -} - -} // namespace WebCore - - -// This is the implementation of AndroidThreading, which is declared in -// JavaScriptCore/wtf/android/AndroidThreading.h. It is provided here, rather -// than in its own source file, to avoid linker problems. -// -// By default, when building a shared library, the linker strips from static -// libraries any compilation units which do not contain any code referenced from -// that static library. Since -// AndroidThreading::scheduleDispatchFunctionsOnMainThread is not referenced -// from libwebcore.a, implementing it in its own compilation unit results in it -// being stripped. This stripping can be avoided by using the linker option -// --whole-archive for libwebcore.a, but this adds considerably to the size of -// libwebcore.so. - -namespace WTF { - -// Callback in the main thread. -static void timeoutFired(void*) -{ - dispatchFunctionsFromMainThread(); -} - -void AndroidThreading::scheduleDispatchFunctionsOnMainThread() -{ - JavaSharedClient::EnqueueFunctionPtr(timeoutFired, 0); -} - -} // namespace WTF diff --git a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp b/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp deleted file mode 100644 index 7f54810..0000000 --- a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 <ResourceLoaderAndroid.h> - -#include "Frame.h" -#include "FrameLoaderClientAndroid.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreResourceLoader.h" -#include "WebUrlLoader.h" -#include "WebViewCore.h" - -using namespace android; - -namespace WebCore { - -PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start( - ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync) -{ - // Called on main thread - FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*>(client); -#if USE(CHROME_NETWORK_STACK) - WebViewCore* webViewCore = WebViewCore::getWebViewCore(clientAndroid->getFrame()->view()); - bool isMainFrame = !(clientAndroid->getFrame()->tree() && clientAndroid->getFrame()->tree()->parent()); - return WebUrlLoader::start(client, handle, request, isMainResource, isMainFrame, isSync, webViewCore->webRequestContext()); -#else - return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync); -#endif -} - -bool ResourceLoaderAndroid::willLoadFromCache(const WebCore::KURL& url, int64_t identifier) -{ -#if USE(CHROME_NETWORK_STACK) - // This method is used to determine if a POST request can be repeated from - // cache, but you cannot really know until you actually try to read from the - // cache. Even if we checked now, something else could come along and wipe - // out the cache entry by the time we fetch it. - // - // So, we always say yes here, to prevent the FrameLoader from initiating a - // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we - // fix-up the cache policy of the request to force a load from the cache. - return true; -#else - return WebCoreResourceLoader::willLoadFromCache(url, identifier); -#endif -} - -} diff --git a/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp b/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp deleted file mode 100644 index 3779ba8..0000000 --- a/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp +++ /dev/null @@ -1,130 +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 "UrlInterceptResponse" -#include "config.h" - -#include "JNIUtility.h" -#include "UrlInterceptResponse.h" -#include "WebCoreJni.h" - -#include <utils/Log.h> - -namespace android { - -class JavaInputStreamWrapper { -public: - JavaInputStreamWrapper(JNIEnv* env, jobject inputStream) - : m_inputStream(env->NewGlobalRef(inputStream)) - , m_buffer(0) { - LOG_ALWAYS_FATAL_IF(!inputStream); - jclass inputStreamClass = env->FindClass("java/io/InputStream"); - LOG_ALWAYS_FATAL_IF(!inputStreamClass); - m_read = env->GetMethodID(inputStreamClass, "read", "([B)I"); - LOG_ALWAYS_FATAL_IF(!m_read); - m_close = env->GetMethodID(inputStreamClass, "close", "()V"); - LOG_ALWAYS_FATAL_IF(!m_close); - } - - ~JavaInputStreamWrapper() { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_inputStream, m_close); - checkException(env); - env->DeleteGlobalRef(m_inputStream); - // In case we never call read(). - if (m_buffer) - env->DeleteGlobalRef(m_buffer); - } - - void read(std::vector<char>* out) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - // Initialize our read buffer to the capacity of out. - if (!m_buffer) { - m_buffer = env->NewByteArray(out->capacity()); - m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer); - } - int size = (int) env->CallIntMethod(m_inputStream, m_read, m_buffer); - if (checkException(env) || size < 0) - return; - // Copy from m_buffer to out. - out->resize(size); - env->GetByteArrayRegion(m_buffer, 0, size, (jbyte*)&out->front()); - } - -private: - jobject m_inputStream; - jbyteArray m_buffer; - jmethodID m_read; - jmethodID m_close; -}; - -UrlInterceptResponse::UrlInterceptResponse(JNIEnv* env, jobject response) { - jclass javaResponse = env->FindClass("android/webkit/WebResourceResponse"); - LOG_ALWAYS_FATAL_IF(!javaResponse); - jfieldID mimeType = env->GetFieldID(javaResponse, "mMimeType", - "Ljava/lang/String;"); - LOG_ALWAYS_FATAL_IF(!mimeType); - jfieldID encoding = env->GetFieldID(javaResponse, "mEncoding", - "Ljava/lang/String;"); - LOG_ALWAYS_FATAL_IF(!encoding); - jfieldID inputStream = env->GetFieldID(javaResponse, "mInputStream", - "Ljava/io/InputStream;"); - LOG_ALWAYS_FATAL_IF(!inputStream); - - jobject stream = env->GetObjectField(response, inputStream); - if (stream) - m_inputStream.set(new JavaInputStreamWrapper(env, stream)); - - jstring mimeStr = (jstring) env->GetObjectField(response, mimeType); - jstring encodingStr = (jstring) env->GetObjectField(response, encoding); - - if (mimeStr) { - const char* s = env->GetStringUTFChars(mimeStr, NULL); - m_mimeType.assign(s, env->GetStringUTFLength(mimeStr)); - env->ReleaseStringUTFChars(mimeStr, s); - } - if (encodingStr) { - const char* s = env->GetStringUTFChars(encodingStr, NULL); - m_encoding.assign(s, env->GetStringUTFLength(encodingStr)); - env->ReleaseStringUTFChars(encodingStr, s); - } - - env->DeleteLocalRef(javaResponse); - env->DeleteLocalRef(mimeStr); - env->DeleteLocalRef(encodingStr); -} - -UrlInterceptResponse::~UrlInterceptResponse() { - // Cannot be inlined because of JavaInputStreamWrapper visibility. -} - -bool UrlInterceptResponse::readStream(std::vector<char>* out) const { - if (!m_inputStream) - return false; - m_inputStream->read(out); - return true; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/UrlInterceptResponse.h b/WebKit/android/WebCoreSupport/UrlInterceptResponse.h deleted file mode 100644 index 64dad69..0000000 --- a/WebKit/android/WebCoreSupport/UrlInterceptResponse.h +++ /dev/null @@ -1,70 +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 UrlInterceptResponse_h -#define UrlInterceptResponse_h - -#include "PlatformString.h" -#include "wtf/Noncopyable.h" -#include "wtf/OwnPtr.h" - -#include <jni.h> -#include <string> -#include <vector> - -namespace android { - -class JavaInputStreamWrapper; - -class UrlInterceptResponse : public Noncopyable { -public: - UrlInterceptResponse(JNIEnv* env, jobject response); - ~UrlInterceptResponse(); - - const std::string& mimeType() const { - return m_mimeType; - } - - const std::string& encoding() const { - return m_encoding; - } - - int status() const { - return m_inputStream ? 200 : 404; - } - - // Read from the input stream. Returns false if reading failed. - // A size of 0 indicates eof. - bool readStream(std::vector<char>* out) const; - -private: - std::string m_mimeType; - std::string m_encoding; - OwnPtr<JavaInputStreamWrapper> m_inputStream; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/V8Counters.cpp b/WebKit/android/WebCoreSupport/V8Counters.cpp deleted file mode 100644 index d164f9a..0000000 --- a/WebKit/android/WebCoreSupport/V8Counters.cpp +++ /dev/null @@ -1,116 +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. - */ - - -#ifdef ANDROID_INSTRUMENT - -#define LOG_TAG "WebCore" - -#include "config.h" -#include "V8Counters.h" - -#include "NotImplemented.h" -#include <utils/Log.h> -#include <wtf/text/CString.h> -#include <wtf/text/StringHash.h> - -#if USE(V8) - -namespace WebCore { - -V8Counters::Counter::Counter(bool isHistogram) - : m_count(0), m_sampleTotal(0), m_isHistogram(isHistogram) { } - -void V8Counters::Counter::addSample(int sample) -{ - m_count++; - m_sampleTotal += sample; -} - -HashMap<String, V8Counters::Counter*> V8Counters::m_counters; - -// static -int* V8Counters::counterForName(const char* name) -{ - Counter* counter = m_counters.get(name); - if (!counter) { - counter = new Counter(false); - m_counters.add(name, counter); - } - return *counter; -} - -// static -void* V8Counters::createHistogram(const char* name, int min, int max, - size_t buckets) -{ - Counter* counter = new Counter(true); - m_counters.add(name, counter); - return counter; -} - -// static -void V8Counters::addHistogramSample(void* histogram, int sample) -{ - Counter* counter = reinterpret_cast<Counter*>(histogram); - counter->addSample(sample); -} - -// static -void V8Counters::initCounters() -{ - static bool isInitialized = false; - if (!isInitialized) { - v8::V8::SetCounterFunction(counterForName); - v8::V8::SetCreateHistogramFunction(createHistogram); - v8::V8::SetAddHistogramSampleFunction(addHistogramSample); - isInitialized = true; - } -} - -// static -void V8Counters::dumpCounters() -{ - LOGD("+----------------------------------------+-------------+\n"); - LOGD("| Name | Value |\n"); - LOGD("+----------------------------------------+-------------+\n"); - typedef HashMap<String, V8Counters::Counter*>::iterator CounterIterator; - for (CounterIterator iter = m_counters.begin(); iter != m_counters.end(); ++iter) { - Counter* counter = iter->second; - if (counter->isHistogram()) { - LOGD("| c:%-36s | %11i |\n", iter->first.latin1().data(), counter->count()); - LOGD("| t:%-36s | %11i |\n", iter->first.latin1().data(), counter->sampleTotal()); - } else { - LOGD("| %-38s | %11i |\n", iter->first.latin1().data(), counter->count()); - } - } - LOGD("+----------------------------------------+-------------+\n"); -} - -} - -#endif // ANDROID_INSTRUMENT - -#endif // USE(V8) diff --git a/WebKit/android/WebCoreSupport/V8Counters.h b/WebKit/android/WebCoreSupport/V8Counters.h deleted file mode 100644 index 499b856..0000000 --- a/WebKit/android/WebCoreSupport/V8Counters.h +++ /dev/null @@ -1,77 +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 V8Counters_h -#define V8Counters_h - -#if USE(V8) - -#ifdef ANDROID_INSTRUMENT - -#include <PlatformString.h> -#include <v8.h> -#include <wtf/HashMap.h> - -namespace WebCore { - -class V8Counters { -public: - // Counter callbacks, see v8.h - static int* counterForName(const char* name); - - static void* createHistogram(const char* name, - int min, - int max, - size_t buckets); - - static void addHistogramSample(void* histogram, int sample); - - static void initCounters(); - static void dumpCounters(); -private: - class Counter { - public: - Counter(bool isHistogram); - - int count() { return m_count; } - int sampleTotal() { return m_sampleTotal; } - bool isHistogram() { return m_isHistogram; } - void addSample(int32_t sample); - - operator int*() { return &m_count; } - private: - int m_count; - int m_sampleTotal; - bool m_isHistogram; - }; - - static HashMap<String, Counter*> m_counters; -}; - -} - -#endif // ANDROID_INSTRUMENT -#endif // USE(V8) -#endif // V8Counters_h diff --git a/WebKit/android/WebCoreSupport/WebCache.cpp b/WebKit/android/WebCoreSupport/WebCache.cpp deleted file mode 100644 index be9a700..0000000 --- a/WebKit/android/WebCoreSupport/WebCache.cpp +++ /dev/null @@ -1,237 +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. - */ - -#include "config.h" -#include "WebCache.h" - -#include "JNIUtility.h" -#include "WebCoreJni.h" -#include "WebRequestContext.h" -#include "WebUrlLoaderClient.h" - -#include <wtf/text/CString.h> - -using namespace WTF; -using namespace disk_cache; -using namespace net; -using namespace std; - -namespace android { - -static WTF::Mutex instanceMutex; - -static const string& rootDirectory() -{ - // This method may be called on any thread, as the Java method is - // synchronized. - static WTF::Mutex mutex; - MutexLocker lock(mutex); - static string cacheDirectory; - if (cacheDirectory.empty()) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass bridgeClass = env->FindClass("android/webkit/JniUtil"); - jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;"); - cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method))); - env->DeleteLocalRef(bridgeClass); - } - return cacheDirectory; -} - -static string storageDirectory() -{ - // Private cache is currently in memory only - static const char* const kDirectory = "/webviewCacheChromium"; - string storageDirectory = rootDirectory(); - storageDirectory.append(kDirectory); - return storageDirectory; -} - -static scoped_refptr<WebCache>* instance(bool isPrivateBrowsing) -{ - static scoped_refptr<WebCache> regularInstance; - static scoped_refptr<WebCache> privateInstance; - return isPrivateBrowsing ? &privateInstance : ®ularInstance; -} - -WebCache* WebCache::get(bool isPrivateBrowsing) -{ - MutexLocker lock(instanceMutex); - scoped_refptr<WebCache>* instancePtr = instance(isPrivateBrowsing); - if (!instancePtr->get()) - *instancePtr = new WebCache(isPrivateBrowsing); - return instancePtr->get(); -} - -void WebCache::cleanup(bool isPrivateBrowsing) -{ - MutexLocker lock(instanceMutex); - scoped_refptr<WebCache>* instancePtr = instance(isPrivateBrowsing); - *instancePtr = 0; -} - -WebCache::WebCache(bool isPrivateBrowsing) - : m_doomAllEntriesCallback(this, &WebCache::doomAllEntries) - , m_onClearDoneCallback(this, &WebCache::onClearDone) - , m_isClearInProgress(false) - , m_openEntryCallback(this, &WebCache::openEntry) - , m_onGetEntryDoneCallback(this, &WebCache::onGetEntryDone) - , m_isGetEntryInProgress(false) - , m_cacheBackend(0) -{ - base::Thread* ioThread = WebUrlLoaderClient::ioThread(); - scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy(); - - static const int kMaximumCacheSizeBytes = 20 * 1024 * 1024; - m_hostResolver = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0); - - m_proxyConfigService = new ProxyConfigServiceAndroid(); - net::HttpCache::BackendFactory* backendFactory; - if (isPrivateBrowsing) - backendFactory = net::HttpCache::DefaultBackend::InMemory(kMaximumCacheSizeBytes / 2); - else { - FilePath directoryPath(storageDirectory().c_str()); - backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy); - } - - m_cache = new net::HttpCache(m_hostResolver.get(), - 0, // dnsrr_resolver - 0, // dns_cert_checker - net::ProxyService::CreateWithoutProxyResolver(m_proxyConfigService, 0 /* net_log */), - net::SSLConfigService::CreateSystemSSLConfigService(), - net::HttpAuthHandlerFactory::CreateDefault(m_hostResolver.get()), - 0, // network_delegate - 0, // net_log - backendFactory); -} - -void WebCache::clear() -{ - base::Thread* thread = WebUrlLoaderClient::ioThread(); - if (thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::clearImpl)); -} - -void WebCache::clearImpl() -{ - if (m_isClearInProgress) - return; - m_isClearInProgress = true; - - if (!m_cacheBackend) { - int code = m_cache->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback); - // Code ERR_IO_PENDING indicates that the operation is still in progress and - // the supplied callback will be invoked when it completes. - if (code == ERR_IO_PENDING) - return; - else if (code != OK) { - onClearDone(0 /*unused*/); - return; - } - } - doomAllEntries(0 /*unused*/); -} - -void WebCache::doomAllEntries(int) -{ - if (!m_cacheBackend) { - onClearDone(0 /*unused*/); - return; - } - - // Code ERR_IO_PENDING indicates that the operation is still in progress and - // the supplied callback will be invoked when it completes. - if (m_cacheBackend->DoomAllEntries(&m_onClearDoneCallback) == ERR_IO_PENDING) - return; - onClearDone(0 /*unused*/); -} - -void WebCache::onClearDone(int) -{ - m_isClearInProgress = false; -} - -scoped_refptr<CacheResult> WebCache::getCacheResult(String url) -{ - // This is called on the UI thread. - MutexLocker lock(m_getEntryMutex); - if (m_isGetEntryInProgress) - return 0; // TODO: OK? Or can we queue 'em up? - - // The Chromium methods are asynchronous, but we need this method to be - // synchronous. Do the work on the Chromium thread but block this thread - // here waiting for the work to complete. - base::Thread* thread = WebUrlLoaderClient::ioThread(); - if (!thread) - return 0; - - m_entry = 0; - m_isGetEntryInProgress = true; - m_entryUrl = url.threadsafeCopy(); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::getEntryImpl)); - - while (m_isGetEntryInProgress) - m_getEntryCondition.wait(m_getEntryMutex); - - if (!m_entry) - return 0; - - return new CacheResult(m_entry, url); -} - -void WebCache::getEntryImpl() -{ - if (!m_cacheBackend) { - int code = m_cache->GetBackend(&m_cacheBackend, &m_openEntryCallback); - if (code == ERR_IO_PENDING) - return; - else if (code != OK) { - onGetEntryDone(0 /*unused*/); - return; - } - } - openEntry(0 /*unused*/); -} - -void WebCache::openEntry(int) -{ - if (!m_cacheBackend) { - onGetEntryDone(0 /*unused*/); - return; - } - - if (m_cacheBackend->OpenEntry(string(m_entryUrl.utf8().data()), &m_entry, &m_onGetEntryDoneCallback) == ERR_IO_PENDING) - return; - onGetEntryDone(0 /*unused*/); -} - -void WebCache::onGetEntryDone(int) -{ - // Unblock the UI thread in getEntry(); - MutexLocker lock(m_getEntryMutex); - m_isGetEntryInProgress = false; - m_getEntryCondition.signal(); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebCache.h b/WebKit/android/WebCoreSupport/WebCache.h deleted file mode 100644 index 7149fcc..0000000 --- a/WebKit/android/WebCoreSupport/WebCache.h +++ /dev/null @@ -1,88 +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 WebCache_h -#define WebCache_h - -#include "CacheResult.h" -#include "ChromiumIncludes.h" - -#include <OwnPtr.h> -#include <platform/text/PlatformString.h> -#include <wtf/ThreadingPrimitives.h> - -namespace android { - -// This class is not generally threadsafe. However, get() and cleanup() are -// threadsafe. -class WebCache : public base::RefCountedThreadSafe<WebCache> { -public: - static WebCache* get(bool isPrivateBrowsing); - static void cleanup(bool isPrivateBrowsing); - - void clear(); - scoped_refptr<CacheResult> getCacheResult(WTF::String url); - net::HostResolver* hostResolver() { return m_hostResolver.get(); } - net::HttpCache* cache() { return m_cache.get(); } - net::ProxyConfigServiceAndroid* proxy() { return m_proxyConfigService; } - -private: - WebCache(bool isPrivateBrowsing); - - // For clear() - void clearImpl(); - void doomAllEntries(int); - void onClearDone(int); - - // For getEntry() - void getEntryImpl(); - void openEntry(int); - void onGetEntryDone(int); - - OwnPtr<net::HostResolver> m_hostResolver; - OwnPtr<net::HttpCache> m_cache; - // This is owned by the ProxyService, which is owned by the HttpNetworkLayer, - // which is owned by the HttpCache, which is owned by this class. - net::ProxyConfigServiceAndroid* m_proxyConfigService; - - // For clear() - net::CompletionCallbackImpl<WebCache> m_doomAllEntriesCallback; - net::CompletionCallbackImpl<WebCache> m_onClearDoneCallback; - bool m_isClearInProgress; - // For getEntry() - net::CompletionCallbackImpl<WebCache> m_openEntryCallback; - net::CompletionCallbackImpl<WebCache> m_onGetEntryDoneCallback; - bool m_isGetEntryInProgress; - String m_entryUrl; - disk_cache::Entry* m_entry; - WTF::Mutex m_getEntryMutex; - WTF::ThreadCondition m_getEntryCondition; - - disk_cache::Backend* m_cacheBackend; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.cpp b/WebKit/android/WebCoreSupport/WebCookieJar.cpp deleted file mode 100644 index 99de67e..0000000 --- a/WebKit/android/WebCoreSupport/WebCookieJar.cpp +++ /dev/null @@ -1,263 +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. - */ - -#include "config.h" -#include "WebCookieJar.h" - -#include "JNIUtility.h" -#include "WebCoreJni.h" -#include "WebRequestContext.h" -#include "WebUrlLoaderClient.h" - -#include <cutils/log.h> -#include <dirent.h> - -#undef ASSERT -#define ASSERT(assertion, ...) do \ - if (!(assertion)) { \ - android_printLog(ANDROID_LOG_ERROR, __FILE__, __VA_ARGS__); \ - } \ -while (0) - -namespace android { - -static WTF::Mutex instanceMutex; -static bool isFirstInstanceCreated = false; -static bool fileSchemeCookiesEnabled = false; - -static const std::string& databaseDirectory() -{ - // This method may be called on any thread, as the Java method is - // synchronized. - static WTF::Mutex databaseDirectoryMutex; - MutexLocker lock(databaseDirectoryMutex); - static std::string databaseDirectory; - if (databaseDirectory.empty()) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass bridgeClass = env->FindClass("android/webkit/JniUtil"); - jmethodID method = env->GetStaticMethodID(bridgeClass, "getDatabaseDirectory", "()Ljava/lang/String;"); - databaseDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method))); - env->DeleteLocalRef(bridgeClass); - } - return databaseDirectory; -} - -static void removeFileOrDirectory(const char* filename) -{ - struct stat filetype; - if (stat(filename, &filetype) != 0) - return; - if (S_ISDIR(filetype.st_mode)) { - DIR* directory = opendir(filename); - if (directory) { - while (struct dirent* entry = readdir(directory)) { - if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) - continue; - std::string entryName(filename); - entryName.append("/"); - entryName.append(entry->d_name); - removeFileOrDirectory(entryName.c_str()); - } - closedir(directory); - rmdir(filename); - } - return; - } - unlink(filename); -} - -static std::string databaseDirectory(bool isPrivateBrowsing) -{ - static const char* const kDatabaseFilename = "/webviewCookiesChromium.db"; - static const char* const kDatabaseFilenamePrivateBrowsing = "/webviewCookiesChromiumPrivate.db"; - - std::string databaseFilePath = databaseDirectory(); - databaseFilePath.append(isPrivateBrowsing ? kDatabaseFilenamePrivateBrowsing : kDatabaseFilename); - return databaseFilePath; -} - -scoped_refptr<WebCookieJar>* instance(bool isPrivateBrowsing) -{ - static scoped_refptr<WebCookieJar> regularInstance; - static scoped_refptr<WebCookieJar> privateInstance; - return isPrivateBrowsing ? &privateInstance : ®ularInstance; -} - -WebCookieJar* WebCookieJar::get(bool isPrivateBrowsing) -{ - MutexLocker lock(instanceMutex); - if (!isFirstInstanceCreated && fileSchemeCookiesEnabled) - net::CookieMonster::EnableFileScheme(); - isFirstInstanceCreated = true; - scoped_refptr<WebCookieJar>* instancePtr = instance(isPrivateBrowsing); - if (!instancePtr->get()) - *instancePtr = new WebCookieJar(databaseDirectory(isPrivateBrowsing)); - return instancePtr->get(); -} - -void WebCookieJar::cleanup(bool isPrivateBrowsing) -{ - // This is called on the UI thread. - MutexLocker lock(instanceMutex); - scoped_refptr<WebCookieJar>* instancePtr = instance(isPrivateBrowsing); - *instancePtr = 0; - removeFileOrDirectory(databaseDirectory(isPrivateBrowsing).c_str()); -} - -WebCookieJar::WebCookieJar(const std::string& databaseFilePath) - : m_allowCookies(true) -{ - // Setup the permissions for the file - const char* cDatabasePath = databaseFilePath.c_str(); - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; - if (access(cDatabasePath, F_OK) == 0) - chmod(cDatabasePath, mode); - else { - int fd = open(cDatabasePath, O_CREAT, mode); - if (fd >= 0) - close(fd); - } - - FilePath cookiePath(databaseFilePath.c_str()); - m_cookieDb = new SQLitePersistentCookieStore(cookiePath); - m_cookieStore = new net::CookieMonster(m_cookieDb.get(), 0); -} - -bool WebCookieJar::allowCookies() -{ - MutexLocker lock(m_allowCookiesMutex); - return m_allowCookies; -} - -void WebCookieJar::setAllowCookies(bool allow) -{ - MutexLocker lock(m_allowCookiesMutex); - m_allowCookies = allow; -} - -int WebCookieJar::getNumCookiesInDatabase() -{ - if (!m_cookieStore) - return 0; - return m_cookieStore->GetCookieMonster()->GetAllCookies().size(); -} - -// From CookiePolicy in chromium -int WebCookieJar::CanGetCookies(const GURL&, const GURL&, net::CompletionCallback*) -{ - MutexLocker lock(m_allowCookiesMutex); - return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED; -} - -// From CookiePolicy in chromium -int WebCookieJar::CanSetCookie(const GURL&, const GURL&, const std::string&, net::CompletionCallback*) -{ - MutexLocker lock(m_allowCookiesMutex); - return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED; -} - -class FlushSemaphore : public base::RefCounted<FlushSemaphore> -{ -public: - FlushSemaphore() - : m_condition(&m_lock) - , m_count(0) - {} - - void SendFlushRequest(net::CookieMonster* monster) { - // FlushStore() needs to run on a Chrome thread (because it will need - // to post the callback, and it may want to do so on its own thread.) - // We use the IO thread for this purpose. - // - // TODO(husky): Our threads are hidden away in various files. Clean this - // up and consider integrating with Chrome's browser_thread.h. Might be - // a better idea to use the DB thread here rather than the IO thread. - - base::Thread* ioThread = WebUrlLoaderClient::ioThread(); - if (ioThread) { - Task* callback = NewRunnableMethod(this, &FlushSemaphore::Callback); - ioThread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( - monster, &net::CookieMonster::FlushStore, callback)); - } else { - Callback(); - } - } - - // Block until the given number of callbacks has been made. - void Wait(int numCallbacks) { - AutoLock al(m_lock); - int lastCount = m_count; - while (m_count < numCallbacks) { - // TODO(husky): Maybe use TimedWait() here? But it's not obvious what - // to do if the flush fails. Might be okay just to let the OS kill us. - m_condition.Wait(); - ASSERT(lastCount != m_count, "Wait finished without incrementing m_count %d %d", m_count, lastCount); - lastCount = m_count; - } - m_count -= numCallbacks; - } - -private: - friend class base::RefCounted<FlushSemaphore>; - - void Callback() { - AutoLock al(m_lock); - m_count++; - m_condition.Broadcast(); - } - - Lock m_lock; - ConditionVariable m_condition; - volatile int m_count; -}; - -void WebCookieJar::flush() -{ - // Flush both cookie stores (private and non-private), wait for 2 callbacks. - static scoped_refptr<FlushSemaphore> semaphore(new FlushSemaphore()); - semaphore->SendFlushRequest(get(false)->cookieStore()->GetCookieMonster()); - semaphore->SendFlushRequest(get(true)->cookieStore()->GetCookieMonster()); - semaphore->Wait(2); -} - -bool WebCookieJar::acceptFileSchemeCookies() -{ - MutexLocker lock(instanceMutex); - return fileSchemeCookiesEnabled; -} - -void WebCookieJar::setAcceptFileSchemeCookies(bool accept) -{ - // The Chromium HTTP stack only reflects changes to this flag when creating - // a new CookieMonster instance. While we could track whether any - // CookieMonster instances currently exist, this would be complicated and is - // not required, so we only allow this flag to be changed before the first - // instance is created. - MutexLocker lock(instanceMutex); - if (!isFirstInstanceCreated) - fileSchemeCookiesEnabled = accept; -} - -} diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.h b/WebKit/android/WebCoreSupport/WebCookieJar.h deleted file mode 100644 index 1f4266c..0000000 --- a/WebKit/android/WebCoreSupport/WebCookieJar.h +++ /dev/null @@ -1,78 +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 WebCookieJar_h -#define WebCookieJar_h - -#include "ChromiumIncludes.h" - -#include <wtf/ThreadingPrimitives.h> - -namespace android { - -// This class is threadsafe. It is used from the IO, WebCore and Chromium IO -// threads. -class WebCookieJar : public net::CookiePolicy, public base::RefCountedThreadSafe<WebCookieJar> { -public: - static WebCookieJar* get(bool isPrivateBrowsing); - static void cleanup(bool isPrivateBrowsing); - - // Flush all cookies to disk. Synchronous. - static void flush(); - - // CookiePolicy implementation from external/chromium - virtual int CanGetCookies(const GURL& url, const GURL& first_party_for_cookies, net::CompletionCallback*); - virtual int CanSetCookie(const GURL& url, const GURL& first_party_for_cookies, const std::string& cookie_line, net::CompletionCallback*); - - bool allowCookies(); - void setAllowCookies(bool allow); - - // Getter and setter for whether we accept cookies for file scheme URLS. - // Defaults to false. Note that calls to the setter are ignored once the - // first instance of this class has been created. - static bool acceptFileSchemeCookies(); - static void setAcceptFileSchemeCookies(bool); - - // Instead of this it would probably be better to add the cookie methods - // here so the rest of WebKit doesn't have to know about Chromium classes - net::CookieStore* cookieStore() { return m_cookieStore.get(); } - net::CookiePolicy* cookiePolicy() { return this; } - - // Get the number of cookies that have actually been saved to flash. - // (This is used to implement CookieManager.hasCookies() in the Java framework.) - int getNumCookiesInDatabase(); - -private: - WebCookieJar(const std::string& databaseFilePath); - - scoped_refptr<SQLitePersistentCookieStore> m_cookieDb; - scoped_refptr<net::CookieStore> m_cookieStore; - bool m_allowCookies; - WTF::Mutex m_allowCookiesMutex; -}; - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp deleted file mode 100644 index a7321da..0000000 --- a/WebKit/android/WebCoreSupport/WebRequest.cpp +++ /dev/null @@ -1,531 +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. - */ - -#include "config.h" -#include "WebRequest.h" - -#include "JNIUtility.h" -#include "MainThread.h" -#include "UrlInterceptResponse.h" -#include "WebCoreFrameBridge.h" -#include "WebRequestContext.h" -#include "WebResourceRequest.h" -#include "WebUrlLoaderClient.h" -#include "jni.h" - -#include <cutils/log.h> -#include <string> -#include <utils/AssetManager.h> - -extern android::AssetManager* globalAssetManager(); - -// TODO: -// - Finish the file upload. Testcase is mobile buzz -// - Add network throttle needed by Android plugins - -// TODO: Turn off asserts crashing before release -// http://b/issue?id=2951985 -#undef ASSERT -#define ASSERT(assertion, ...) do \ - if (!(assertion)) { \ - android_printLog(ANDROID_LOG_ERROR, __FILE__, __VA_ARGS__); \ - } \ -while (0) - -namespace android { - -namespace { - const int kInitialReadBufSize = 32768; -} - -WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& webResourceRequest) - : m_urlLoader(loader) - , m_androidUrl(false) - , m_url(webResourceRequest.url()) - , m_userAgent(webResourceRequest.userAgent()) - , m_loadState(Created) - , m_authRequestCount(0) - , m_cacheMode(0) - , m_runnableFactory(this) - , m_wantToPause(false) - , m_isPaused(false) - , m_isSync(false) -{ - GURL gurl(m_url); - - m_request = new URLRequest(gurl, this); - - m_request->SetExtraRequestHeaders(webResourceRequest.requestHeaders()); - m_request->set_referrer(webResourceRequest.referrer()); - m_request->set_method(webResourceRequest.method()); - m_request->set_load_flags(webResourceRequest.loadFlags()); -} - -// This is a special URL for Android. Query the Java InputStream -// for data and send to WebCore -WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& webResourceRequest, UrlInterceptResponse* intercept) - : m_urlLoader(loader) - , m_interceptResponse(intercept) - , m_androidUrl(true) - , m_url(webResourceRequest.url()) - , m_userAgent(webResourceRequest.userAgent()) - , m_loadState(Created) - , m_authRequestCount(0) - , m_cacheMode(0) - , m_runnableFactory(this) - , m_wantToPause(false) - , m_isPaused(false) - , m_isSync(false) -{ -} - -WebRequest::~WebRequest() -{ - ASSERT(m_loadState == Finished, "dtor called on a WebRequest in a different state than finished (%d)", m_loadState); - - m_loadState = Deleted; -} - -const std::string& WebRequest::getUrl() const -{ - return m_url; -} - -const std::string& WebRequest::getUserAgent() const -{ - return m_userAgent; -} - -#ifdef LOG_REQUESTS -namespace { -int remaining = 0; -} -#endif - -void WebRequest::finish(bool success) -{ - m_runnableFactory.RevokeAll(); - ASSERT(m_loadState < Finished, "(%p) called finish on an already finished WebRequest (%d) (%s)", this, m_loadState, m_url.c_str()); - if (m_loadState >= Finished) - return; -#ifdef LOG_REQUESTS - time_t finish; - time(&finish); - finish = finish - m_startTime; - struct tm * timeinfo; - char buffer[80]; - timeinfo = localtime(&finish); - strftime(buffer, 80, "Time: %M:%S",timeinfo); - android_printLog(ANDROID_LOG_DEBUG, "KM", "(%p) finish (%d) (%s) (%d) (%s)", this, --remaining, buffer, success, m_url.c_str()); -#endif - - // Make sure WebUrlLoaderClient doesn't delete us in the middle of this method. - scoped_refptr<WebRequest> guard(this); - - m_loadState = Finished; - if (success) { - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didFinishLoading)); - } else { - if (m_interceptResponse == NULL) { - OwnPtr<WebResponse> webResponse(new WebResponse(m_request.get())); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didFail, webResponse.release())); - } else { - OwnPtr<WebResponse> webResponse(new WebResponse(m_url, m_interceptResponse->mimeType(), 0, - m_interceptResponse->encoding(), m_interceptResponse->status())); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didFail, webResponse.release())); - } - } - m_networkBuffer = 0; - m_request = 0; - m_urlLoader = 0; -} - -void WebRequest::appendFileToUpload(const std::string& filename) -{ - // AppendFileToUpload is only valid before calling start - ASSERT(m_loadState == Created, "appendFileToUpload called on a WebRequest not in CREATED state: (%s)", m_url.c_str()); - FilePath filePath(filename); - m_request->AppendFileToUpload(filePath); -} - -void WebRequest::appendBytesToUpload(WTF::Vector<char>* data) -{ - // AppendBytesToUpload is only valid before calling start - ASSERT(m_loadState == Created, "appendBytesToUpload called on a WebRequest not in CREATED state: (%s)", m_url.c_str()); - m_request->AppendBytesToUpload(data->data(), data->size()); - delete data; -} - -void WebRequest::setRequestContext(WebRequestContext* context) -{ - m_cacheMode = context->getCacheMode(); - if (m_request) - m_request->set_context(context); -} - -void WebRequest::updateLoadFlags(int& loadFlags) -{ - if (m_cacheMode == 1) { // LOAD_CACHE_ELSE_NETWORK - loadFlags |= net::LOAD_PREFERRING_CACHE; - loadFlags &= ~net::LOAD_VALIDATE_CACHE; - } - if (m_cacheMode == 2) // LOAD_NO_CACHE - loadFlags |= net::LOAD_BYPASS_CACHE; - if (m_cacheMode == 3) // LOAD_CACHE_ONLY - loadFlags |= net::LOAD_ONLY_FROM_CACHE; - - if (m_isSync) - loadFlags |= net::LOAD_IGNORE_LIMITS; -} - -void WebRequest::start() -{ - ASSERT(m_loadState == Created, "Start called on a WebRequest not in CREATED state: (%s)", m_url.c_str()); -#ifdef LOG_REQUESTS - android_printLog(ANDROID_LOG_DEBUG, "KM", "(%p) start (%d) (%s)", this, ++remaining, m_url.c_str()); - time(&m_startTime); -#endif - - m_loadState = Started; - - if (m_interceptResponse != NULL) - return handleInterceptedURL(); - - // Handle data urls before we send it off to the http stack - if (m_request->url().SchemeIs("data")) - return handleDataURL(m_request->url()); - - if (m_request->url().SchemeIs("browser")) - return handleBrowserURL(m_request->url()); - - // Update load flags with settings from WebSettings - int loadFlags = m_request->load_flags(); - updateLoadFlags(loadFlags); - m_request->set_load_flags(loadFlags); - - m_request->Start(); -} - -void WebRequest::cancel() -{ - ASSERT(m_loadState >= Started, "Cancel called on a not started WebRequest: (%s)", m_url.c_str()); - ASSERT(m_loadState != Cancelled, "Cancel called on an already cancelled WebRequest: (%s)", m_url.c_str()); - - // There is a possible race condition between the IO thread finishing the request and - // the WebCore thread cancelling it. If the request has already finished, do - // nothing to avoid sending duplicate finish messages to WebCore. - if (m_loadState > Cancelled) { - return; - } - ASSERT(m_request, "Request set to 0 before it is finished"); - - m_loadState = Cancelled; - - m_request->Cancel(); - finish(true); -} - -void WebRequest::pauseLoad(bool pause) -{ - ASSERT(m_loadState >= GotData, "PauseLoad in state other than RESPONSE and GOTDATA"); - if (pause) { - if (!m_isPaused) - m_wantToPause = true; - } else { - m_wantToPause = false; - if (m_isPaused) { - m_isPaused = false; - MessageLoop::current()->PostTask(FROM_HERE, m_runnableFactory.NewRunnableMethod(&WebRequest::startReading)); - } - } -} - -void WebRequest::handleInterceptedURL() -{ - m_loadState = Response; - - const std::string& mime = m_interceptResponse->mimeType(); - // Get the MIME type from the URL. "text/html" is a last resort, hopefully overridden. - std::string mimeType("text/html"); - if (mime == "") { - // Gmail appends the MIME to the end of the URL, with a ? separator. - size_t mimeTypeIndex = m_url.find_last_of('?'); - if (mimeTypeIndex != std::string::npos) { - mimeType.assign(m_url.begin() + mimeTypeIndex + 1, m_url.end()); - } else { - // Get the MIME type from the file extension, if any. - FilePath path(m_url); - net::GetMimeTypeFromFile(path, &mimeType); - } - } else { - // Set from the intercept response. - mimeType = mime; - } - - - OwnPtr<WebResponse> webResponse(new WebResponse(m_url, mimeType, 0, m_interceptResponse->encoding(), m_interceptResponse->status())); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release())); - - do { - // data is deleted in WebUrlLoaderClient::didReceiveAndroidFileData - // data is sent to the webcore thread - OwnPtr<std::vector<char> > data(new std::vector<char>); - data->reserve(kInitialReadBufSize); - - // Read returns false on error and size of 0 on eof. - if (!m_interceptResponse->readStream(data.get()) || data->size() == 0) - break; - - m_loadState = GotData; - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveAndroidFileData, data.release())); - } while (true); - - finish(m_interceptResponse->status() == 200); -} - -void WebRequest::handleDataURL(GURL url) -{ - OwnPtr<std::string> data(new std::string); - std::string mimeType; - std::string charset; - - if (net::DataURL::Parse(url, &mimeType, &charset, data.get())) { - // PopulateURLResponse from chrome implementation - // weburlloader_impl.cc - m_loadState = Response; - OwnPtr<WebResponse> webResponse(new WebResponse(url.spec(), mimeType, data->size(), charset, 200)); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release())); - - if (!data->empty()) { - m_loadState = GotData; - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveDataUrl, data.release())); - } - } else { - // handle the failed case - } - - finish(true); -} - -void WebRequest::handleBrowserURL(GURL url) -{ - std::string data("data:text/html;charset=utf-8,"); - if (url.spec() == "browser:incognito") { - AssetManager* assetManager = globalAssetManager(); - Asset* asset = assetManager->open("webkit/incognito_mode_start_page.html", Asset::ACCESS_BUFFER); - if (asset) { - data.append((const char*)asset->getBuffer(false), asset->getLength()); - delete asset; - } - } - GURL dataURL(data.c_str()); - handleDataURL(dataURL); -} - -// Called upon a server-initiated redirect. The delegate may call the -// request's Cancel method to prevent the redirect from being followed. -// Since there may be multiple chained redirects, there may also be more -// than one redirect call. -// -// When this function is called, the request will still contain the -// original URL, the destination of the redirect is provided in 'new_url'. -// If the delegate does not cancel the request and |*defer_redirect| is -// false, then the redirect will be followed, and the request's URL will be -// changed to the new URL. Otherwise if the delegate does not cancel the -// request and |*defer_redirect| is true, then the redirect will be -// followed once FollowDeferredRedirect is called on the URLRequest. -// -// The caller must set |*defer_redirect| to false, so that delegates do not -// need to set it if they are happy with the default behavior of not -// deferring redirect. -void WebRequest::OnReceivedRedirect(URLRequest* newRequest, const GURL& newUrl, bool* deferRedirect) -{ - ASSERT(m_loadState < Response, "Redirect after receiving response"); - ASSERT(newRequest && newRequest->status().is_success(), "Invalid redirect"); - - OwnPtr<WebResponse> webResponse(new WebResponse(newRequest)); - webResponse->setUrl(newUrl.spec()); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::willSendRequest, webResponse.release())); - - // Defer the redirect until followDeferredRedirect() is called. - *deferRedirect = true; -} - -// Called when we receive an authentication failure. The delegate should -// call request->SetAuth() with the user's credentials once it obtains them, -// or request->CancelAuth() to cancel the login and display the error page. -// When it does so, the request will be reissued, restarting the sequence -// of On* callbacks. -void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* authInfo) -{ - ASSERT(m_loadState == Started, "OnAuthRequired called on a WebRequest not in STARTED state (state=%d)", m_loadState); - - scoped_refptr<net::AuthChallengeInfo> authInfoPtr(authInfo); - bool firstTime = (m_authRequestCount == 0); - ++m_authRequestCount; - - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr, firstTime)); -} - -// Called when we received an SSL certificate error. The delegate will provide -// the user the options to proceed, cancel, or view certificates. -void WebRequest::OnSSLCertificateError(URLRequest* request, int cert_error, net::X509Certificate* cert) -{ - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::reportSslCertError, cert_error, cert)); -} - -// After calling Start(), the delegate will receive an OnResponseStarted -// callback when the request has completed. If an error occurred, the -// request->status() will be set. On success, all redirects have been -// followed and the final response is beginning to arrive. At this point, -// meta data about the response is available, including for example HTTP -// response headers if this is a request for a HTTP resource. -void WebRequest::OnResponseStarted(URLRequest* request) -{ - ASSERT(m_loadState == Started, "Got response after receiving response"); - - m_loadState = Response; - if (request && request->status().is_success()) { - OwnPtr<WebResponse> webResponse(new WebResponse(request)); - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release())); - - // Start reading the response - startReading(); - } else { - finish(false); - } -} - -void WebRequest::setAuth(const string16& username, const string16& password) -{ - ASSERT(m_loadState == Started, "setAuth called on a WebRequest not in STARTED state (state=%d)", m_loadState); - - m_request->SetAuth(username, password); -} - -void WebRequest::cancelAuth() -{ - ASSERT(m_loadState == Started, "cancelAuth called on a WebRequest not in STARTED state (state=%d)", m_loadState); - - m_request->CancelAuth(); -} - -void WebRequest::followDeferredRedirect() -{ - ASSERT(m_loadState < Response, "Redirect after receiving response"); - - m_request->FollowDeferredRedirect(); -} - -void WebRequest::proceedSslCertError() -{ - m_request->ContinueDespiteLastError(); -} - -void WebRequest::cancelSslCertError(int cert_error) -{ - m_request->SimulateError(cert_error); -} - -void WebRequest::startReading() -{ - ASSERT(m_networkBuffer == 0, "startReading called with a nonzero buffer"); - ASSERT(m_isPaused == 0, "startReading called in paused state"); - ASSERT(m_loadState == Response || m_loadState == GotData, "StartReading in state other than RESPONSE and GOTDATA"); - if (m_loadState > GotData) // We have been cancelled between reads - return; - - if (m_wantToPause) { - m_isPaused = true; - return; - } - - int bytesRead = 0; - - if (!read(&bytesRead)) { - if (m_request && m_request->status().is_io_pending()) - return; // Wait for OnReadCompleted() - return finish(false); - } - - // bytesRead == 0 indicates finished - if (!bytesRead) - return finish(true); - - m_loadState = GotData; - // Read ok, forward buffer to webcore - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(m_urlLoader.get(), &WebUrlLoaderClient::didReceiveData, m_networkBuffer, bytesRead)); - m_networkBuffer = 0; - MessageLoop::current()->PostTask(FROM_HERE, m_runnableFactory.NewRunnableMethod(&WebRequest::startReading)); -} - -bool WebRequest::read(int* bytesRead) -{ - ASSERT(m_loadState == Response || m_loadState == GotData, "read in state other than RESPONSE and GOTDATA"); - ASSERT(m_networkBuffer == 0, "Read called with a nonzero buffer"); - - // TODO: when asserts work, check that the buffer is 0 here - m_networkBuffer = new net::IOBuffer(kInitialReadBufSize); - return m_request->Read(m_networkBuffer, kInitialReadBufSize, bytesRead); -} - -// This is called when there is data available - -// Called when the a Read of the response body is completed after an -// IO_PENDING status from a Read() call. -// The data read is filled into the buffer which the caller passed -// to Read() previously. -// -// If an error occurred, request->status() will contain the error, -// and bytes read will be -1. -void WebRequest::OnReadCompleted(URLRequest* request, int bytesRead) -{ - ASSERT(m_loadState == Response || m_loadState == GotData, "OnReadCompleted in state other than RESPONSE and GOTDATA"); - - if (request->status().is_success()) { - m_loadState = GotData; - m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( - m_urlLoader.get(), &WebUrlLoaderClient::didReceiveData, m_networkBuffer, bytesRead)); - m_networkBuffer = 0; - - // Get the rest of the data - startReading(); - } else { - finish(false); - } -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h deleted file mode 100644 index 252267b..0000000 --- a/WebKit/android/WebCoreSupport/WebRequest.h +++ /dev/null @@ -1,125 +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 WebRequest_h -#define WebRequest_h - -#include "ChromiumIncludes.h" -#include <wtf/Vector.h> - -class MessageLoop; - -namespace android { - -enum LoadState { - Created, - Started, - Response, - GotData, - Cancelled, - Finished, - Deleted -}; - -class UrlInterceptResponse; -class WebFrame; -class WebRequestContext; -class WebResourceRequest; -class WebUrlLoaderClient; - -// All methods in this class must be called on the io thread -class WebRequest : public URLRequest::Delegate, public base::RefCountedThreadSafe<WebRequest> { -public: - WebRequest(WebUrlLoaderClient*, const WebResourceRequest&); - - // If this is an android specific url or the application wants to load - // custom data, we load the data through an input stream. - // Used for: - // - file:///android_asset - // - file:///android_res - // - content:// - WebRequest(WebUrlLoaderClient*, const WebResourceRequest&, UrlInterceptResponse* intercept); - - // Optional, but if used has to be called before start - void appendBytesToUpload(Vector<char>* data); - void appendFileToUpload(const std::string& filename); - - void setRequestContext(WebRequestContext* context); - void start(); - void cancel(); - void pauseLoad(bool pause); - - // From URLRequest::Delegate - virtual void OnReceivedRedirect(URLRequest*, const GURL&, bool* deferRedirect); - virtual void OnResponseStarted(URLRequest*); - virtual void OnReadCompleted(URLRequest*, int bytesRead); - virtual void OnAuthRequired(URLRequest*, net::AuthChallengeInfo*); - virtual void OnSSLCertificateError(URLRequest* request, int cert_error, net::X509Certificate* cert); - - // Methods called during a request by the UI code (via WebUrlLoaderClient). - void setAuth(const string16& username, const string16& password); - void cancelAuth(); - void followDeferredRedirect(); - void proceedSslCertError(); - void cancelSslCertError(int cert_error); - - const std::string& getUrl() const; - const std::string& getUserAgent() const; - - void setSync(bool sync) { m_isSync = sync; } -private: - void startReading(); - bool read(int* bytesRead); - - friend class base::RefCountedThreadSafe<WebRequest>; - virtual ~WebRequest(); - void handleDataURL(GURL); - void handleBrowserURL(GURL); - void handleInterceptedURL(); - void finish(bool success); - void updateLoadFlags(int& loadFlags); - - scoped_refptr<WebUrlLoaderClient> m_urlLoader; - OwnPtr<URLRequest> m_request; - scoped_refptr<net::IOBuffer> m_networkBuffer; - scoped_ptr<UrlInterceptResponse> m_interceptResponse; - bool m_androidUrl; - std::string m_url; - std::string m_userAgent; - LoadState m_loadState; - int m_authRequestCount; - int m_cacheMode; - ScopedRunnableMethodFactory<WebRequest> m_runnableFactory; - bool m_wantToPause; - bool m_isPaused; - bool m_isSync; -#ifdef LOG_REQUESTS - time_t m_startTime; -#endif -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.cpp b/WebKit/android/WebCoreSupport/WebRequestContext.cpp deleted file mode 100644 index 78c3501..0000000 --- a/WebKit/android/WebCoreSupport/WebRequestContext.cpp +++ /dev/null @@ -1,130 +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. - */ - -#include "config.h" -#include "WebRequestContext.h" - -#include "ChromiumIncludes.h" -#include "ChromiumInit.h" -#include "WebCache.h" -#include "WebCookieJar.h" - -#include <wtf/text/CString.h> - -static std::string acceptLanguageStdString(""); -static WTF::String acceptLanguageWtfString(""); -static WTF::Mutex acceptLanguageMutex; - -static int numPrivateBrowsingInstances; - -extern void ANPSystemInterface_CleanupIncognito(); - -using namespace WTF; - -namespace android { - -WebRequestContext::WebRequestContext(bool isPrivateBrowsing) - : m_isPrivateBrowsing(isPrivateBrowsing) -{ - // Initialize chromium logging, needs to be done before any chromium code is called. - initChromium(); - - if (m_isPrivateBrowsing) { - // Delete the old files if this is the first private browsing instance - // They are probably leftovers from a power cycle - // We do not need to clear the cache as it is in memory only for private browsing - if (!numPrivateBrowsingInstances) - WebCookieJar::cleanup(true); - numPrivateBrowsingInstances++; - } - - WebCache* cache = WebCache::get(m_isPrivateBrowsing); - host_resolver_ = cache->hostResolver(); - http_transaction_factory_ = cache->cache(); - - WebCookieJar* cookieJar = WebCookieJar::get(m_isPrivateBrowsing); - cookie_store_ = cookieJar->cookieStore(); - cookie_policy_ = cookieJar; - - // Also hardcoded in FrameLoader.java - accept_charset_ = "utf-8, iso-8859-1, utf-16, *;q=0.7"; -} - -WebRequestContext::~WebRequestContext() -{ - if (m_isPrivateBrowsing) { - numPrivateBrowsingInstances--; - - // This is the last private browsing context, delete the cookies and cache - if (!numPrivateBrowsingInstances) { - WebCookieJar::cleanup(true); - WebCache::cleanup(true); - ANPSystemInterface_CleanupIncognito(); - } - } -} - -void WebRequestContext::setUserAgent(const String& string) -{ - MutexLocker lock(m_userAgentMutex); - m_userAgent = string.utf8().data(); -} - -void WebRequestContext::setCacheMode(int mode) -{ - m_cacheMode = mode; -} - -int WebRequestContext::getCacheMode() -{ - return m_cacheMode; -} - -const std::string& WebRequestContext::GetUserAgent(const GURL& url) const -{ - MutexLocker lock(m_userAgentMutex); - return m_userAgent; -} - -void WebRequestContext::setAcceptLanguage(const String& string) -{ - MutexLocker lock(acceptLanguageMutex); - acceptLanguageStdString = string.utf8().data(); - acceptLanguageWtfString = string; -} - -const std::string& WebRequestContext::GetAcceptLanguage() const -{ - MutexLocker lock(acceptLanguageMutex); - return acceptLanguageStdString; -} - -const String& WebRequestContext::acceptLanguage() -{ - MutexLocker lock(acceptLanguageMutex); - return acceptLanguageWtfString; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.h b/WebKit/android/WebCoreSupport/WebRequestContext.h deleted file mode 100644 index 51f0514..0000000 --- a/WebKit/android/WebCoreSupport/WebRequestContext.h +++ /dev/null @@ -1,64 +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 WebRequestContext_h -#define WebRequestContext_h - -#include "ChromiumIncludes.h" -#include "PlatformString.h" - -#include <wtf/ThreadingPrimitives.h> - -namespace android { - -// This class is generally not threadsafe. -class WebRequestContext : public URLRequestContext { -public: - // URLRequestContext overrides. - virtual const std::string& GetUserAgent(const GURL&) const; - virtual const std::string& GetAcceptLanguage() const; - - WebRequestContext(bool isPrivateBrowsing); - - // These methods are threadsafe. - void setUserAgent(const WTF::String&); - void setCacheMode(int); - int getCacheMode(); - static void setAcceptLanguage(const WTF::String&); - static const WTF::String& acceptLanguage(); - -private: - WebRequestContext(); - ~WebRequestContext(); - - std::string m_userAgent; - int m_cacheMode; - mutable WTF::Mutex m_userAgentMutex; - bool m_isPrivateBrowsing; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp deleted file mode 100644 index 9b70fce..0000000 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp +++ /dev/null @@ -1,96 +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. - */ - -#include "config.h" -#include "WebResourceRequest.h" - -#include "ResourceRequest.h" - -#include <wtf/text/CString.h> - -using namespace WebCore; - -namespace android { - -WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceRequest) -{ - // Set the load flags based on the WebCore request. - m_loadFlags = net::LOAD_NORMAL; - switch (resourceRequest.cachePolicy()) { - case ReloadIgnoringCacheData: - m_loadFlags |= net::LOAD_VALIDATE_CACHE; - break; - case ReturnCacheDataElseLoad: - m_loadFlags |= net::LOAD_PREFERRING_CACHE; - break; - case ReturnCacheDataDontLoad: - m_loadFlags |= net::LOAD_ONLY_FROM_CACHE; - break; - case UseProtocolCachePolicy: - break; - } - - // TODO: We should consider setting these flags and net::LOAD_DO_NOT_SEND_AUTH_DATA - // when FrameLoaderClient::shouldUseCredentialStorage() is false. However, - // the required WebKit logic is not yet in place. See Chromium's - // FrameLoaderClientImpl::shouldUseCredentialStorage(). - if (!resourceRequest.allowCookies()) { - m_loadFlags |= net::LOAD_DO_NOT_SAVE_COOKIES; - m_loadFlags |= net::LOAD_DO_NOT_SEND_COOKIES; - } - - - // Set the request headers - const HTTPHeaderMap& map = resourceRequest.httpHeaderFields(); - for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it) { - const std::string& nameUtf8 = it->first.string().utf8().data(); - const std::string& valueUtf8 = it->second.utf8().data(); - - // Skip over referrer headers found in the header map because we already - // pulled it out as a separate parameter. We likewise prune the UA since - // that will be added back by the network layer. - if (LowerCaseEqualsASCII(nameUtf8, "referer") || LowerCaseEqualsASCII(nameUtf8, "user-agent")) - continue; - - // Skip over "Cache-Control: max-age=0" header if the corresponding - // load flag is already specified. FrameLoader sets both the flag and - // the extra header -- the extra header is redundant since our network - // implementation will add the necessary headers based on load flags. - // See http://code.google.com/p/chromium/issues/detail?id=3434. - if ((m_loadFlags & net::LOAD_VALIDATE_CACHE) && - LowerCaseEqualsASCII(nameUtf8, "cache-control") && LowerCaseEqualsASCII(valueUtf8, "max-age=0")) - continue; - - m_requestHeaders.SetHeader(nameUtf8, valueUtf8); - } - - m_method = resourceRequest.httpMethod().utf8().data(); - m_referrer = resourceRequest.httpReferrer().utf8().data(); - m_userAgent = resourceRequest.httpUserAgent().utf8().data(); - - m_url = resourceRequest.url().string().utf8().data(); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.h b/WebKit/android/WebCoreSupport/WebResourceRequest.h deleted file mode 100644 index 38f37b5..0000000 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.h +++ /dev/null @@ -1,86 +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 WebResourceRequest_h -#define WebResourceRequest_h - -#include "ChromiumIncludes.h" - -#include <string> - -namespace WebCore { -class ResourceRequest; -} - -namespace android { - -class WebResourceRequest { - -public: - WebResourceRequest(const WebCore::ResourceRequest&); - - const std::string& method() const - { - return m_method; - } - - const std::string& referrer() const - { - return m_referrer; - } - - const std::string& userAgent() const - { - return m_userAgent; - } - - const net::HttpRequestHeaders& requestHeaders() const - { - return m_requestHeaders; - } - - const std::string& url() const - { - return m_url; - } - - int loadFlags() const - { - return m_loadFlags; - } - -private: - std::string m_method; - std::string m_referrer; - std::string m_userAgent; - net::HttpRequestHeaders m_requestHeaders; - std::string m_url; - int m_loadFlags; -}; - -} // namespace android - - -#endif diff --git a/WebKit/android/WebCoreSupport/WebResponse.cpp b/WebKit/android/WebCoreSupport/WebResponse.cpp deleted file mode 100644 index 4d297d7..0000000 --- a/WebKit/android/WebCoreSupport/WebResponse.cpp +++ /dev/null @@ -1,167 +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. - */ - -#include "config.h" -#include "WebResponse.h" - -#include "MIMETypeRegistry.h" -#include "PlatformString.h" -#include "ResourceResponse.h" -#include "ResourceError.h" - -#include <wtf/text/CString.h> - -using namespace std; - -namespace android { - -WebResponse::WebResponse(URLRequest* request) - : m_httpStatusCode(0) -{ - // The misleadingly-named os_error() is actually a net::Error enum constant. - m_error = net::Error(request->status().os_error()); - - m_url = request->url().spec(); - m_host = request->url().HostNoBrackets(); - request->GetMimeType(&m_mime); - - request->GetCharset(&m_encoding); - m_expectedSize = request->GetExpectedContentSize(); - - m_sslInfo = request->ssl_info(); - - net::HttpResponseHeaders* responseHeaders = request->response_headers(); - if (!responseHeaders) - return; - - m_httpStatusCode = responseHeaders->response_code(); - m_httpStatusText = responseHeaders->GetStatusText(); - - string value; - string name; - void* iter = 0; - while (responseHeaders->EnumerateHeaderLines(&iter, &name, &value)) - m_headerFields[name] = value; -} - -WebResponse::WebResponse(const string &url, const string &mimeType, long long expectedSize, const string &encoding, int httpStatusCode) - : m_error(net::OK) - , m_encoding(encoding) - , m_httpStatusCode(httpStatusCode) - , m_expectedSize(expectedSize) - , m_mime(mimeType) - , m_url(url) -{ -} - -WebCore::ResourceResponse WebResponse::createResourceResponse() -{ - WebCore::ResourceResponse resourceResponse(createKurl(), getMimeType().c_str(), m_expectedSize, m_encoding.c_str(), ""); - resourceResponse.setHTTPStatusCode(m_httpStatusCode); - resourceResponse.setHTTPStatusText(m_httpStatusText.c_str()); - - map<string, string>::const_iterator it; - for (it = m_headerFields.begin(); it != m_headerFields.end(); ++it) - resourceResponse.setHTTPHeaderField(it->first.c_str(), it->second.c_str()); - - return resourceResponse; -} - -WebCore::ResourceError WebResponse::createResourceError() -{ - WebCore::ResourceError error(m_host.c_str(), ToWebViewClientError(m_error), m_url.c_str(), WTF::String()); - return error; -} - - -WebCore::KURL WebResponse::createKurl() -{ - WebCore::KURL kurl(WebCore::ParsedURLString, m_url.c_str()); - return kurl; -} - -const string& WebResponse::getUrl() const -{ - return m_url; -} - -void WebResponse::setUrl(const string& url) -{ - m_url = url; -} - -// Calls WebCore APIs so should only be called from the WebCore thread. -// TODO: can we return a WTF::String directly? Need to check all callsites. -const string& WebResponse::getMimeType() -{ - if (!m_url.length()) - return m_mime; - - if (!m_mime.length() || !m_mime.compare("text/plain") || !m_mime.compare("application/octet-stream")) - m_mime = resolveMimeType(m_url, m_mime); - - return m_mime; -} - -const string WebResponse::resolveMimeType(const string& url, const string& old_mime) -{ - // Use "text/html" as a default (matching the behaviour of the Apache - // HTTP stack -- see guessMimeType() in LoadListener.java). - string mimeType = old_mime.length() ? old_mime : "text/html"; - // Try to guess a better MIME type from the URL. We call - // getMIMETypeForExtension rather than getMIMETypeForPath because the - // latter defaults to "application/octet-stream" on failure. - WebCore::KURL kurl(WebCore::ParsedURLString, url.c_str()); - WTF::String path = kurl.path(); - size_t extensionPos = path.reverseFind('.'); - if (extensionPos != WTF::notFound) { - // We found a file extension. - path.remove(0, extensionPos + 1); - // TODO: Should use content-disposition instead of url if it is there - WTF::String mime = WebCore::MIMETypeRegistry::getMIMETypeForExtension(path); - if (!mime.isEmpty()) { - // Great, we found a MIME type. - mimeType = std::string(mime.utf8().data(), mime.length()); - } - } - return mimeType; -} - -bool WebResponse::getHeader(const string& header, string* result) const -{ - map<string, string>::const_iterator iter = m_headerFields.find(header); - if (iter == m_headerFields.end()) - return false; - if (result) - *result = iter->second; - return true; -} - -long long WebResponse::getExpectedSize() const -{ - return m_expectedSize; -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebResponse.h b/WebKit/android/WebCoreSupport/WebResponse.h deleted file mode 100644 index 88c8917..0000000 --- a/WebKit/android/WebCoreSupport/WebResponse.h +++ /dev/null @@ -1,91 +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 WebResponse_h -#define WebResponse_h - -#include "ChromiumIncludes.h" -#include "KURL.h" -#include "WebViewClientError.h" - -#include <map> -#include <string> - -namespace WebCore { -class ResourceResponse; -class ResourceError; -} - -namespace android { - -class WebResponse { - -public: - WebResponse() {} - WebResponse(URLRequest*); - WebResponse(const std::string &url, const std::string &mimeType, long long expectedSize, const std::string &encoding, int httpStatusCode); - - const std::string& getUrl() const; - void setUrl(const std::string&); - - const std::string& getMimeType(); // Use only on WebCore thread. - bool getHeader(const std::string& header, std::string* result) const; - long long getExpectedSize() const; - - const net::SSLInfo& getSslInfo() const { return m_sslInfo; } - - // The create() methods create WebCore objects. They must only be called on the WebKit thread. - WebCore::KURL createKurl(); - WebCore::ResourceResponse createResourceResponse(); - WebCore::ResourceError createResourceError(); - - static const std::string resolveMimeType(const std::string& url, const std::string& old_mime); - -private: - net::Error m_error; - std::string m_encoding; - int m_httpStatusCode; - std::string m_host; - std::string m_httpStatusText; - long long m_expectedSize; - std::string m_mime; - std::string m_url; - net::SSLInfo m_sslInfo; - - struct CaseInsensitiveLessThan { - bool operator()(const std::string& lhs, const std::string& rhs) const { - return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; - } - }; - - // Header fields are case insensitive, so we use a case-insensitive map. - // See RFC 822, 3.4.7, "CASE INDEPENDENCE". - std::map<std::string, std::string, CaseInsensitiveLessThan> m_headerFields; - -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp deleted file mode 100644 index 0c90bc5..0000000 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp +++ /dev/null @@ -1,87 +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. - */ - -#include "config.h" - -#include "WebUrlLoader.h" - -#include "FrameLoaderClientAndroid.h" -#include "WebCoreFrameBridge.h" -#include "WebUrlLoaderClient.h" - -namespace android { - -// on main thread -WebUrlLoader::WebUrlLoader(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) -{ - m_loaderClient = new WebUrlLoaderClient(webFrame, resourceHandle, resourceRequest); -} - -// on main thread -WebUrlLoader::~WebUrlLoader() -{ -} - -PassRefPtr<WebUrlLoader> WebUrlLoader::start(FrameLoaderClient* client, WebCore::ResourceHandle* resourceHandle, - const WebCore::ResourceRequest& resourceRequest, bool isMainResource, bool isMainFrame, bool isSync, WebRequestContext* context) -{ - FrameLoaderClientAndroid* androidClient = static_cast<FrameLoaderClientAndroid*>(client); - WebFrame* webFrame = androidClient->webFrame(); - - if (webFrame->blockNetworkLoads() && - (resourceRequest.url().protocolIs("http") || - resourceRequest.url().protocolIs("https"))) - return NULL; - - webFrame->maybeSavePassword(androidClient->getFrame(), resourceRequest); - - RefPtr<WebUrlLoader> loader = WebUrlLoader::create(webFrame, resourceHandle, resourceRequest); - loader->m_loaderClient->start(isMainResource, isMainFrame, isSync, context); - - return loader.release(); -} - -PassRefPtr<WebUrlLoader> WebUrlLoader::create(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) -{ - return adoptRef(new WebUrlLoader(webFrame, resourceHandle, resourceRequest)); -} - -// on main thread -void WebUrlLoader::cancel() -{ - m_loaderClient->cancel(); -} - -void WebUrlLoader::downloadFile() -{ - m_loaderClient->downloadFile(); -} - -void WebUrlLoader::pauseLoad(bool pause) -{ - m_loaderClient->pauseLoad(pause); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.h b/WebKit/android/WebCoreSupport/WebUrlLoader.h deleted file mode 100644 index dd88e73..0000000 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.h +++ /dev/null @@ -1,57 +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 WebUrlLoader_h -#define WebUrlLoader_h - -#include "ChromiumIncludes.h" -#include "ResourceLoaderAndroid.h" - -using namespace WebCore; - -namespace android { -class WebUrlLoaderClient; -class WebFrame; -class WebRequestContext; - -class WebUrlLoader : public ResourceLoaderAndroid { -public: - virtual ~WebUrlLoader(); - static PassRefPtr<WebUrlLoader> start(FrameLoaderClient* client, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool isMainResource, bool isMainFrame, bool sync, WebRequestContext*); - - virtual void cancel(); - virtual void downloadFile(); - virtual void pauseLoad(bool pause); - -private: - WebUrlLoader(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); - static PassRefPtr<WebUrlLoader> create(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); - - scoped_refptr<WebUrlLoaderClient> m_loaderClient; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp deleted file mode 100644 index cf218e7..0000000 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp +++ /dev/null @@ -1,482 +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 "WebUrlLoaderClient" - -#include "config.h" -#include "WebUrlLoaderClient.h" - -#include "ChromiumIncludes.h" -#include "OwnPtr.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceResponse.h" -#include "WebCoreFrameBridge.h" -#include "WebRequest.h" -#include "WebResourceRequest.h" - -#include <wtf/text/CString.h> - -namespace android { - -base::Thread* WebUrlLoaderClient::ioThread() -{ - static base::Thread* networkThread = 0; - static Lock networkThreadLock; - - // Multiple threads appear to access the ioThread so we must ensure the - // critical section ordering. - AutoLock lock(networkThreadLock); - - if (!networkThread) - networkThread = new base::Thread("network"); - - if (!networkThread) - return 0; - - if (networkThread->IsRunning()) - return networkThread; - - base::Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; - if (!networkThread->StartWithOptions(options)) { - delete networkThread; - networkThread = 0; - } - - return networkThread; -} - -Lock* WebUrlLoaderClient::syncLock() { - static Lock s_syncLock; - return &s_syncLock; -} - -ConditionVariable* WebUrlLoaderClient::syncCondition() { - static ConditionVariable s_syncCondition(syncLock()); - return &s_syncCondition; -} - -WebUrlLoaderClient::~WebUrlLoaderClient() -{ -} - -bool WebUrlLoaderClient::isActive() const -{ - if (m_cancelling) - return false; - if (!m_resourceHandle) - return false; - if (!m_resourceHandle->client()) - return false; - if (m_finished) - return false; - - return true; -} - -WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) - : m_webFrame(webFrame) - , m_resourceHandle(resourceHandle) - , m_isMainResource(false) - , m_isMainFrame(false) - , m_isCertMimeType(false) - , m_cancelling(false) - , m_sync(false) - , m_finished(false) -{ - WebResourceRequest webResourceRequest(resourceRequest); - UrlInterceptResponse* intercept = webFrame->shouldInterceptRequest(resourceRequest.url().string()); - if (intercept) { - m_request = new WebRequest(this, webResourceRequest, intercept); - return; - } - - m_request = new WebRequest(this, webResourceRequest); - - // Set uploads before start is called on the request - if (resourceRequest.httpBody() && !(webResourceRequest.method() == "GET" || webResourceRequest.method() == "HEAD")) { - Vector<FormDataElement>::iterator iter; - Vector<FormDataElement> elements = resourceRequest.httpBody()->elements(); - for (iter = elements.begin(); iter != elements.end(); iter++) { - FormDataElement element = *iter; - - switch (element.m_type) { - case FormDataElement::data: - if (!element.m_data.isEmpty()) { - // WebKit sometimes gives up empty data to append. These aren't - // necessary so we just optimize those out here. - base::Thread* thread = ioThread(); - if (thread) { - Vector<char>* data = new Vector<char>(element.m_data); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::appendBytesToUpload, data)); - } - } - break; - case FormDataElement::encodedFile: - { - // Chromium check if it is a directory by checking - // element.m_fileLength, that doesn't work in Android - std::string filename = element.m_filename.utf8().data(); - if (filename.size()) { - // Change from a url string to a filename - if (filename.find("file://") == 0) // Found at pos 0 - filename.erase(0, 7); - base::Thread* thread = ioThread(); - if (thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::appendFileToUpload, filename)); - } - } - break; -#if ENABLE(BLOB) - case FormDataElement::encodedBlob: - LOG_ASSERT(false, "Unexpected use of FormDataElement::encodedBlob"); - break; -#endif // ENABLE(BLOB) - default: - LOG_ASSERT(false, "Unexpected default case in WebUrlLoaderClient.cpp"); - break; - } - } - } -} - -bool WebUrlLoaderClient::start(bool isMainResource, bool isMainFrame, bool sync, WebRequestContext* context) -{ - base::Thread* thread = ioThread(); - if (!thread) { - return false; - } - - m_isMainResource = isMainResource; - m_isMainFrame = isMainFrame; - m_sync = sync; - if (m_sync) { - AutoLock autoLock(*syncLock()); - m_request->setSync(sync); - m_request->setRequestContext(context); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start)); - - // Run callbacks until the queue is exhausted and m_finished is true. - // Sometimes, a sync load can wait forever and lock up the WebCore thread, - // here we use TimedWait() with multiple tries to avoid locking. - const int kMaxNumTimeout = 3; - const int kCallbackWaitingTime = 10; - int num_timeout = 0; - while(!m_finished) { - while (!m_queue.empty()) { - OwnPtr<Task> task(m_queue.front()); - m_queue.pop_front(); - task->Run(); - } - if (m_finished) break; - - syncCondition()->TimedWait(base::TimeDelta::FromSeconds(kCallbackWaitingTime)); - if (m_queue.empty()) { - LOGE("Synchronous request timed out after %d seconds for the %dth try, URL: %s", - kCallbackWaitingTime, num_timeout, m_request->getUrl().c_str()); - num_timeout++; - if (num_timeout >= kMaxNumTimeout) { - cancel(); - m_resourceHandle = 0; - return false; - } - } - } - - // This may be the last reference to us, so we may be deleted now. - // Don't access any more member variables after releasing this reference. - m_resourceHandle = 0; - } else { - // Asynchronous start. - // Important to set this before the thread starts so it has a reference and can't be deleted - // before the task starts running on the IO thread. - m_request->setRequestContext(context); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start)); - } - return true; -} - -namespace { -// Check if the mime type is for certificate installation. -// The items must be consistent with the sCertificateTypeMap -// in frameworks/base/core/java/android/webkit/CertTool.java. -bool isMimeTypeForCert(const std::string& mimeType) -{ - static std::hash_set<std::string> sCertificateTypeSet; - if (sCertificateTypeSet.empty()) { - sCertificateTypeSet.insert("application/x-x509-ca-cert"); - sCertificateTypeSet.insert("application/x-x509-user-cert"); - sCertificateTypeSet.insert("application/x-pkcs12"); - } - return sCertificateTypeSet.find(mimeType) != sCertificateTypeSet.end(); -} -} - -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_isCertMimeType = isMimeTypeForCert(m_response->getMimeType()); - // Currently, only certificate mime type needs to receive the data. - // Other mime type, e.g. wav, will send the url to other application - // which will load the data by url. - if (!m_isCertMimeType) - cancel(); - } else { - LOGE("Unexpected call to downloadFile() before didReceiveResponse(). URL: %s", m_request->getUrl().c_str()); - // TODO: Turn off asserts crashing before release - // http://b/issue?id=2951985 - CRASH(); - } -} - -void WebUrlLoaderClient::cancel() -{ - if (!isActive()) - return; - - m_cancelling = true; - - base::Thread* thread = ioThread(); - if (thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancel)); -} - -void WebUrlLoaderClient::pauseLoad(bool pause) -{ - if (!isActive()) - return; - - base::Thread* thread = ioThread(); - if (thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::pauseLoad, pause)); -} - -void WebUrlLoaderClient::setAuth(const std::string& username, const std::string& password) -{ - if (!isActive()) - return; - - base::Thread* thread = ioThread(); - if (!thread) { - return; - } - string16 username16 = ASCIIToUTF16(username); - string16 password16 = ASCIIToUTF16(password); - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::setAuth, username16, password16)); -} - -void WebUrlLoaderClient::cancelAuth() -{ - if (!isActive()) - return; - - base::Thread* thread = ioThread(); - if (!thread) { - return; - } - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelAuth)); -} - -void WebUrlLoaderClient::proceedSslCertError() -{ - base::Thread* thread = ioThread(); - if (isActive() && thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::proceedSslCertError)); - this->Release(); -} - -void WebUrlLoaderClient::cancelSslCertError(int cert_error) -{ - base::Thread* thread = ioThread(); - if (isActive() && thread) - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelSslCertError, cert_error)); - this->Release(); -} - - -void WebUrlLoaderClient::finish() -{ - m_finished = true; - if (!m_sync) { - // This is the last reference to us, so we will be deleted now. - // We only release the reference here if start() was called asynchronously! - m_resourceHandle = 0; - } - m_request = 0; -} - -namespace { -// Trampoline to wrap a Chromium Task* in a WebKit-style static function + void*. -static void RunTask(void* v) { - OwnPtr<Task> task(static_cast<Task*>(v)); - task->Run(); -} -} - -// This is called from the IO thread, and dispatches the callback to the main thread. -void WebUrlLoaderClient::maybeCallOnMainThread(Task* task) -{ - if (m_sync) { - AutoLock autoLock(*syncLock()); - if (m_queue.empty()) { - syncCondition()->Broadcast(); - } - m_queue.push_back(task); - } else { - // Let WebKit handle it. - callOnMainThread(RunTask, task); - } -} - -// Response methods -void WebUrlLoaderClient::didReceiveResponse(PassOwnPtr<WebResponse> webResponse) -{ - if (!isActive()) - return; - - m_response = webResponse; - m_resourceHandle->client()->didReceiveResponse(m_resourceHandle.get(), m_response->createResourceResponse()); - - // Set the main page's certificate to WebView. - if (m_isMainResource && m_isMainFrame) { - const net::SSLInfo& ssl_info = m_response->getSslInfo(); - if (ssl_info.is_valid()) { - std::vector<std::string> chain_bytes; - ssl_info.cert->GetChainDEREncodedBytes(&chain_bytes); - m_webFrame->setCertificate(chain_bytes[0]); - } - - // Look for X-Auto-Login on the main resource to log in the user. - std::string login; - if (m_response->getHeader("x-auto-login", &login)) - m_webFrame->autoLogin(login); - } -} - -void WebUrlLoaderClient::didReceiveData(scoped_refptr<net::IOBuffer> buf, int size) -{ - if (m_isMainResource && m_isCertMimeType) { - m_webFrame->didReceiveData(buf->data(), size); - } - - if (!isActive() || !size) - return; - - // didReceiveData will take a copy of the data - if (m_resourceHandle && m_resourceHandle->client()) - m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), buf->data(), size, size); -} - -// For data url's -void WebUrlLoaderClient::didReceiveDataUrl(PassOwnPtr<std::string> str) -{ - if (!isActive() || !str->size()) - return; - - // didReceiveData will take a copy of the data - m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), str->data(), str->size(), str->size()); -} - -// For special android files -void WebUrlLoaderClient::didReceiveAndroidFileData(PassOwnPtr<std::vector<char> > vector) -{ - if (!isActive() || !vector->size()) - return; - - // didReceiveData will take a copy of the data - m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), vector->begin(), vector->size(), vector->size()); -} - -void WebUrlLoaderClient::didFail(PassOwnPtr<WebResponse> webResponse) -{ - if (isActive()) - m_resourceHandle->client()->didFail(m_resourceHandle.get(), webResponse->createResourceError()); - - // Always finish a request, if not it will leak - finish(); -} - -void WebUrlLoaderClient::willSendRequest(PassOwnPtr<WebResponse> webResponse) -{ - if (!isActive()) - return; - - KURL url = webResponse->createKurl(); - OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(url)); - m_resourceHandle->client()->willSendRequest(m_resourceHandle.get(), *resourceRequest, webResponse->createResourceResponse()); - - // WebKit may have killed the request. - if (!isActive()) - return; - - // Like Chrome, we only follow the redirect if WebKit left the URL unmodified. - if (url == resourceRequest->url()) { - ioThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::followDeferredRedirect)); - } else { - cancel(); - } -} - -void WebUrlLoaderClient::didFinishLoading() -{ - if (isActive()) - m_resourceHandle->client()->didFinishLoading(m_resourceHandle.get(), 0); - - if (m_isMainResource && m_isCertMimeType) { - m_webFrame->didFinishLoading(); - } - - // Always finish a request, if not it will leak - finish(); -} - -void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> authChallengeInfo, bool firstTime) -{ - if (!isActive()) - return; - - std::string host = base::SysWideToUTF8(authChallengeInfo->host_and_port); - std::string realm = base::SysWideToUTF8(authChallengeInfo->realm); - - m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, firstTime); -} - -void WebUrlLoaderClient::reportSslCertError(int cert_error, net::X509Certificate* cert) -{ - if (!isActive()) - return; - - std::vector<std::string> chain_bytes; - cert->GetChainDEREncodedBytes(&chain_bytes); - this->AddRef(); - m_webFrame->reportSslCertError(this, cert_error, chain_bytes[0]); -} - -} // namespace android diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h deleted file mode 100644 index dc101db..0000000 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h +++ /dev/null @@ -1,130 +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 WebUrlLoaderClient_h -#define WebUrlLoaderClient_h - -#include "ChromiumIncludes.h" -#include "RefCounted.h" -#include "WebResponse.h" -#include "WebUrlLoader.h" - -#include <string> -#include <deque> -#include <string> -#include <vector> - -class Lock; -class ConditionVariable; - -namespace base { -class Thread; -} - -namespace net { -class IOBuffer; -class AuthChallengeInfo; -} - -namespace android { - -class WebFrame; -class WebRequest; -class WebRequestContext; - -// This class handles communication between the IO thread where loading happens -// and the webkit main thread. -// TODO: -// - Implement didFail -// - Implement sync requests -// - Implement downloadFile -// - Implement pauseLoad -class WebUrlLoaderClient : public base::RefCountedThreadSafe<WebUrlLoaderClient> { -public: - WebUrlLoaderClient(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); - - // Called from WebCore, will be forwarded to the IO thread - bool start(bool isMainResource, bool isMainFrame, bool sync, WebRequestContext*); - void cancel(); - void downloadFile(); - void pauseLoad(bool pause); - void setAuth(const std::string& username, const std::string& password); - void cancelAuth(); - void proceedSslCertError(); - void cancelSslCertError(int cert_error); - - typedef void CallbackFunction(void*); - - // This is called from the IO thread, and dispatches the callback to the main thread. - // (For asynchronous calls, we just delegate to WebKit's callOnMainThread.) - void maybeCallOnMainThread(Task* task); - - // Called by WebRequest (using maybeCallOnMainThread), should be forwarded to WebCore. - void didReceiveResponse(PassOwnPtr<WebResponse>); - void didReceiveData(scoped_refptr<net::IOBuffer>, int size); - void didReceiveDataUrl(PassOwnPtr<std::string>); - void didReceiveAndroidFileData(PassOwnPtr<std::vector<char> >); - void didFinishLoading(); - void didFail(PassOwnPtr<WebResponse>); - void willSendRequest(PassOwnPtr<WebResponse>); - void authRequired(scoped_refptr<net::AuthChallengeInfo>, bool firstTime); - void reportSslCertError(int cert_error, net::X509Certificate* cert); - - // Handle to the chrome IO thread - static base::Thread* ioThread(); - -private: - friend class base::RefCountedThreadSafe<WebUrlLoaderClient>; - virtual ~WebUrlLoaderClient(); - - void finish(); - - WebFrame* m_webFrame; - RefPtr<WebCore::ResourceHandle> m_resourceHandle; - bool m_isMainResource; - bool m_isMainFrame; - bool m_isCertMimeType; - bool m_cancelling; - bool m_sync; - volatile bool m_finished; - - scoped_refptr<WebRequest> m_request; - OwnPtr<WebResponse> m_response; // NULL until didReceiveResponse is called. - - // Check if a request is active - bool isActive() const; - - // Mutex and condition variable used for synchronous requests. - // Note that these are static. This works because there's only one main thread. - static Lock* syncLock(); - static ConditionVariable* syncCondition(); - - // Queue of callbacks to be executed by the main thread. Must only be accessed inside mutex. - std::deque<Task*> m_queue; -}; - -} // namespace android - -#endif diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.cpp b/WebKit/android/WebCoreSupport/WebViewClientError.cpp deleted file mode 100644 index 59542da..0000000 --- a/WebKit/android/WebCoreSupport/WebViewClientError.cpp +++ /dev/null @@ -1,132 +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. - */ - -#include "config.h" -#include "WebViewClientError.h" - -using namespace net; - -namespace android { - -WebViewClientError ToWebViewClientError(net::Error error) { - // Note: many net::Error constants don't have an obvious mapping. - // These will be handled by the default case, ERROR_UNKNOWN. - switch(error) { - case ERR_UNSUPPORTED_AUTH_SCHEME: - return ERROR_UNSUPPORTED_AUTH_SCHEME; - - case ERR_INVALID_AUTH_CREDENTIALS: - case ERR_MISSING_AUTH_CREDENTIALS: - case ERR_MISCONFIGURED_AUTH_ENVIRONMENT: - return ERROR_AUTHENTICATION; - - case ERR_TOO_MANY_REDIRECTS: - return ERROR_REDIRECT_LOOP; - - case ERR_UPLOAD_FILE_CHANGED: - return ERROR_FILE_NOT_FOUND; - - case ERR_INVALID_URL: - return ERROR_BAD_URL; - - case ERR_DISALLOWED_URL_SCHEME: - case ERR_UNKNOWN_URL_SCHEME: - return ERROR_UNSUPPORTED_SCHEME; - - case ERR_IO_PENDING: - case ERR_NETWORK_IO_SUSPENDED: - return ERROR_IO; - - case ERR_CONNECTION_TIMED_OUT: - case ERR_TIMED_OUT: - return ERROR_TIMEOUT; - - case ERR_FILE_TOO_BIG: - return ERROR_FILE; - - case ERR_HOST_RESOLVER_QUEUE_TOO_LARGE: - case ERR_INSUFFICIENT_RESOURCES: - case ERR_OUT_OF_MEMORY: - return ERROR_TOO_MANY_REQUESTS; - - case ERR_CONNECTION_CLOSED: - case ERR_CONNECTION_RESET: - case ERR_CONNECTION_REFUSED: - case ERR_CONNECTION_ABORTED: - case ERR_CONNECTION_FAILED: - case ERR_SOCKET_NOT_CONNECTED: - return ERROR_CONNECT; - - case ERR_ADDRESS_INVALID: - case ERR_ADDRESS_UNREACHABLE: - case ERR_NAME_NOT_RESOLVED: - case ERR_NAME_RESOLUTION_FAILED: - return ERROR_HOST_LOOKUP; - - case ERR_SSL_PROTOCOL_ERROR: - case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: - case ERR_TUNNEL_CONNECTION_FAILED: - case ERR_NO_SSL_VERSIONS_ENABLED: - case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: - case ERR_SSL_RENEGOTIATION_REQUESTED: - case ERR_CERT_ERROR_IN_SSL_RENEGOTIATION: - case ERR_BAD_SSL_CLIENT_AUTH_CERT: - case ERR_SSL_NO_RENEGOTIATION: - case ERR_SSL_DECOMPRESSION_FAILURE_ALERT: - case ERR_SSL_BAD_RECORD_MAC_ALERT: - case ERR_SSL_UNSAFE_NEGOTIATION: - case ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: - case ERR_SSL_SNAP_START_NPN_MISPREDICTION: - case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: - case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: - return ERROR_FAILED_SSL_HANDSHAKE; - - case ERR_PROXY_AUTH_UNSUPPORTED: - case ERR_PROXY_AUTH_REQUESTED: - case ERR_PROXY_CONNECTION_FAILED: - case ERR_UNEXPECTED_PROXY_AUTH: - return ERROR_PROXY_AUTHENTICATION; - - /* The certificate errors are handled by their own dialog - * and don't need to be reported to the framework again. - */ - case ERR_CERT_COMMON_NAME_INVALID: - case ERR_CERT_DATE_INVALID: - case ERR_CERT_AUTHORITY_INVALID: - case ERR_CERT_CONTAINS_ERRORS: - case ERR_CERT_NO_REVOCATION_MECHANISM: - case ERR_CERT_UNABLE_TO_CHECK_REVOCATION: - case ERR_CERT_REVOKED: - case ERR_CERT_INVALID: - case ERR_CERT_WEAK_SIGNATURE_ALGORITHM: - case ERR_CERT_NOT_IN_DNS: - return ERROR_OK; - - default: - return ERROR_UNKNOWN; - } -} - -} diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.h b/WebKit/android/WebCoreSupport/WebViewClientError.h deleted file mode 100644 index d274dc7..0000000 --- a/WebKit/android/WebCoreSupport/WebViewClientError.h +++ /dev/null @@ -1,74 +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 WebViewClientError_h -#define WebViewClientError_h - -#include "ChromiumIncludes.h" - -namespace android { - -// This enum must be kept in sync with WebViewClient.java -enum WebViewClientError { - /** Success */ - ERROR_OK = 0, - /** Generic error */ - ERROR_UNKNOWN = -1, - /** Server or proxy hostname lookup failed */ - ERROR_HOST_LOOKUP = -2, - /** Unsupported authentication scheme (not basic or digest) */ - ERROR_UNSUPPORTED_AUTH_SCHEME = -3, - /** User authentication failed on server */ - ERROR_AUTHENTICATION = -4, - /** User authentication failed on proxy */ - ERROR_PROXY_AUTHENTICATION = -5, - /** Failed to connect to the server */ - ERROR_CONNECT = -6, - /** Failed to read or write to the server */ - ERROR_IO = -7, - /** Connection timed out */ - ERROR_TIMEOUT = -8, - /** Too many redirects */ - ERROR_REDIRECT_LOOP = -9, - /** Unsupported URI scheme */ - ERROR_UNSUPPORTED_SCHEME = -10, - /** Failed to perform SSL handshake */ - ERROR_FAILED_SSL_HANDSHAKE = -11, - /** Malformed URL */ - ERROR_BAD_URL = -12, - /** Generic file error */ - ERROR_FILE = -13, - /** File not found */ - ERROR_FILE_NOT_FOUND = -14, - /** Too many requests during this load */ - ERROR_TOO_MANY_REQUESTS = -15, -}; - -// Get the closest WebViewClient match to the given Chrome error code. -WebViewClientError ToWebViewClientError(net::Error); - -} // namespace android - -#endif // WebViewClientError_h diff --git a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp deleted file mode 100644 index 5bc4c92..0000000 --- a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp +++ /dev/null @@ -1,51 +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. - */ - -#include "config.h" -#include "AutoFillHostAndroid.h" - -#include "autofill/WebAutoFill.h" - -namespace android { - -AutoFillHostAndroid::AutoFillHostAndroid(WebAutoFill* autoFill) - : mAutoFill(autoFill) -{ -} - -void AutoFillHostAndroid::AutoFillSuggestionsReturned(const std::vector<string16>& names, const std::vector<string16>& labels, const std::vector<string16>& icons, const std::vector<int>& uniqueIds) -{ - // TODO: what do we do with icons? - if (mAutoFill) - mAutoFill->querySuccessful(names[0], labels[0], uniqueIds[0]); -} - -void AutoFillHostAndroid::AutoFillFormDataFilled(int queryId, const webkit_glue::FormData& form) -{ - if (mAutoFill) - mAutoFill->fillFormInPage(queryId, form); -} - -} diff --git a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h deleted file mode 100644 index 9677b46..0000000 --- a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h +++ /dev/null @@ -1,54 +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 AutoFillHostAndroid_h -#define AutoFillHostAndroid_h - -#include "ChromiumIncludes.h" - -#include <vector> - -namespace webkit_glue { -class FormData; -} - -namespace android { -class WebAutoFill; - -// This class receives the callbacks from the AutoFillManager in the Chromium code. -class AutoFillHostAndroid : public AutoFillHost { -public: - AutoFillHostAndroid(WebAutoFill* autoFill); - virtual ~AutoFillHostAndroid() { } - - virtual void AutoFillSuggestionsReturned(const std::vector<string16>& names, const std::vector<string16>& labels, const std::vector<string16>& icons, const std::vector<int>& uniqueIds); - virtual void AutoFillFormDataFilled(int queryId, const webkit_glue::FormData&); - -private: - WebAutoFill* mAutoFill; -}; -} - -#endif diff --git a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp deleted file mode 100644 index 6af0875..0000000 --- a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2010 The Chromium Authors. All rights reserved. - * 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. - */ - -#include "config.h" -#include "FormFieldAndroid.h" - -#include "ChromiumIncludes.h" -#include "Element.h" -#include "HTMLFormControlElement.h" -#include "HTMLInputElement.h" -#include "HTMLNames.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "StringUtils.h" -#include <wtf/Vector.h> - -using WebCore::Element; -using WebCore::HTMLFormControlElement; -using WebCore::HTMLInputElement; -using WebCore::HTMLOptionElement; -using WebCore::HTMLSelectElement; - -using namespace WebCore::HTMLNames; - -// TODO: This file is taken from chromium/webkit/glue/form_field.cc and -// customised to use WebCore types rather than WebKit API types. It would -// be nice and would ease future merge pain if the two could be combined. - -namespace webkit_glue { - -FormField::FormField() - : max_length_(0), - is_autofilled_(false) { -} - -// TODO: This constructor should probably be deprecated and the -// functionality moved to FormManager. -FormField::FormField(const HTMLFormControlElement& element) - : max_length_(0), - is_autofilled_(false) { - name_ = nameForAutoFill(element); - - // TODO: Extract the field label. For now we just use the field - // name. - label_ = name_; - - form_control_type_ = formControlType(element); - if (form_control_type_ == kText) { - const HTMLInputElement& input_element = static_cast<const HTMLInputElement&>(element); - value_ = WTFStringToString16(input_element.value()); - max_length_ = input_element.size(); - is_autofilled_ = input_element.isAutofilled(); - } else if (form_control_type_ == kSelectOne) { - const HTMLSelectElement& const_select_element = static_cast<const HTMLSelectElement&>(element); - HTMLSelectElement& select_element = const_cast<HTMLSelectElement&>(const_select_element); - value_ = WTFStringToString16(select_element.value()); - - // For select-one elements copy option strings. - WTF::Vector<Element*> list_items = select_element.listItems(); - option_strings_.reserve(list_items.size()); - for (size_t i = 0; i < list_items.size(); ++i) { - if (list_items[i]->hasTagName(optionTag)) - option_strings_.push_back(WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value())); - } - } - - TrimWhitespace(value_, TRIM_LEADING, &value_); -} - -FormField::FormField(const string16& label, const string16& name, const string16& value, const string16& form_control_type, int max_length, bool is_autofilled) - : label_(label), - name_(name), - value_(value), - form_control_type_(form_control_type), - max_length_(max_length), - is_autofilled_(is_autofilled) { -} - -FormField::~FormField() { -} - -bool FormField::operator==(const FormField& field) const { - // A FormField stores a value, but the value is not part of the identity of - // the field, so we don't want to compare the values. - return (label_ == field.label_ && - name_ == field.name_ && - form_control_type_ == field.form_control_type_ && - max_length_ == field.max_length_); -} - -bool FormField::operator!=(const FormField& field) const { - return !operator==(field); -} - -bool FormField::StrictlyEqualsHack(const FormField& field) const { - return (label_ == field.label_ && - name_ == field.name_ && - value_ == field.value_ && - form_control_type_ == field.form_control_type_ && - max_length_ == field.max_length_); -} - -std::ostream& operator<<(std::ostream& os, const FormField& field) { - return os - << UTF16ToUTF8(field.label()) - << " " - << UTF16ToUTF8(field.name()) - << " " - << UTF16ToUTF8(field.value()) - << " " - << UTF16ToUTF8(field.form_control_type()) - << " " - << field.max_length(); -} - -} // namespace webkit_glue diff --git a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h deleted file mode 100644 index c5e3ecc..0000000 --- a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010 The Chromium Authors. All rights reserved. - * 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 FormFieldAndroid_h -#define FormFieldAndroid_h - -#include <base/string16.h> -#include <vector> - -// TODO: This file is taken from chromium/webkit/glue/form_field.h and -// customised to use WebCore types rather than WebKit API types. It would -// be nice and would ease future merge pain if the two could be combined. - -namespace WebCore { -class HTMLFormControlElement; -} - -namespace webkit_glue { - -// Stores information about a field in a form. -class FormField { -public: - FormField(); - explicit FormField(const WebCore::HTMLFormControlElement& element); - FormField(const string16& label, const string16& name, const string16& value, const string16& form_control_type, int max_length, bool is_autofilled); - virtual ~FormField(); - - const string16& label() const { return label_; } - const string16& name() const { return name_; } - const string16& value() const { return value_; } - const string16& form_control_type() const { return form_control_type_; } - int max_length() const { return max_length_; } - bool is_autofilled() const { return is_autofilled_; } - - // Returns option string for elements for which they make sense (select-one, - // for example) for the rest of elements return an empty array. - const std::vector<string16>& option_strings() const { return option_strings_; } - - void set_label(const string16& label) { label_ = label; } - void set_name(const string16& name) { name_ = name; } - void set_value(const string16& value) { value_ = value; } - void set_form_control_type(const string16& form_control_type) { form_control_type_ = form_control_type; } - void set_max_length(int max_length) { max_length_ = max_length; } - void set_autofilled(bool is_autofilled) { is_autofilled_ = is_autofilled; } - void set_option_strings(const std::vector<string16>& strings) { option_strings_ = strings; } - - // Equality tests for identity which does not include |value_| or |size_|. - // Use |StrictlyEqualsHack| method to test all members. - // TODO: These operators need to be revised when we implement field - // ids. - bool operator==(const FormField& field) const; - bool operator!=(const FormField& field) const; - - // Test equality of all data members. - // TODO: This will be removed when we implement field ids. - bool StrictlyEqualsHack(const FormField& field) const; - -private: - string16 label_; - string16 name_; - string16 value_; - string16 form_control_type_; - int max_length_; - bool is_autofilled_; - std::vector<string16> option_strings_; -}; - -// So we can compare FormFields with EXPECT_EQ(). -std::ostream& operator<<(std::ostream& os, const FormField& field); - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_FORM_FIELD_H_ diff --git a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp deleted file mode 100644 index 9652794..0000000 --- a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (c) 2010 The Chromium Authors. All rights reserved. - * 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. - */ - -#include "config.h" -#include "FormManagerAndroid.h" - -#include "DocumentLoader.h" -#include "Element.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "HTMLCollection.h" -#include "HTMLFormControlElement.h" -#include "HTMLFormElement.h" -#include "HTMLInputElement.h" -#include "HTMLLabelElement.h" -#include "HTMLNames.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "Node.h" -#include "NodeList.h" -#include "HTMLCollection.h" -#include "FormAssociatedElement.h" -#include "FormFieldAndroid.h" -#include "QualifiedName.h" -#include "StringUtils.h" - -// TODO: This file is taken from chromium/chrome/renderer/form_manager.cc and -// customised to use WebCore types rather than WebKit API types. It would be -// nice and would ease future merge pain if the two could be combined. - -using webkit_glue::FormData; -using webkit_glue::FormField; -using WebCore::Element; -using WebCore::FormAssociatedElement; -using WebCore::HTMLCollection; -using WebCore::HTMLElement; -using WebCore::HTMLFormControlElement; -using WebCore::HTMLFormElement; -using WebCore::HTMLInputElement; -using WebCore::HTMLLabelElement; -using WebCore::HTMLOptionElement; -using WebCore::HTMLSelectElement; -using WebCore::Node; -using WebCore::NodeList; - -using namespace WebCore::HTMLNames; - -namespace { - -// The number of fields required by AutoFill. Ideally we could send the forms -// to AutoFill no matter how many fields are in the forms; however, finding the -// label for each field is a costly operation and we can't spare the cycles if -// it's not necessary. -// Note the on ANDROID we reduce this from Chromium's 3 as it allows us to -// autofill simple name/email forms for example. This improves the mobile -// device experience where form filling can be time consuming and frustrating. -const size_t kRequiredAutoFillFields = 2; - -// The maximum length allowed for form data. -const size_t kMaxDataLength = 1024; - -// This is a helper function for the FindChildText() function. -// Returns the aggregated values of the descendants or siblings of |node| that -// are non-empty text nodes. This is a faster alternative to |innerText()| for -// performance critical operations. It does a full depth-first search so -// can be used when the structure is not directly known. The text is -// accumulated after the whitespace has been stropped. Search depth is limited -// with the |depth| parameter. -string16 FindChildTextInner(Node* node, int depth) { - string16 element_text; - if (!node || depth <= 0) - return element_text; - - string16 node_text = WTFStringToString16(node->nodeValue()); - TrimWhitespace(node_text, TRIM_ALL, &node_text); - if (!node_text.empty()) - element_text = node_text; - - string16 child_text = FindChildTextInner(node->firstChild(), depth-1); - if (!child_text.empty()) - element_text = element_text + child_text; - - string16 sibling_text = FindChildTextInner(node->nextSibling(), depth-1); - if (!sibling_text.empty()) - element_text = element_text + sibling_text; - - return element_text; -} - -// Returns the node value of the first decendant of |element| that is a -// non-empty text node. "Non-empty" in this case means non-empty after the -// whitespace has been stripped. Search is limited to withing 10 siblings and/or -// descendants. -string16 FindChildText(Element* element) { - Node* child = element->firstChild(); - - const int kChildSearchDepth = 10; - return FindChildTextInner(child, kChildSearchDepth); -} - -string16 InferLabelFromPrevious(const HTMLFormControlElement& element) { - string16 inferred_label; - Node* previous = element.previousSibling(); - if (!previous) - return string16(); - - if (previous->isTextNode()) { - inferred_label = WTFStringToString16(previous->nodeValue()); - TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); - } - - // If we didn't find text, check for previous paragraph. - // Eg. <p>Some Text</p><input ...> - // Note the lack of whitespace between <p> and <input> elements. - if (inferred_label.empty() && previous->isElementNode()) { - Element* element = static_cast<Element*>(previous); - if (element->hasTagName(pTag)) - inferred_label = FindChildText(element); - } - - // If we didn't find paragraph, check for previous paragraph to this. - // Eg. <p>Some Text</p> <input ...> - // Note the whitespace between <p> and <input> elements. - if (inferred_label.empty()) { - Node* sibling = previous->previousSibling(); - if (sibling && sibling->isElementNode()) { - Element* element = static_cast<Element*>(sibling); - if (element->hasTagName(pTag)) - inferred_label = FindChildText(element); - } - } - - // Look for text node prior to <img> tag. - // Eg. Some Text<img/><input ...> - if (inferred_label.empty()) { - while (inferred_label.empty() && previous) { - if (previous->isTextNode()) { - inferred_label = WTFStringToString16(previous->nodeValue()); - TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); - } else if (previous->isElementNode()) { - Element* element = static_cast<Element*>(previous); - if (!element->hasTagName(imgTag)) - break; - } else - break; - previous = previous->previousSibling(); - } - } - - // Look for label node prior to <input> tag. - // Eg. <label>Some Text</label><input ...> - if (inferred_label.empty()) { - while (inferred_label.empty() && previous) { - if (previous->isTextNode()) { - inferred_label = WTFStringToString16(previous->nodeValue()); - TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); - } else if (previous->isElementNode()) { - Element* element = static_cast<Element*>(previous); - if (element->hasTagName(labelTag)) { - inferred_label = FindChildText(element); - } else { - break; - } - } else { - break; - } - - previous = previous->previousSibling(); - } - } - - return inferred_label; -} - -// Helper for |InferLabelForElement()| that infers a label, if possible, from -// surrounding table structure. -// Eg. <tr><td>Some Text</td><td><input ...></td></tr> -// Eg. <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> -string16 InferLabelFromTable(const HTMLFormControlElement& element) { - string16 inferred_label; - Node* parent = element.parentNode(); - while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(tdTag)) - parent = parent->parentNode(); - - // Check all previous siblings, skipping non-element nodes, until we find a - // non-empty text block. - Node* previous = parent; - while(previous) { - if (previous->isElementNode()) { - Element* e = static_cast<Element*>(previous); - if (e->hasTagName(tdTag)) { - inferred_label = FindChildText(e); - if (!inferred_label.empty()) - break; - } - } - previous = previous->previousSibling(); - } - return inferred_label; -} - -// Helper for |InferLabelForElement()| that infers a label, if possible, from -// a surrounding div table. -// Eg. <div>Some Text<span><input ...></span></div> -string16 InferLabelFromDivTable(const HTMLFormControlElement& element) { - Node* parent = element.parentNode(); - while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(divTag)) - parent = parent->parentNode(); - - if (!parent || !parent->isElementNode()) - return string16(); - - Element* e = static_cast<Element*>(parent); - if (!e || !e->hasTagName(divTag)) - return string16(); - - return FindChildText(e); -} - -// Helper for |InferLabelForElement()| that infers a label, if possible, from -// a surrounding definition list. -// Eg. <dl><dt>Some Text</dt><dd><input ...></dd></dl> -// Eg. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> -string16 InferLabelFromDefinitionList(const HTMLFormControlElement& element) { - string16 inferred_label; - Node* parent = element.parentNode(); - while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(ddTag)) - parent = parent->parentNode(); - - if (parent && parent->isElementNode()) { - Element* element = static_cast<Element*>(parent); - if (element->hasTagName(ddTag)) { - Node* previous = parent->previousSibling(); - - // Skip by any intervening text nodes. - while (previous && previous->isTextNode()) - previous = previous->previousSibling(); - - if (previous && previous->isElementNode()) { - element = static_cast<Element*>(previous); - if (element->hasTagName(dtTag)) - inferred_label = FindChildText(element); - } - } - } - return inferred_label; -} - -void GetOptionStringsFromElement(HTMLFormControlElement* element, std::vector<string16>* option_strings) { - DCHECK(element); - DCHECK(option_strings); - option_strings->clear(); - if (formControlType(*element) == kSelectOne) { - HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); - - // For select-one elements copy option strings. - WTF::Vector<Element*> list_items = select_element->listItems(); - option_strings->reserve(list_items.size()); - for (size_t i = 0; i < list_items.size(); ++i) { - if (list_items[i]->hasTagName(optionTag)) - option_strings->push_back(WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value())); - } - } -} - -} // namespace - -namespace android { - -struct FormManager::FormElement { - RefPtr<HTMLFormElement> form_element; - std::vector<RefPtr<HTMLFormControlElement> > control_elements; - std::vector<string16> control_values; -}; - -FormManager::FormManager() { -} - -FormManager::~FormManager() { - Reset(); -} - -// static -void FormManager::HTMLFormControlElementToFormField(HTMLFormControlElement* element, ExtractMask extract_mask, FormField* field) { - DCHECK(field); - - // The label is not officially part of a HTMLFormControlElement; however, the - // labels for all form control elements are scraped from the DOM and set in - // WebFormElementToFormData. - field->set_name(nameForAutoFill(*element)); - field->set_form_control_type(formControlType(*element)); - - if (extract_mask & EXTRACT_OPTIONS) { - std::vector<string16> option_strings; - GetOptionStringsFromElement(element, &option_strings); - field->set_option_strings(option_strings); - } - - if (formControlType(*element) == kText) { - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - field->set_max_length(input_element->maxLength()); - field->set_autofilled(input_element->isAutofilled()); - } - - if (!(extract_mask & EXTRACT_VALUE)) - return; - - // TODO: In WebKit, move value() and setValue() to - // WebFormControlElement. - string16 value; - if (formControlType(*element) == kText || - formControlType(*element) == kHidden) { - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - value = WTFStringToString16(input_element->value()); - } else if (formControlType(*element) == kSelectOne) { - HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); - value = WTFStringToString16(select_element->value()); - - // Convert the |select_element| value to text if requested. - if (extract_mask & EXTRACT_OPTION_TEXT) { - Vector<Element*> list_items = select_element->listItems(); - for (size_t i = 0; i < list_items.size(); ++i) { - if (list_items[i]->hasTagName(optionTag) && - WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value()) == value) { - value = WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->text()); - break; - } - } - } - } - - // TODO: This is a temporary stop-gap measure designed to prevent - // a malicious site from DOS'ing the browser with extremely large profile - // data. The correct solution is to parse this data asynchronously. - // See http://crbug.com/49332. - if (value.size() > kMaxDataLength) - value = value.substr(0, kMaxDataLength); - - field->set_value(value); -} - -// static -string16 FormManager::LabelForElement(const HTMLFormControlElement& element) { - // Don't scrape labels for hidden elements. - if (formControlType(element) == kHidden) - return string16(); - - RefPtr<NodeList> labels = element.document()->getElementsByTagName("label"); - for (unsigned i = 0; i < labels->length(); ++i) { - Node* e = labels->item(i); - if (e->hasTagName(labelTag)) { - HTMLLabelElement* label = static_cast<HTMLLabelElement*>(e); - if (label->control() == &element) - return FindChildText(label); - } - } - - // Infer the label from context if not found in label element. - return FormManager::InferLabelForElement(element); -} - -// static -bool FormManager::HTMLFormElementToFormData(HTMLFormElement* element, RequirementsMask requirements, ExtractMask extract_mask, FormData* form) { - DCHECK(form); - - Frame* frame = element->document()->frame(); - if (!frame) - return false; - - if (requirements & REQUIRE_AUTOCOMPLETE && !element->autoComplete()) - return false; - - form->name = WTFStringToString16(element->name()); - form->method = WTFStringToString16(element->method()); - form->origin = GURL(WTFStringToString16(frame->loader()->documentLoader()->url().string())); - form->action = GURL(WTFStringToString16(frame->document()->completeURL(element->action()))); - form->user_submitted = element->wasUserSubmitted(); - - // If the completed URL is not valid, just use the action we get from - // WebKit. - if (!form->action.is_valid()) - form->action = GURL(WTFStringToString16(element->action())); - - // A map from a FormField's name to the FormField itself. - std::map<string16, FormField*> name_map; - - // The extracted FormFields. We use pointers so we can store them in - // |name_map|. - ScopedVector<FormField> form_fields; - - WTF::Vector<WebCore::FormAssociatedElement*> control_elements = element->associatedElements(); - - // A vector of bools that indicate whether each field in the form meets the - // requirements and thus will be in the resulting |form|. - std::vector<bool> fields_extracted(control_elements.size(), false); - - for (size_t i = 0; i < control_elements.size(); ++i) { - if (!control_elements[i]->isFormControlElement()) - continue; - - HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]); - if (!(control_element->hasTagName(inputTag) || control_element->hasTagName(selectTag))) - continue; - - if (requirements & REQUIRE_AUTOCOMPLETE && - formControlType(*control_element) == kText) { - const WebCore::HTMLInputElement* input_element = static_cast<const WebCore::HTMLInputElement*>(control_element); - if (!input_element->autoComplete()) - continue; - } - - if (requirements & REQUIRE_ENABLED && !control_element->isEnabledFormControl()) - continue; - - // Create a new FormField, fill it out and map it to the field's name. - FormField* field = new FormField; - HTMLFormControlElementToFormField(control_element, extract_mask, field); - form_fields.push_back(field); - // TODO: A label element is mapped to a form control element's id. - // field->name() will contain the id only if the name does not exist. Add - // an id() method to HTMLFormControlElement and use that here. - name_map[field->name()] = field; - fields_extracted[i] = true; - } - - // Don't extract field labels if we have no fields. - if (form_fields.empty()) - return false; - - // Loop through the label elements inside the form element. For each label - // element, get the corresponding form control element, use the form control - // element's name as a key into the <name, FormField> map to find the - // previously created FormField and set the FormField's label to the - // label.firstChild().nodeValue() of the label element. - RefPtr<WebCore::NodeList> labels = element->getElementsByTagName("label"); - for (unsigned i = 0; i < labels->length(); ++i) { - HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(labels->item(i)); - HTMLFormControlElement* field_element = label->control(); - if (!field_element || field_element->type() == "hidden") - continue; - - std::map<string16, FormField*>::iterator iter = - name_map.find(nameForAutoFill(*field_element)); - if (iter != name_map.end()) - iter->second->set_label(FindChildText(label)); - } - - // Loop through the form control elements, extracting the label text from the - // DOM. We use the |fields_extracted| vector to make sure we assign the - // extracted label to the correct field, as it's possible |form_fields| will - // not contain all of the elements in |control_elements|. - for (size_t i = 0, field_idx = 0; i < control_elements.size() && field_idx < form_fields.size(); ++i) { - // This field didn't meet the requirements, so don't try to find a label for - // it. - if (!fields_extracted[i]) - continue; - - if (!control_elements[i]->isFormControlElement()) - continue; - - const HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]); - if (form_fields[field_idx]->label().empty()) - form_fields[field_idx]->set_label(FormManager::InferLabelForElement(*control_element)); - - ++field_idx; - - } - // Copy the created FormFields into the resulting FormData object. - for (ScopedVector<FormField>::const_iterator iter = form_fields.begin(); iter != form_fields.end(); ++iter) - form->fields.push_back(**iter); - - return true; -} - -void FormManager::ExtractForms(Frame* frame) { - - ResetFrame(frame); - - WTF::PassRefPtr<HTMLCollection> web_forms = frame->document()->forms(); - - for (size_t i = 0; i < web_forms->length(); ++i) { - FormElement* form_element = new FormElement; - HTMLFormElement* html_form_element = static_cast<HTMLFormElement*>(web_forms->item(i)); - form_element->form_element = html_form_element; - - WTF::Vector<FormAssociatedElement*> control_elements = html_form_element->associatedElements(); - for (size_t j = 0; j < control_elements.size(); ++j) { - if (!control_elements[j]->isFormControlElement()) - continue; - - HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(control_elements[j]); - form_element->control_elements.push_back(element); - - // Save original values of "select-one" inputs so we can restore them - // when |ClearFormWithNode()| is invoked. - if (formControlType(*element) == kSelectOne) { - HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); - string16 value = WTFStringToString16(select_element->value()); - form_element->control_values.push_back(value); - } else - form_element->control_values.push_back(string16()); - } - - form_elements_.push_back(form_element); - } -} - -void FormManager::GetFormsInFrame(const Frame* frame, RequirementsMask requirements, std::vector<FormData>* forms) { - DCHECK(frame); - DCHECK(forms); - - for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { - FormElement* form_element = *form_iter; - - if (form_element->form_element->document()->frame() != frame) - continue; - - // We need at least |kRequiredAutoFillFields| fields before appending this - // form to |forms|. - if (form_element->control_elements.size() < kRequiredAutoFillFields) - continue; - - if (requirements & REQUIRE_AUTOCOMPLETE && !form_element->form_element->autoComplete()) - continue; - - FormData form; - HTMLFormElementToFormData(form_element->form_element.get(), requirements, EXTRACT_VALUE, &form); - if (form.fields.size() >= kRequiredAutoFillFields) - forms->push_back(form); - } -} - -bool FormManager::FindFormWithFormControlElement(HTMLFormControlElement* element, RequirementsMask requirements, FormData* form) { - DCHECK(form); - - const Frame* frame = element->document()->frame(); - if (!frame) - return false; - - for (FormElementList::const_iterator iter = form_elements_.begin(); iter != form_elements_.end(); ++iter) { - const FormElement* form_element = *iter; - - if (form_element->form_element->document()->frame() != frame) - continue; - - for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = form_element->control_elements.begin(); iter != form_element->control_elements.end(); ++iter) { - HTMLFormControlElement* candidate = iter->get(); - if (nameForAutoFill(*candidate) == nameForAutoFill(*element)) { - ExtractMask extract_mask = static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); - return HTMLFormElementToFormData(form_element->form_element.get(), requirements, extract_mask, form); - } - } - } - return false; -} - -bool FormManager::FillForm(const FormData& form, Node* node) { - FormElement* form_element = NULL; - if (!FindCachedFormElement(form, &form_element)) - return false; - - RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY); - ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::FillFormField)); - - return true; -} - -bool FormManager::PreviewForm(const FormData& form, Node* node) { - FormElement* form_element = NULL; - if (!FindCachedFormElement(form, &form_element)) - return false; - - RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY); - ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::PreviewFormField)); - - return true; -} - -bool FormManager::ClearFormWithNode(Node* node) { - FormElement* form_element = NULL; - if (!FindCachedFormElementWithNode(node, &form_element)) - return false; - - for (size_t i = 0; i < form_element->control_elements.size(); ++i) { - HTMLFormControlElement* element = form_element->control_elements[i].get(); - if (formControlType(*element) == kText) { - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - - // We don't modify the value of disabled fields. - if (!input_element->isEnabledFormControl()) - continue; - - input_element->setValue(""); - input_element->setAutofilled(false); - // Clearing the value in the focused node (above) can cause selection - // to be lost. We force selection range to restore the text cursor. - if (node == input_element) { - int length = input_element->value().length(); - input_element->setSelectionRange(length, length); - } - } else if (formControlType(*element) == kSelectOne) { - HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); - select_element->setValue(form_element->control_values[i].c_str()); - } - } - - return true; -} - -bool FormManager::ClearPreviewedFormWithNode(Node* node, bool was_autofilled) { - FormElement* form_element = NULL; - if (!FindCachedFormElementWithNode(node, &form_element)) - return false; - - for (size_t i = 0; i < form_element->control_elements.size(); ++i) { - HTMLFormControlElement* element = form_element->control_elements[i].get(); - - // Only input elements can be previewed. - if (formControlType(*element) != kText) - continue; - - // If the input element has not been auto-filled, FormManager has not - // previewed this field, so we have nothing to reset. - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - if (!input_element->isAutofilled()) - continue; - - // There might be unrelated elements in this form which have already been - // auto-filled. For example, the user might have already filled the address - // part of a form and now be dealing with the credit card section. We only - // want to reset the auto-filled status for fields that were previewed. - if (input_element->suggestedValue().isEmpty()) - continue; - - // Clear the suggested value. For the initiating node, also restore the - // original value. - input_element->setSuggestedValue(""); - bool is_initiating_node = (node == input_element); - if (is_initiating_node) { - // Call |setValue()| to force the renderer to update the field's displayed - // value. - input_element->setValue(input_element->value()); - input_element->setAutofilled(was_autofilled); - } else { - input_element->setAutofilled(false); - } - - // Clearing the suggested value in the focused node (above) can cause - // selection to be lost. We force selection range to restore the text - // cursor. - if (is_initiating_node) { - int length = input_element->value().length(); - input_element->setSelectionRange(length, length); - } - } - - return true; -} - -void FormManager::Reset() { - STLDeleteElements(&form_elements_); -} - -void FormManager::ResetFrame(const Frame* frame) { - FormElementList::iterator iter = form_elements_.begin(); - while (iter != form_elements_.end()) { - if ((*iter)->form_element->document()->frame() == frame) { - delete *iter; - iter = form_elements_.erase(iter); - } else - ++iter; - } -} - -bool FormManager::FormWithNodeIsAutoFilled(Node* node) { - FormElement* form_element = NULL; - if (!FindCachedFormElementWithNode(node, &form_element)) - return false; - - for (size_t i = 0; i < form_element->control_elements.size(); ++i) { - HTMLFormControlElement* element = form_element->control_elements[i].get(); - if (formControlType(*element) != kText) - continue; - - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - if (input_element->isAutofilled()) - return true; - } - - return false; -} - -// static -string16 FormManager::InferLabelForElement(const HTMLFormControlElement& element) { - // Don't scrape labels for hidden elements. - if (formControlType(element) == kHidden) - return string16(); - - string16 inferred_label = InferLabelFromPrevious(element); - - // If we didn't find a label, check for table cell case. - if (inferred_label.empty()) - inferred_label = InferLabelFromTable(element); - - // If we didn't find a label, check for div table case. - if (inferred_label.empty()) - inferred_label = InferLabelFromDivTable(element); - - // If we didn't find a label, check for definition list case. - if (inferred_label.empty()) - inferred_label = InferLabelFromDefinitionList(element); - - return inferred_label; -} - -bool FormManager::FindCachedFormElementWithNode(Node* node, - FormElement** form_element) { - for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { - for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = (*form_iter)->control_elements.begin(); iter != (*form_iter)->control_elements.end(); ++iter) { - if (iter->get() == node) { - *form_element = *form_iter; - return true; - } - } - } - - return false; -} - -bool FormManager::FindCachedFormElement(const FormData& form, FormElement** form_element) { - for (FormElementList::iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { - // TODO: matching on form name here which is not guaranteed to - // be unique for the page, nor is it guaranteed to be non-empty. Need to - // find a way to uniquely identify the form cross-process. For now we'll - // check form name and form action for identity. - // http://crbug.com/37990 test file sample8.html. - // Also note that WebString() == WebString(string16()) does not seem to - // evaluate to |true| for some reason TBD, so forcing to string16. - string16 element_name(WTFStringToString16((*form_iter)->form_element->name())); - GURL action(WTFStringToString16((*form_iter)->form_element->document()->completeURL((*form_iter)->form_element->action()).string())); - if (element_name == form.name && action == form.action) { - *form_element = *form_iter; - return true; - } - } - - return false; -} - - -void FormManager::ForEachMatchingFormField(FormElement* form, Node* node, RequirementsMask requirements, const FormData& data, Callback* callback) { - // It's possible that the site has injected fields into the form after the - // page has loaded, so we can't assert that the size of the cached control - // elements is equal to the size of the fields in |form|. Fortunately, the - // one case in the wild where this happens, paypal.com signup form, the fields - // are appended to the end of the form and are not visible. - for (size_t i = 0, j = 0; i < form->control_elements.size() && j < data.fields.size(); ++i) { - HTMLFormControlElement* element = form->control_elements[i].get(); - string16 element_name = nameForAutoFill(*element); - - if (element_name.empty()) - continue; - - // Search forward in the |form| for a corresponding field. - size_t k = j; - while (k < data.fields.size() && element_name != data.fields[k].name()) - k++; - - if (k >= data.fields.size()) - continue; - - DCHECK_EQ(data.fields[k].name(), element_name); - - bool is_initiating_node = false; - - // More than likely |requirements| will contain REQUIRE_AUTOCOMPLETE and/or - // REQUIRE_EMPTY, which both require text form control elements, so special- - // case this type of element. - if (formControlType(*element) == kText) { - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element); - - // TODO: WebKit currently doesn't handle the autocomplete - // attribute for select control elements, but it probably should. - if (requirements & REQUIRE_AUTOCOMPLETE && !input_element->autoComplete()) - continue; - - is_initiating_node = (input_element == node); - // Don't require the node that initiated the auto-fill process to be - // empty. The user is typing in this field and we should complete the - // value when the user selects a value to fill out. - if (requirements & REQUIRE_EMPTY && !is_initiating_node && !input_element->value().isEmpty()) - continue; - } - - if (requirements & REQUIRE_ENABLED && !element->isEnabledFormControl()) - continue; - - callback->Run(element, &data.fields[k], is_initiating_node); - - // We found a matching form field so move on to the next. - ++j; - } - - delete callback; -} - -void FormManager::FillFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) { - // Nothing to fill. - if (data->value().empty()) - return; - - if (formControlType(*field) == kText) { - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(field); - - // If the maxlength attribute contains a negative value, maxLength() - // returns the default maxlength value. - input_element->setValue(data->value().substr(0, input_element->maxLength()).c_str()); - input_element->setAutofilled(true); - if (is_initiating_node) { - int length = input_element->value().length(); - input_element->setSelectionRange(length, length); - } - } else if (formControlType(*field) == kSelectOne) { - HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(field); - select_element->setValue(data->value().c_str()); - } -} - -void FormManager::PreviewFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) { - // Nothing to preview. - if (data->value().empty()) - return; - - // Only preview input fields. - if (formControlType(*field) != kText) - return; - - HTMLInputElement* input_element = static_cast<HTMLInputElement*>(field); - - // If the maxlength attribute contains a negative value, maxLength() - // returns the default maxlength value. - input_element->setSuggestedValue(data->value().substr(0, input_element->maxLength()).c_str()); - input_element->setAutofilled(true); - if (is_initiating_node) - input_element->setSelectionRange(0, input_element->suggestedValue().length()); -} - -} diff --git a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h deleted file mode 100644 index e844981..0000000 --- a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010 The Chromium Authors. All rights reserved. - * 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 FormManagerAndroid_h -#define FormManagerAndroid_h - -#include "ChromiumIncludes.h" - -#include <map> -#include <vector> - -// TODO: This file is taken from chromium/chrome/renderer/form_manager.h and -// customised to use WebCore types rather than WebKit API types. It would be -// nice and would ease future merge pain if the two could be combined. - -namespace webkit_glue { -struct FormData; -class FormField; -} // namespace webkit_glue - -namespace WebCore { -class Frame; -class HTMLFormControlElement; -class HTMLFormElement; -class Node; -} - -using WebCore::Frame; -using WebCore::HTMLFormControlElement; -using WebCore::HTMLFormElement; -using WebCore::Node; - -namespace android { - -// Manages the forms in a Document. -class FormManager { -public: - // A bit field mask for form requirements. - enum RequirementsMask { - REQUIRE_NONE = 0, // No requirements. - REQUIRE_AUTOCOMPLETE = 1 << 0, // Require that autocomplete != off. - REQUIRE_ENABLED = 1 << 1, // Require that disabled attribute is off. - REQUIRE_EMPTY = 1 << 2, // Require that the fields are empty. - }; - - // A bit field mask to extract data from HTMLFormControlElement. - enum ExtractMask { - EXTRACT_NONE = 0, - EXTRACT_VALUE = 1 << 0, // Extract value from HTMLFormControlElement. - EXTRACT_OPTION_TEXT = 1 << 1, // Extract option text from HTMLFormSelectElement. Only valid when |EXTRACT_VALUE| is set. This is used for form submission where humand readable value is captured. - EXTRACT_OPTIONS = 1 << 2, // Extract options from HTMLFormControlElement. - }; - - FormManager(); - virtual ~FormManager(); - - // Fills out a FormField object from a given HTMLFormControlElement. - // |extract_mask|: See the enum ExtractMask above for details. - static void HTMLFormControlElementToFormField(HTMLFormControlElement* element, ExtractMask extract_mask, webkit_glue::FormField* field); - - // Returns the corresponding label for |element|. WARNING: This method can - // potentially be very slow. Do not use during any code paths where the page - // is loading. - static string16 LabelForElement(const HTMLFormControlElement& element); - - // Fills out a FormData object from a given WebFormElement. If |get_values| - // is true, the fields in |form| will have the values filled out. Returns - // true if |form| is filled out; it's possible that |element| won't meet the - // requirements in |requirements|. This also returns false if there are no - // fields in |form|. - // TODO: Remove the user of this in RenderView and move this to - // private. - static bool HTMLFormElementToFormData(HTMLFormElement* element, RequirementsMask requirements, ExtractMask extract_mask, webkit_glue::FormData* form); - - // Scans the DOM in |frame| extracting and storing forms. - void ExtractForms(Frame* frame); - - // Returns a vector of forms in |frame| that match |requirements|. - void GetFormsInFrame(const Frame* frame, RequirementsMask requirements, std::vector<webkit_glue::FormData>* forms); - - // Finds the form that contains |element| and returns it in |form|. Returns - // false if the form is not found. - bool FindFormWithFormControlElement(HTMLFormControlElement* element, RequirementsMask requirements, webkit_glue::FormData* form); - - // Fills the form represented by |form|. |form| should have the name set to - // the name of the form to fill out, and the number of elements and values - // must match the number of stored elements in the form. |node| is the form - // control element that initiated the auto-fill process. - // TODO: Is matching on name alone good enough? It's possible to - // store multiple forms with the same names from different frames. - bool FillForm(const webkit_glue::FormData& form, Node* node); - - // Previews the form represented by |form|. |node| is the form control element - // that initiated the preview process. Same conditions as FillForm. - bool PreviewForm(const webkit_glue::FormData& form, Node* node); - - // Clears the values of all input elements in the form that contains |node|. - // Returns false if the form is not found. - bool ClearFormWithNode(Node* node); - - // Clears the placeholder values and the auto-filled background for any fields - // in the form containing |node| that have been previewed. Resets the - // autofilled state of |node| to |was_autofilled|. Returns false if the form - // is not found. - bool ClearPreviewedFormWithNode(Node* node, bool was_autofilled); - - // Resets the stored set of forms. - void Reset(); - - // Resets the forms for the specified |frame|. - void ResetFrame(const Frame* frame); - - // Returns true if |form| has any auto-filled fields. - bool FormWithNodeIsAutoFilled(Node* node); - -private: - // Stores the HTMLFormElement and the form control elements for a form. - // Original form values are stored so when we clear a form we can reset - // "select-one" values to their original state. - struct FormElement; - - // Type for cache of FormElement objects. - typedef std::vector<FormElement*> FormElementList; - - // The callback type used by ForEachMatchingFormField(). - typedef Callback3<HTMLFormControlElement*, const webkit_glue::FormField*, bool>::Type Callback; - - // Infers corresponding label for |element| from surrounding context in the - // DOM. Contents of preceeding <p> tag or preceeding text element found in - // the form. - static string16 InferLabelForElement(const HTMLFormControlElement& element); - - // Finds the cached FormElement that contains |node|. - bool FindCachedFormElementWithNode(Node* node, FormElement** form_element); - - // Uses the data in |form| to find the cached FormElement. - bool FindCachedFormElement(const webkit_glue::FormData& form, FormElement** form_element); - - // For each field in |data| that matches the corresponding field in |form| - // and meets the |requirements|, |callback| is called with the actual - // WebFormControlElement and the FormField data from |form|. The field that - // matches |node| is not required to be empty if |requirements| includes - // REQUIRE_EMPTY. This method owns |callback|. - void ForEachMatchingFormField(FormElement* form, Node* node, RequirementsMask requirements, const webkit_glue::FormData& data, Callback* callback); - - // A ForEachMatchingFormField() callback that sets |field|'s value using the - // value in |data|. This method also sets the autofill attribute, causing the - // background to be yellow. - void FillFormField(HTMLFormControlElement* field, const webkit_glue::FormField* data, bool is_initiating_node); - - // A ForEachMatchingFormField() callback that sets |field|'s placeholder value - // using the value in |data|, causing the test to be greyed-out. This method - // also sets the autofill attribute, causing the background to be yellow. - void PreviewFormField(HTMLFormControlElement* field, const webkit_glue::FormField* data, bool is_initiaiting_node); - - // The cached FormElement objects. - FormElementList form_elements_; - - DISALLOW_COPY_AND_ASSIGN(FormManager); -}; - -} // namespace android - -#endif // FormManagerAndroid_h diff --git a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp deleted file mode 100644 index 598b9c4..0000000 --- a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp +++ /dev/null @@ -1,35 +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. - */ - - -#include "config.h" -#include "MainThreadProxy.h" - -#include <wtf/MainThread.h> - -void MainThreadProxy::CallOnMainThread(CallOnMainThreadFunction f, void* c) -{ - callOnMainThread(f, c); -} diff --git a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h deleted file mode 100644 index d9310bb..0000000 --- a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h +++ /dev/null @@ -1,37 +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 MAIN_THREAD_PROXY_H -#define MAIN_THREAD_PROXY_H - -typedef void CallOnMainThreadFunction(void*); - -class MainThreadProxy -{ -public: - static void CallOnMainThread(CallOnMainThreadFunction, void*); -}; - -#endif diff --git a/WebKit/android/WebCoreSupport/autofill/StringUtils.h b/WebKit/android/WebCoreSupport/autofill/StringUtils.h deleted file mode 100644 index aa408a5..0000000 --- a/WebKit/android/WebCoreSupport/autofill/StringUtils.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2010 The Android Open Source Project. All rights reserved. - * - * 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 AutoFillStringUtils_h_ -#define AutoFillStringUtils_h_ - -#include "ChromiumIncludes.h" -#include "HTMLFormControlElement.h" -#include <wtf/text/WTFString.h> - -using WebCore::HTMLFormControlElement; - -const string16 kText = ASCIIToUTF16("text"); -const string16 kHidden = ASCIIToUTF16("hidden"); -const string16 kSelectOne = ASCIIToUTF16("select-one"); - -inline string16 WTFStringToString16(const WTF::String& wtfString) -{ - WTF::String str = wtfString; - - if (str.charactersWithNullTermination()) - return string16(str.charactersWithNullTermination()); - else - return string16(); -} - -inline string16 nameForAutoFill(const HTMLFormControlElement& element) -{ - // Taken from WebKit/chromium/src/WebFormControlElement.cpp, ported - // to use WebCore types for accessing element properties. - String name = element.name(); - String trimmedName = name.stripWhiteSpace(); - if (!trimmedName.isEmpty()) - return WTFStringToString16(trimmedName); - name = element.getIdAttribute(); - trimmedName = name.stripWhiteSpace(); - if (!trimmedName.isEmpty()) - return WTFStringToString16(trimmedName); - return string16(); -} - -inline string16 formControlType(const HTMLFormControlElement& element) -{ - // Taken from WebKit/chromium/src/WebFormControlElement.cpp, ported - // to use WebCore types for accessing element properties. - return WTFStringToString16(element.type()); -} - -#endif - diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp deleted file mode 100644 index a80636c..0000000 --- a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp +++ /dev/null @@ -1,296 +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. - */ - -#include "config.h" -#include "WebAutoFill.h" - -#if ENABLE(WEB_AUTOFILL) - -#include "AutoFillHostAndroid.h" -#include "Frame.h" -#include "FormData.h" -#include "FormManagerAndroid.h" -#include "FrameLoader.h" -#include "HTMLFormControlElement.h" -#include "MainThreadProxy.h" -#include "Node.h" -#include "Page.h" -#include "Settings.h" -#include "WebFrame.h" -#include "WebRequestContext.h" -#include "WebUrlLoaderClient.h" -#include "WebViewCore.h" - -#define NO_PROFILE_SET 0 -#define FORM_NOT_AUTOFILLABLE -1 - -namespace android -{ -WebAutoFill::WebAutoFill() - : mQueryId(1) - , mWebViewCore(0) - , mLastSearchDomVersion(0) - , mParsingForms(false) -{ - mTabContents = new TabContents(); - setEmptyProfile(); -} - -void WebAutoFill::init() -{ - if (mAutoFillManager) - return; - - mFormManager = new FormManager(); - // We use the WebView's WebRequestContext, which may be a private browsing context. - ASSERT(mWebViewCore); - mAutoFillManager = new AutoFillManager(mTabContents.get()); - mAutoFillHost = new AutoFillHostAndroid(this); - mTabContents->SetProfileRequestContext(new AndroidURLRequestContextGetter(mWebViewCore->webRequestContext(), WebUrlLoaderClient::ioThread())); - mTabContents->SetAutoFillHost(mAutoFillHost.get()); -} - -WebAutoFill::~WebAutoFill() -{ - cleanUpQueryMap(); - mUniqueIdMap.clear(); -} - -void WebAutoFill::cleanUpQueryMap() -{ - for (AutoFillQueryFormDataMap::iterator it = mQueryMap.begin(); it != mQueryMap.end(); it++) - delete it->second; - mQueryMap.clear(); -} - -void WebAutoFill::searchDocument(WebCore::Frame* frame) -{ - if (!enabled()) - return; - - MutexLocker lock(mFormsSeenMutex); - - init(); - - cleanUpQueryMap(); - mUniqueIdMap.clear(); - mForms.clear(); - mQueryId = 1; - - ASSERT(mFormManager); - ASSERT(mAutoFillManager); - - mAutoFillManager->Reset(); - mFormManager->Reset(); - - mFormManager->ExtractForms(frame); - mFormManager->GetFormsInFrame(frame, FormManager::REQUIRE_AUTOCOMPLETE, &mForms); - - // Needs to be done on a Chrome thread as it will make a URL request to the AutoFill server. - // TODO: Use our own Autofill thread instead of the IO thread. - // TODO: For now, block here. Would like to make this properly async. - base::Thread* thread = WebUrlLoaderClient::ioThread(); - mParsingForms = true; - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebAutoFill::formsSeenImpl)); - while (mParsingForms) - mFormsSeenCondition.wait(mFormsSeenMutex); -} - -// Called on the Chromium IO thread. -void WebAutoFill::formsSeenImpl() -{ - MutexLocker lock(mFormsSeenMutex); - mAutoFillManager->FormsSeen(mForms); - mParsingForms = false; - mFormsSeenCondition.signal(); -} - -void WebAutoFill::formFieldFocused(WebCore::HTMLFormControlElement* formFieldElement) -{ - ASSERT(formFieldElement); - - Document* doc = formFieldElement->document(); - Frame* frame = doc->frame(); - - // FIXME: AutoFill only works in main frame for now. Should consider - // child frames. - if (frame != frame->page()->mainFrame()) - return; - - unsigned domVersion = doc->domTreeVersion(); - ASSERT(domVersion > 0); - - if (mLastSearchDomVersion != domVersion) { - // Need to extract forms as DOM version has changed since the last time - // we searched. - searchDocument(formFieldElement->document()->frame()); - mLastSearchDomVersion = domVersion; - } - - if (!enabled()) { - // In case that we've just been disabled and the last time we got autofill - // suggestions and told Java about them, clear that bit Java side now - // we're disabled. - mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE, string16()); - return; - } - - // Get the FormField from the Node. - webkit_glue::FormField* formField = new webkit_glue::FormField; - FormManager::HTMLFormControlElementToFormField(formFieldElement, FormManager::EXTRACT_NONE, formField); - formField->set_label(FormManager::LabelForElement(*formFieldElement)); - - webkit_glue::FormData* form = new webkit_glue::FormData; - mFormManager->FindFormWithFormControlElement(formFieldElement, FormManager::REQUIRE_AUTOCOMPLETE, form); - mQueryMap[mQueryId] = new FormDataAndField(form, formField); - - bool suggestions = mAutoFillManager->GetAutoFillSuggestions(*form, *formField); - - mQueryId++; - if (!suggestions) { - ASSERT(mWebViewCore); - // Tell Java no autofill suggestions for this form. - mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE, string16()); - return; - } -} - -void WebAutoFill::querySuccessful(const string16& value, const string16& label, int uniqueId) -{ - if (!enabled()) - return; - - // Store the unique ID for the query and inform java that autofill suggestions for this form are available. - // Pass java the queryId so that it can pass it back if the user decides to use autofill. - mUniqueIdMap[mQueryId] = uniqueId; - - ASSERT(mWebViewCore); - mWebViewCore->setWebTextViewAutoFillable(mQueryId, mAutoFillProfile->Label()); -} - -void WebAutoFill::fillFormFields(int queryId) -{ - if (!enabled()) - return; - - webkit_glue::FormData* form = mQueryMap[queryId]->form(); - webkit_glue::FormField* field = mQueryMap[queryId]->field(); - ASSERT(form); - ASSERT(field); - - AutoFillQueryToUniqueIdMap::iterator iter = mUniqueIdMap.find(queryId); - if (iter == mUniqueIdMap.end()) { - // The user has most likely tried to AutoFill the form again without - // refocussing the form field. The UI should protect against this - // but stop here to be certain. - return; - } - mAutoFillManager->FillAutoFillFormData(queryId, *form, *field, iter->second); - mUniqueIdMap.erase(iter); -} - -void WebAutoFill::fillFormInPage(int queryId, const webkit_glue::FormData& form) -{ - if (!enabled()) - return; - - // FIXME: Pass a pointer to the Node that triggered the AutoFill flow here instead of 0. - // The consquence of passing 0 is that we should always fail the test in FormManader::ForEachMathcingFormField():169 - // that says "only overwrite an elements current value if the user triggered autofill through that element" - // for elements that have a value already. But by a quirk of Android text views we are OK. We should still - // fix this though. - mFormManager->FillForm(form, 0); -} - -bool WebAutoFill::enabled() const -{ - Page* page = mWebViewCore->mainFrame()->page(); - return page ? page->settings()->autoFillEnabled() : false; -} - -void WebAutoFill::setProfile(const string16& fullName, const string16& emailAddress, const string16& companyName, - const string16& addressLine1, const string16& addressLine2, const string16& city, - const string16& state, const string16& zipCode, const string16& country, const string16& phoneNumber) -{ - if (!mAutoFillProfile) - mAutoFillProfile.set(new AutoFillProfile()); - - // Update the profile. - // Constants for AutoFill field types are found in external/chromium/chrome/browser/autofill/field_types.h. - mAutoFillProfile->SetInfo(AutoFillType(NAME_FULL), fullName); - mAutoFillProfile->SetInfo(AutoFillType(EMAIL_ADDRESS), emailAddress); - mAutoFillProfile->SetInfo(AutoFillType(COMPANY_NAME), companyName); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), addressLine1); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), addressLine2); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), city); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), state); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), zipCode); - mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), country); - mAutoFillProfile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), phoneNumber); - - std::vector<AutoFillProfile> profiles; - profiles.push_back(*mAutoFillProfile); - updateProfileLabel(); - mTabContents->profile()->GetPersonalDataManager()->SetProfiles(&profiles); -} - -bool WebAutoFill::updateProfileLabel() -{ - std::vector<AutoFillProfile*> profiles; - profiles.push_back(mAutoFillProfile.get()); - return AutoFillProfile::AdjustInferredLabels(&profiles); -} - -void WebAutoFill::clearProfiles() -{ - if (!mAutoFillProfile) - return; - // For now Chromium only ever knows about one profile, so we can just - // remove it. If we support multiple profiles in the future - // we need to remove them all here. - std::string profileGuid = mAutoFillProfile->guid(); - mTabContents->profile()->GetPersonalDataManager()->RemoveProfile(profileGuid); - setEmptyProfile(); -} - -void WebAutoFill::setEmptyProfile() -{ - // Set an empty profile. This will ensure that when autofill is enabled, - // we will still search the document for autofillable forms and inform - // java of their presence so we can invite the user to set up - // their own profile. - - // Chromium code will strip the values sent into the profile so we need them to be - // at least one non-whitespace character long. We need to set all fields of the - // profile to a non-empty string so that any field type can trigger the autofill - // suggestion. AutoFill will not detect form fields if the profile value for that - // field is an empty string. - static const string16 empty = string16(ASCIIToUTF16("a")); - setProfile(empty, empty, empty, empty, empty, empty, empty, empty, empty, empty); -} - -} - -#endif diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h deleted file mode 100644 index 97e478e..0000000 --- a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h +++ /dev/null @@ -1,127 +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 WebAutoFill_h -#define WebAutoFill_h - -#if ENABLE(WEB_AUTOFILL) - -#include "ChromiumIncludes.h" - -#include <map> -#include <vector> -#include <wtf/Noncopyable.h> -#include <wtf/OwnPtr.h> -#include <wtf/ThreadingPrimitives.h> - -class AutoFillManager; -class AutoFillProfile; -class AutoFillHost; - -namespace WebCore { -class Frame; -class HTMLFormControlElement; -} - -namespace android -{ -class FormManager; -class WebViewCore; - -class FormDataAndField { -public: - FormDataAndField(webkit_glue::FormData* form, webkit_glue::FormField* field) - : mForm(form) - , mField(field) - { - } - - webkit_glue::FormData* form() { return mForm.get(); } - webkit_glue::FormField* field() { return mField.get(); } - -private: - OwnPtr<webkit_glue::FormData> mForm; - OwnPtr<webkit_glue::FormField> mField; -}; - -class WebAutoFill : public Noncopyable -{ -public: - WebAutoFill(); - virtual ~WebAutoFill(); - void formFieldFocused(WebCore::HTMLFormControlElement*); - void fillFormFields(int queryId); - void querySuccessful(const string16& value, const string16& label, int uniqueId); - void fillFormInPage(int queryId, const webkit_glue::FormData& form); - void setWebViewCore(WebViewCore* webViewCore) { mWebViewCore = webViewCore; } - bool enabled() const; - - void setProfile(const string16& fullName, const string16& emailAddress, const string16& companyName, - const string16& addressLine1, const string16& addressLine2, const string16& city, - const string16& state, const string16& zipCode, const string16& country, const string16& phoneNumber); - void clearProfiles(); - - bool updateProfileLabel(); - - void reset() { mLastSearchDomVersion = 0; } - -private: - void init(); - void searchDocument(WebCore::Frame*); - void setEmptyProfile(); - void formsSeenImpl(); - void cleanUpQueryMap(); - - OwnPtr<FormManager> mFormManager; - OwnPtr<AutoFillManager> mAutoFillManager; - OwnPtr<AutoFillHost> mAutoFillHost; - OwnPtr<TabContents> mTabContents; - OwnPtr<AutoFillProfile> mAutoFillProfile; - - typedef std::vector<webkit_glue::FormData, std::allocator<webkit_glue::FormData> > FormList; - FormList mForms; - - typedef std::map<int, FormDataAndField*> AutoFillQueryFormDataMap; - AutoFillQueryFormDataMap mQueryMap; - - typedef std::map<int, int> AutoFillQueryToUniqueIdMap; - AutoFillQueryToUniqueIdMap mUniqueIdMap; - int mQueryId; - - WebViewCore* mWebViewCore; - - unsigned mLastSearchDomVersion; - - WTF::Mutex mFormsSeenMutex; // Guards mFormsSeenCondition and mParsingForms. - WTF::ThreadCondition mFormsSeenCondition; - bool volatile mParsingForms; -}; - -} - -DISABLE_RUNNABLE_METHOD_REFCOUNT(android::WebAutoFill); - -#endif // ENABLE(WEB_AUTOFILL) -#endif // WebAutoFill_h diff --git a/WebKit/android/benchmark/Android.mk b/WebKit/android/benchmark/Android.mk deleted file mode 100644 index 5b189e1..0000000 --- a/WebKit/android/benchmark/Android.mk +++ /dev/null @@ -1,41 +0,0 @@ -## -## -## Copyright 2009, The Android Open Source Project -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions -## are met: -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## * Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in the -## documentation and/or other materials provided with the distribution. -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR -## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -## - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - main.cpp - -# Pull the webkit definitions from the base webkit makefile. -LOCAL_SHARED_LIBRARIES := libwebcore $(WEBKIT_SHARED_LIBRARIES) -LOCAL_LDLIBS := $(WEBKIT_LDLIBS) - -LOCAL_MODULE := webcore_test - -LOCAL_MODULE_TAGS := optional - -include $(BUILD_EXECUTABLE) diff --git a/WebKit/android/benchmark/Intercept.cpp b/WebKit/android/benchmark/Intercept.cpp deleted file mode 100644 index deffac2..0000000 --- a/WebKit/android/benchmark/Intercept.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define LOG_TAG "webcore_test" -#include "config.h" - -#include "Base64.h" -#include "HTTPParsers.h" -#include "Intercept.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "TextEncoding.h" - -#include <utils/Log.h> -#include <wtf/HashMap.h> -#include <wtf/text/CString.h> -#include <wtf/text/StringHash.h> - -PassRefPtr<WebCore::ResourceLoaderAndroid> MyResourceLoader::create( - ResourceHandle* handle, String url) -{ - return adoptRef<WebCore::ResourceLoaderAndroid>( - new MyResourceLoader(handle, url)); -} - -void MyResourceLoader::handleRequest() -{ - if (protocolIs(m_url, "data")) - loadData(m_url.substring(5)); // 5 for data: - else if (protocolIs(m_url, "file")) - loadFile(m_url.substring(7)); // 7 for file:// -} - -void MyResourceLoader::loadData(const String& data) -{ - LOGD("Loading data (%s) ...", data.latin1().data()); - ResourceHandleClient* client = m_handle->client(); - int index = data.find(','); - if (index == -1) { - client->cannotShowURL(m_handle); - return; - } - - String mediaType = data.substring(0, index); - String base64 = data.substring(index + 1); - - bool decode = mediaType.endsWith(";base64", false); - if (decode) - mediaType = mediaType.left(mediaType.length() - 7); // 7 for base64; - - if (mediaType.isEmpty()) - mediaType = "text/plain;charset=US-ASCII"; - - String mimeType = extractMIMETypeFromMediaType(mediaType); - String charset = extractCharsetFromMediaType(mediaType); - - ResourceResponse response; - response.setMimeType(mimeType); - - if (decode) { - base64 = decodeURLEscapeSequences(base64); - response.setTextEncodingName(charset); - client->didReceiveResponse(m_handle, response); - - // FIXME: This is annoying. WebCore's Base64 decoder chokes on spaces. - // That is correct with strict decoding but html authors (particularly - // the acid3 authors) put spaces in the data which should be ignored. - // Remove them here before sending to the decoder. - Vector<char> in; - CString str = base64.latin1(); - const char* chars = str.data(); - unsigned i = 0; - while (i < str.length()) { - char c = chars[i]; - // Don't send spaces or control characters. - if (c != ' ' && c != '\n' && c != '\t' && c != '\b' - && c != '\f' && c != '\r') - in.append(chars[i]); - i++; - } - Vector<char> out; - if (base64Decode(in, out) && out.size() > 0) - client->didReceiveData(m_handle, out.data(), out.size(), 0); - } else { - base64 = decodeURLEscapeSequences(base64, TextEncoding(charset)); - response.setTextEncodingName("UTF-16"); - client->didReceiveResponse(m_handle, response); - if (base64.length() > 0) - client->didReceiveData(m_handle, (const char*)base64.characters(), - base64.length() * sizeof(UChar), 0); - } - client->didFinishLoading(m_handle, 0); -} -static String mimeTypeForExtension(const String& file) -{ - static HashMap<String, String, CaseFoldingHash> extensionToMime; - if (extensionToMime.isEmpty()) { - extensionToMime.set("txt", "text/plain"); - extensionToMime.set("html", "text/html"); - extensionToMime.set("htm", "text/html"); - extensionToMime.set("png", "image/png"); - extensionToMime.set("jpeg", "image/jpeg"); - extensionToMime.set("jpg", "image/jpeg"); - extensionToMime.set("gif", "image/gif"); - extensionToMime.set("ico", "image/x-icon"); - extensionToMime.set("js", "text/javascript"); - } - int dot = file.reverseFind('.'); - String mime("text/plain"); - if (dot != -1) { - String ext = file.substring(dot + 1); - if (extensionToMime.contains(ext)) - mime = extensionToMime.get(ext); - } - return mime; -} - -void MyResourceLoader::loadFile(const String& file) -{ - LOGD("Loading file (%s) ...", file.latin1().data()); - FILE* f = fopen(file.latin1().data(), "r"); - ResourceHandleClient* client = m_handle->client(); - if (!f) { - client->didFail(m_handle, - ResourceError("", -14, file, "Could not open file")); - } else { - ResourceResponse response; - response.setTextEncodingName("utf-8"); - response.setMimeType(mimeTypeForExtension(file)); - client->didReceiveResponse(m_handle, response); - char buf[512]; - while (true) { - int res = fread(buf, 1, sizeof(buf), f); - if (res <= 0) - break; - client->didReceiveData(m_handle, buf, res, 0); - } - fclose(f); - client->didFinishLoading(m_handle, 0); - } -} - -PassRefPtr<WebCore::ResourceLoaderAndroid> MyWebFrame::startLoadingResource( - ResourceHandle* handle, const ResourceRequest& req, bool ignore, - bool ignore2) -{ - RefPtr<WebCore::ResourceLoaderAndroid> loader = - MyResourceLoader::create(handle, req.url().string()); - m_requests.append(loader); - if (!m_timer.isActive()) - m_timer.startOneShot(0); - return loader.release(); -} - -void MyWebFrame::timerFired(Timer<MyWebFrame>*) -{ - LOGD("Handling requests..."); - Vector<RefPtr<WebCore::ResourceLoaderAndroid> > reqs; - reqs.swap(m_requests); - Vector<RefPtr<WebCore::ResourceLoaderAndroid> >::iterator i = reqs.begin(); - Vector<RefPtr<WebCore::ResourceLoaderAndroid> >::iterator end = reqs.end(); - for (; i != end; i++) - static_cast<MyResourceLoader*>((*i).get())->handleRequest(); - - LOGD("...done"); -} diff --git a/WebKit/android/benchmark/Intercept.h b/WebKit/android/benchmark/Intercept.h deleted file mode 100644 index edd5123..0000000 --- a/WebKit/android/benchmark/Intercept.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef INTERCEPT_H -#define INTERCEPT_H - -#include "MyJavaVM.h" -#include "PlatformString.h" -#include "Timer.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreResourceLoader.h" -#include <JNIUtility.h> -#include <wtf/Vector.h> - -namespace WebCore { - class Page; - class ResourceHandle; - class ResourceRequest; -} - -using namespace android; -using namespace WebCore; -using namespace WTF; - -class MyResourceLoader : public WebCoreResourceLoader { -public: - static PassRefPtr<WebCore::ResourceLoaderAndroid> create( - ResourceHandle* handle, String url); - void handleRequest(); - -private: - MyResourceLoader(ResourceHandle* handle, String url) - : WebCoreResourceLoader(JSC::Bindings::getJNIEnv(), MY_JOBJECT) - , m_handle(handle) - , m_url(url) {} - - void loadData(const String&); - void loadFile(const String&); - ResourceHandle* m_handle; - String m_url; -}; - -class MyWebFrame : public WebFrame { -public: - MyWebFrame(Page* page) - : WebFrame(JSC::Bindings::getJNIEnv(), MY_JOBJECT, MY_JOBJECT, page) - , m_timer(this, &MyWebFrame::timerFired) {} - - virtual PassRefPtr<WebCore::ResourceLoaderAndroid> startLoadingResource( - ResourceHandle* handle, const ResourceRequest& req, bool, bool); - - virtual bool canHandleRequest(const ResourceRequest&) { return true; } - -private: - void timerFired(Timer<MyWebFrame>*); - Vector<RefPtr<WebCore::ResourceLoaderAndroid> > m_requests; - Timer<MyWebFrame> m_timer; -}; - -#endif diff --git a/WebKit/android/benchmark/MyJavaVM.cpp b/WebKit/android/benchmark/MyJavaVM.cpp deleted file mode 100644 index 574c745..0000000 --- a/WebKit/android/benchmark/MyJavaVM.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MyJavaVM.h" - -#include <JNIUtility.h> -#include <jni.h> - -static JNIEnv* s_env; -static JavaVM* s_jvm; - -// JavaVM functions -jint vm_attachCurrentThread(JavaVM*, JNIEnv** env, void*) { - *env = s_env; - return JNI_OK; -} - -// JNIEnv functions -jobject env_callObjectMethodV(JNIEnv*, jobject, jmethodID, va_list) { - return MY_JOBJECT; -} -void env_callVoidMethodV(JNIEnv*, jobject, jmethodID, va_list) {} -void env_deleteRef(JNIEnv*, jobject) {} -jboolean env_exceptionCheck(JNIEnv*) { - return false; -} -jclass env_findClass(JNIEnv*, const char*) { - return (jclass) 1; -} -jbyte* env_getByteArrayElements(JNIEnv*, jbyteArray, jboolean*) { - return NULL; -} -jmethodID env_getMethodID(JNIEnv*, jclass, const char*, const char*) { - return (jmethodID) 1; -} -jclass env_getObjectClass(JNIEnv*, jobject) { - return (jclass) 1; -} -static const char* s_fakeString = "Fake Java String"; -const jchar* env_getStringChars(JNIEnv*, jstring, jboolean* isCopy) { - if (isCopy) - *isCopy = false; - return (const jchar*)s_fakeString; -} -jsize env_getStringLength(JNIEnv*, jstring) { - return sizeof(s_fakeString) - 1; -} -jbyteArray env_newByteArray(JNIEnv*, jsize) { - return (jbyteArray) 1; -} -jobject env_newRef(JNIEnv*, jobject obj) { - return obj; -} -jobject env_newObjectV(JNIEnv*, jclass, jmethodID, va_list) { - return MY_JOBJECT; -} -jstring env_newString(JNIEnv*, const jchar*, jsize) { - return (jstring) 1; -} -void env_releaseByteArrayElements(JNIEnv*, jbyteArray, jbyte*, jint) {} -void env_releaseStringChars(JNIEnv*, jstring, const jchar*) {} -void env_setByteArrayRegion(JNIEnv*, jbyteArray, jsize, jsize, const jbyte*) {} -void env_setIntField(JNIEnv*, jobject, jfieldID, jint) {} - -void InitializeJavaVM() { - // First, create the fake vm - s_jvm = new JavaVM; - JNIInvokeInterface* i = new JNIInvokeInterface; - memset(i, 0, sizeof(JNIInvokeInterface)); - s_jvm->functions = i; - - // Now, assign the functions of the vm to our fake ones. - i->AttachCurrentThread = vm_attachCurrentThread; - - // Create the fake env next - s_env = new JNIEnv; - JNINativeInterface* n = new JNINativeInterface; - memset(n, 0, sizeof(JNINativeInterface)); - s_env->functions = n; - - // Point the functions we care about to out fake ones. - n->CallObjectMethodV = env_callObjectMethodV; - n->CallVoidMethodV = env_callVoidMethodV; - n->DeleteLocalRef = env_deleteRef; - n->DeleteGlobalRef = env_deleteRef; - n->DeleteWeakGlobalRef = env_deleteRef; - n->ExceptionCheck = env_exceptionCheck; - n->FindClass = env_findClass; - n->GetByteArrayElements = env_getByteArrayElements; - n->GetMethodID = env_getMethodID; - n->GetObjectClass = env_getObjectClass; - n->GetStringChars = env_getStringChars; - n->GetStringLength = env_getStringLength; - n->NewByteArray = env_newByteArray; - n->NewLocalRef = env_newRef; - n->NewGlobalRef = env_newRef; - n->NewWeakGlobalRef = env_newRef; - n->NewObjectV = env_newObjectV; - n->NewString = env_newString; - n->ReleaseByteArrayElements = env_releaseByteArrayElements; - n->ReleaseStringChars = env_releaseStringChars; - n->SetByteArrayRegion = env_setByteArrayRegion; - n->SetIntField = env_setIntField; - - // Tell WebCore about the vm - JSC::Bindings::setJavaVM(s_jvm); -} diff --git a/WebKit/android/benchmark/MyJavaVM.h b/WebKit/android/benchmark/MyJavaVM.h deleted file mode 100644 index 36d478d..0000000 --- a/WebKit/android/benchmark/MyJavaVM.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MY_JAVA_VM_H -#define MY_JAVA_VM_H - -// Make it 1 just to appease any assertions or checks for valid objects -#define MY_JOBJECT ((jobject) 1) - -void InitializeJavaVM(); - -#endif diff --git a/WebKit/android/benchmark/main.cpp b/WebKit/android/benchmark/main.cpp deleted file mode 100644 index fcb797d..0000000 --- a/WebKit/android/benchmark/main.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define LOG_TAG "webcore_test" - -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <utils/Log.h> - -namespace android { -extern void benchmark(const char*, int, int ,int); -} - -int main(int argc, char** argv) { - int width = 800; - int height = 600; - int reloadCount = 0; - while (true) { - int c = getopt(argc, argv, "d:r:"); - if (c == -1) - break; - else if (c == 'd') { - char* x = strchr(optarg, 'x'); - if (x) { - width = atoi(optarg); - height = atoi(x + 1); - LOGD("Rendering page at %dx%d", width, height); - } - } else if (c == 'r') { - reloadCount = atoi(optarg); - if (reloadCount < 0) - reloadCount = 0; - LOGD("Reloading %d times", reloadCount); - } - } - if (optind >= argc) { - LOGE("Please supply a file to read\n"); - return 1; - } - - android::benchmark(argv[optind], reloadCount, width, height); -} diff --git a/WebKit/android/icu/unicode/ucnv.cpp b/WebKit/android/icu/unicode/ucnv.cpp deleted file mode 100644 index 1b40573..0000000 --- a/WebKit/android/icu/unicode/ucnv.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// BEGIN android-added -// Add config.h to avoid compiler error in uobject.h -// ucnv.h includes uobject.h indirectly and uobjetcs.h defines new/delete. -// new/delete are also defined in WebCorePrefix.h which auto included in Android make. -// -// config.h has to be on top of the include list. -#include "config.h" -// END android-added - -#include "EmojiFont.h" -#include <icu4c/common/unicode/ucnv.h> - -namespace android { - -U_STABLE UConverter* U_EXPORT2 -ucnv_open_emoji(const char *converterName, UErrorCode *err) { - if (EmojiFont::IsAvailable()) { - if (strcmp(converterName, "Shift_JIS") == 0) { - converterName = EmojiFont::GetShiftJisConverterName(); - } - } - return ucnv_open(converterName, err); -} - -} // end namespace android diff --git a/WebKit/android/icu/unicode/ucnv.h b/WebKit/android/icu/unicode/ucnv.h deleted file mode 100644 index 5ddaedb..0000000 --- a/WebKit/android/icu/unicode/ucnv.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 ANDROID_UCNV_H -#define ANDROID_UCNV_H - -// Include the real ucnv.h file from icu. Use a more exact reference so we do -// not conflict with this file. -#include <icu4c/common/unicode/ucnv.h> - -namespace android { - -U_STABLE UConverter* U_EXPORT2 -ucnv_open_emoji(const char *converterName, UErrorCode *err); - -} - -// Redefine ucnv_open to android::ucnv_open_emoji. This relies heavily on the -// fact that this file will be included before any of the real icu headers. -// This is done in Android.mk by including WebKit/android/icu before the -// regular icu directory. -#undef ucnv_open -#define ucnv_open android::ucnv_open_emoji - -#endif diff --git a/WebKit/android/jni/CacheManager.cpp b/WebKit/android/jni/CacheManager.cpp deleted file mode 100644 index 144b62a..0000000 --- a/WebKit/android/jni/CacheManager.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2011, 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" - -#if USE(CHROME_NETWORK_STACK) - -#include "ChromiumIncludes.h" -#include "WebCache.h" -#include "WebCoreJni.h" - -#include <JNIHelp.h> -#include <platform/FileSystem.h> -#include <platform/text/Base64.h> -#include <wtf/text/CString.h> -#include <wtf/text/WTFString.h> - -using namespace WebCore; -using namespace base; -using namespace disk_cache; -using namespace net; -using namespace std; - -namespace android { - -// JNI for android.webkit.CacheManager -static const char* javaCacheManagerClass = "android/webkit/CacheManager"; - -static void setStringField(JNIEnv* env, const jobject& object, const jfieldID& field, const String& str) -{ - jstring jstr = wtfStringToJstring(env, str); - env->SetObjectField(object, field, jstr); - env->DeleteLocalRef(jstr); -} - -static void setFieldFromHeaderIfPresent(CacheResult* result, const char* header, JNIEnv* env, const jobject& object, const jfieldID& field, bool allowEmptyString) -{ - String value; - if (result->firstResponseHeader(header, &value, allowEmptyString)) - setStringField(env, object, field, value); -} - -static String getCacheFileBaseDir(JNIEnv* env) -{ - static String baseDir; - if (baseDir.isEmpty()) { - jclass cacheManagerClass = env->FindClass("android/webkit/CacheManager"); - jmethodID getCacheFileBaseDirMethod = env->GetStaticMethodID(cacheManagerClass, "getCacheFileBaseDir", "()Ljava/io/File;"); - jclass fileClass = env->FindClass("java/io/File"); - jmethodID getPathMethod = env->GetMethodID(fileClass, "getPath", "()Ljava/lang/String;"); - jobject fileObject = env->CallStaticObjectMethod(cacheManagerClass, getCacheFileBaseDirMethod); - baseDir = jstringToWtfString(env, static_cast<jstring>(env->CallObjectMethod(fileObject, getPathMethod))); - } - return baseDir; -} - -static jobject getCacheResult(JNIEnv* env, jobject, jstring url) -{ - // This is called on the UI thread. - scoped_refptr<CacheResult> result = WebCache::get(false /*privateBrowsing*/)->getCacheResult(jstringToWtfString(env, url)); - if (!result) - return 0; - - // We create and populate a file with the cache entry. This allows us to - // replicate the behaviour of the Android HTTP stack in the Java - // CacheManager, which opens the cache file and provides an input stream to - // the file as part of the Java CacheResult object! - String urlWtfString = jstringToWtfString(env, url); - Vector<char> encodedUrl; - base64Encode(urlWtfString.utf8().data(), urlWtfString.length(), encodedUrl, false /*insertLFs*/); - String filePath = pathByAppendingComponent(getCacheFileBaseDir(env), encodedUrl.data()); - if (!result->writeToFile(filePath)) - return 0; - - jclass cacheResultClass = env->FindClass("android/webkit/CacheManager$CacheResult"); - jmethodID constructor = env->GetMethodID(cacheResultClass, "<init>", "()V"); - // We only bother with the fields that are made accessible through the public API. - jfieldID contentdispositionField = env->GetFieldID(cacheResultClass, "contentdisposition", "Ljava/lang/String;"); - jfieldID contentLengthField = env->GetFieldID(cacheResultClass, "contentLength", "J"); - jfieldID etagField = env->GetFieldID(cacheResultClass, "etag", "Ljava/lang/String;"); - jfieldID encodingField = env->GetFieldID(cacheResultClass, "encoding", "Ljava/lang/String;"); - jfieldID expiresField = env->GetFieldID(cacheResultClass, "expires", "J"); - jfieldID expiresStringField = env->GetFieldID(cacheResultClass, "expiresString", "Ljava/lang/String;"); - jfieldID httpStatusCodeField = env->GetFieldID(cacheResultClass, "httpStatusCode", "I"); - jfieldID lastModifiedField = env->GetFieldID(cacheResultClass, "lastModified", "Ljava/lang/String;"); - jfieldID localPathField = env->GetFieldID(cacheResultClass, "localPath", "Ljava/lang/String;"); - jfieldID locationField = env->GetFieldID(cacheResultClass, "location", "Ljava/lang/String;"); - jfieldID mimeTypeField = env->GetFieldID(cacheResultClass, "mimeType", "Ljava/lang/String;"); - - jobject javaResult = env->NewObject(cacheResultClass, constructor); - setFieldFromHeaderIfPresent(result.get(), "content-disposition", env, javaResult, contentdispositionField, true); - env->SetLongField(javaResult, contentLengthField, result->contentSize()); - setFieldFromHeaderIfPresent(result.get(), "etag", env, javaResult, etagField, false); - setStringField(env, javaResult, encodingField, "TODO"); // TODO: Where does the Android stack set this? - env->SetLongField(javaResult, expiresField, result->expires()); - env->SetIntField(javaResult, httpStatusCodeField, result->responseCode()); - setFieldFromHeaderIfPresent(result.get(), "last-modified", env, javaResult, lastModifiedField, false); - setStringField(env, javaResult, localPathField, encodedUrl.data()); - setFieldFromHeaderIfPresent(result.get(), "location", env, javaResult, locationField, false); - setStringField(env, javaResult, mimeTypeField, result->mimeType()); - - return javaResult; -} - -static JNINativeMethod gCacheManagerMethods[] = { - { "nativeGetCacheResult", "(Ljava/lang/String;)Landroid/webkit/CacheManager$CacheResult;", (void*) getCacheResult }, -}; - -int registerCacheManager(JNIEnv* env) -{ -#ifndef NDEBUG - jclass cacheManager = env->FindClass(javaCacheManagerClass); - LOG_ASSERT(cacheManager, "Unable to find class"); - env->DeleteLocalRef(cacheManager); -#endif - return jniRegisterNativeMethods(env, javaCacheManagerClass, gCacheManagerMethods, NELEM(gCacheManagerMethods)); -} - -} // namespace android - -#endif // USE(CHROME_NETWORK_STACK) diff --git a/WebKit/android/jni/CookieManager.cpp b/WebKit/android/jni/CookieManager.cpp deleted file mode 100644 index 0bdf303..0000000 --- a/WebKit/android/jni/CookieManager.cpp +++ /dev/null @@ -1,201 +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. - */ - -#include "config.h" - -#include "ChromiumIncludes.h" -#include "WebCookieJar.h" -#include "WebCoreJni.h" -#include <JNIHelp.h> - -using namespace base; -using namespace net; - -namespace android { - -// JNI for android.webkit.CookieManager -static const char* javaCookieManagerClass = "android/webkit/CookieManager"; - -static bool acceptCookie(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - // This is a static method which gets the cookie policy for all WebViews. We - // always apply the same configuration to the contexts for both regular and - // private browsing, so expect the same result here. - bool regularAcceptCookies = WebCookieJar::get(false)->allowCookies(); - ASSERT(regularAcceptCookies == WebCookieJar::get(true)->allowCookies()); - return regularAcceptCookies; -#else - // The Android HTTP stack is implemented Java-side. - ASSERT_NOT_REACHED(); - return false; -#endif -} - -static jstring getCookie(JNIEnv* env, jobject, jstring url, jboolean privateBrowsing) -{ -#if USE(CHROME_NETWORK_STACK) - GURL gurl(jstringToStdString(env, url)); - CookieOptions options; - options.set_include_httponly(); - std::string cookies = WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->GetCookiesWithOptions(gurl, options); - return stdStringToJstring(env, cookies); -#else - // The Android HTTP stack is implemented Java-side. - ASSERT_NOT_REACHED(); - return jstring(); -#endif -} - -static bool hasCookies(JNIEnv*, jobject, jboolean privateBrowsing) -{ -#if USE(CHROME_NETWORK_STACK) - return WebCookieJar::get(privateBrowsing)->getNumCookiesInDatabase() > 0; -#else - // The Android HTTP stack is implemented Java-side. - ASSERT_NOT_REACHED(); - return false; -#endif -} - -static void removeAllCookie(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->DeleteAll(true); - // This will lazily create a new private browsing context. However, if the - // context doesn't already exist, there's no need to create it, as cookies - // for such contexts are cleared up when we're done with them. - // TODO: Consider adding an optimisation to not create the context if it - // doesn't already exist. - WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->DeleteAll(true); - - // The Java code removes cookies directly from the backing database, so we do the same, - // but with a NULL callback so it's asynchronous. - WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->FlushStore(NULL); -#endif -} - -static void removeExpiredCookie(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - // This simply forces a GC. The getters delete expired cookies so won't return expired cookies anyway. - WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetAllCookies(); - WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->GetAllCookies(); -#endif -} - -static void removeSessionCookies(WebCookieJar* cookieJar) -{ -#if USE(CHROME_NETWORK_STACK) - CookieMonster* cookieMonster = cookieJar->cookieStore()->GetCookieMonster(); - CookieMonster::CookieList cookies = cookieMonster->GetAllCookies(); - for (CookieMonster::CookieList::const_iterator iter = cookies.begin(); iter != cookies.end(); ++iter) { - if (iter->IsSessionCookie()) - cookieMonster->DeleteCanonicalCookie(*iter); - } -#endif -} - -static void removeSessionCookie(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - removeSessionCookies(WebCookieJar::get(false)); - removeSessionCookies(WebCookieJar::get(true)); -#endif -} - -static void setAcceptCookie(JNIEnv*, jobject, jboolean accept) -{ -#if USE(CHROME_NETWORK_STACK) - // This is a static method which configures the cookie policy for all - // WebViews, so we configure the contexts for both regular and private - // browsing. - WebCookieJar::get(false)->setAllowCookies(accept); - WebCookieJar::get(true)->setAllowCookies(accept); -#endif -} - -static void setCookie(JNIEnv* env, jobject, jstring url, jstring value, jboolean privateBrowsing) -{ -#if USE(CHROME_NETWORK_STACK) - GURL gurl(jstringToStdString(env, url)); - std::string line(jstringToStdString(env, value)); - CookieOptions options; - options.set_include_httponly(); - WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->SetCookieWithOptions(gurl, line, options); -#endif -} - -static void flushCookieStore(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - WebCookieJar::flush(); -#endif -} - -static bool acceptFileSchemeCookies(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - return WebCookieJar::acceptFileSchemeCookies(); -#else - // File scheme cookies are always accepted with the Android HTTP stack. - return true; -#endif -} - -static void setAcceptFileSchemeCookies(JNIEnv*, jobject, jboolean accept) -{ -#if USE(CHROME_NETWORK_STACK) - WebCookieJar::setAcceptFileSchemeCookies(accept); -#else - // File scheme cookies are always accepted with the Android HTTP stack. -#endif -} - -static JNINativeMethod gCookieManagerMethods[] = { - { "nativeAcceptCookie", "()Z", (void*) acceptCookie }, - { "nativeGetCookie", "(Ljava/lang/String;Z)Ljava/lang/String;", (void*) getCookie }, - { "nativeHasCookies", "(Z)Z", (void*) hasCookies }, - { "nativeRemoveAllCookie", "()V", (void*) removeAllCookie }, - { "nativeRemoveExpiredCookie", "()V", (void*) removeExpiredCookie }, - { "nativeRemoveSessionCookie", "()V", (void*) removeSessionCookie }, - { "nativeSetAcceptCookie", "(Z)V", (void*) setAcceptCookie }, - { "nativeSetCookie", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*) setCookie }, - { "nativeFlushCookieStore", "()V", (void*) flushCookieStore }, - { "nativeAcceptFileSchemeCookies", "()Z", (void*) acceptFileSchemeCookies }, - { "nativeSetAcceptFileSchemeCookies", "(Z)V", (void*) setAcceptFileSchemeCookies }, -}; - -int registerCookieManager(JNIEnv* env) -{ -#ifndef NDEBUG - jclass cookieManager = env->FindClass(javaCookieManagerClass); - LOG_ASSERT(cookieManager, "Unable to find class"); - env->DeleteLocalRef(cookieManager); -#endif - return jniRegisterNativeMethods(env, javaCookieManagerClass, gCookieManagerMethods, NELEM(gCookieManagerMethods)); -} - -} // namespace android diff --git a/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp b/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp deleted file mode 100644 index 8beb372..0000000 --- a/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp +++ /dev/null @@ -1,171 +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. - */ - -#include "config.h" -#include "DeviceMotionAndOrientationManager.h" - -#include "DeviceMotionClientImpl.h" -#include "DeviceOrientationClientImpl.h" -#include "DeviceOrientationController.h" -#include "WebViewCore.h" -#include "Frame.h" -#include "Page.h" - -#include <DeviceOrientationClientMock.h> -#include <JNIHelp.h> - -using namespace WebCore; - -namespace android { - -DeviceMotionAndOrientationManager::DeviceMotionAndOrientationManager(WebViewCore* webViewCore) - : m_useMock(false) - , m_webViewCore(webViewCore) -{ -} - -void DeviceMotionAndOrientationManager::useMock() -{ - m_useMock = true; -} - -void DeviceMotionAndOrientationManager::setMockMotion(PassRefPtr<DeviceMotionData> motion) -{ - // TODO: There is not yet a DeviceMotion mock. -} - -void DeviceMotionAndOrientationManager::onMotionChange(PassRefPtr<DeviceMotionData> motion) -{ - ASSERT(!m_useMock); - static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->onMotionChange(motion); -} - -void DeviceMotionAndOrientationManager::setMockOrientation(PassRefPtr<DeviceOrientation> orientation) -{ - if (m_useMock) - static_cast<DeviceOrientationClientMock*>(orientationClient())->setOrientation(orientation); -} - -void DeviceMotionAndOrientationManager::onOrientationChange(PassRefPtr<DeviceOrientation> orientation) -{ - ASSERT(!m_useMock); - static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->onOrientationChange(orientation); -} - -void DeviceMotionAndOrientationManager::maybeSuspendClients() -{ - if (!m_useMock) { - if (m_motionClient) - static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->suspend(); - if (m_orientationClient) - static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->suspend(); - } -} - -void DeviceMotionAndOrientationManager::maybeResumeClients() -{ - if (!m_useMock) { - if (m_motionClient) - static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->resume(); - if (m_orientationClient) - static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->resume(); - } -} - -DeviceMotionClient* DeviceMotionAndOrientationManager::motionClient() -{ - // TODO: There is not yet a DeviceMotion mock. - if (!m_motionClient) - m_motionClient.set(m_useMock ? 0 - : static_cast<DeviceMotionClient*>(new DeviceMotionClientImpl(m_webViewCore))); - ASSERT(m_motionClient); - return m_motionClient.get(); -} - -DeviceOrientationClient* DeviceMotionAndOrientationManager::orientationClient() -{ - if (!m_orientationClient) - m_orientationClient.set(m_useMock ? new DeviceOrientationClientMock - : static_cast<DeviceOrientationClient*>(new DeviceOrientationClientImpl(m_webViewCore))); - ASSERT(m_orientationClient); - return m_orientationClient.get(); -} - -// JNI for android.webkit.DeviceMotionAndOrientationManager -static const char* javaDeviceMotionAndOrientationManagerClass = "android/webkit/DeviceMotionAndOrientationManager"; - -static WebViewCore* getWebViewCore(JNIEnv* env, jobject webViewCoreObject) -{ - jclass webViewCoreClass = env->FindClass("android/webkit/WebViewCore"); - jfieldID nativeClassField = env->GetFieldID(webViewCoreClass, "mNativeClass", "I"); - env->DeleteLocalRef(webViewCoreClass); - return reinterpret_cast<WebViewCore*>(env->GetIntField(webViewCoreObject, nativeClassField)); -} - -static void useMock(JNIEnv* env, jobject, jobject webViewCoreObject) -{ - getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->useMock(); -} - -static void onMotionChange(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideX, double x, bool canProvideY, double y, bool canProvideZ, double z, double interval) -{ - // We only provide accelerationIncludingGravity. - RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z); - bool canProvideInterval = canProvideX || canProvideY || canProvideZ; - RefPtr<DeviceMotionData> motion = DeviceMotionData::create(0, accelerationIncludingGravity.release(), 0, canProvideInterval, interval); - getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->onMotionChange(motion.release()); -} - -static void setMockOrientation(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) -{ - RefPtr<DeviceOrientation> orientation = DeviceOrientation::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma); - getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->setMockOrientation(orientation.release()); -} - -static void onOrientationChange(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) -{ - RefPtr<DeviceOrientation> orientation = DeviceOrientation::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma); - getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->onOrientationChange(orientation.release()); -} - -static JNINativeMethod gDeviceMotionAndOrientationManagerMethods[] = { - { "nativeUseMock", "(Landroid/webkit/WebViewCore;)V", (void*) useMock }, - { "nativeOnMotionChange", "(Landroid/webkit/WebViewCore;ZDZDZDD)V", (void*) onMotionChange }, - { "nativeSetMockOrientation", "(Landroid/webkit/WebViewCore;ZDZDZD)V", (void*) setMockOrientation }, - { "nativeOnOrientationChange", "(Landroid/webkit/WebViewCore;ZDZDZD)V", (void*) onOrientationChange } -}; - -int registerDeviceMotionAndOrientationManager(JNIEnv* env) -{ -#ifndef NDEBUG - jclass deviceMotionAndOrientationManager = env->FindClass(javaDeviceMotionAndOrientationManagerClass); - LOG_ASSERT(deviceMotionAndOrientationManager, "Unable to find class"); - env->DeleteLocalRef(deviceMotionAndOrientationManager); -#endif - - return jniRegisterNativeMethods(env, javaDeviceMotionAndOrientationManagerClass, gDeviceMotionAndOrientationManagerMethods, NELEM(gDeviceMotionAndOrientationManagerMethods)); -} - -} // namespace android diff --git a/WebKit/android/jni/DeviceMotionAndOrientationManager.h b/WebKit/android/jni/DeviceMotionAndOrientationManager.h deleted file mode 100644 index 44463c1..0000000 --- a/WebKit/android/jni/DeviceMotionAndOrientationManager.h +++ /dev/null @@ -1,68 +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 DeviceMotionAndOrientationManager_h -#define DeviceMotionAndOrientationManager_h - -#include <DeviceMotionData.h> -#include <DeviceMotionClient.h> -#include <DeviceOrientation.h> -#include <DeviceOrientationClient.h> -#include <OwnPtr.h> -#include <PassRefPtr.h> -#include <RefPtr.h> - -namespace android { - -class WebViewCore; - -// This class takes care of the fact that the clients used for DeviceMotion and -// DeviceOrientation may be either the real implementations or mocks. It also -// handles setting the data on both the real and mock clients. This class is -// owned by WebViewCore and exists to keep cruft out of that class. -class DeviceMotionAndOrientationManager { -public: - DeviceMotionAndOrientationManager(WebViewCore*); - - void useMock(); - void setMockMotion(PassRefPtr<WebCore::DeviceMotionData>); - void onMotionChange(PassRefPtr<WebCore::DeviceMotionData>); - void setMockOrientation(PassRefPtr<WebCore::DeviceOrientation>); - void onOrientationChange(PassRefPtr<WebCore::DeviceOrientation>); - void maybeSuspendClients(); - void maybeResumeClients(); - WebCore::DeviceMotionClient* motionClient(); - WebCore::DeviceOrientationClient* orientationClient(); - -private: - bool m_useMock; - WebViewCore* m_webViewCore; - OwnPtr<WebCore::DeviceMotionClient> m_motionClient; - OwnPtr<WebCore::DeviceOrientationClient> m_orientationClient; -}; - -} // namespace android - -#endif // DeviceMotionAndOrientationManager_h diff --git a/WebKit/android/jni/DeviceMotionClientImpl.cpp b/WebKit/android/jni/DeviceMotionClientImpl.cpp deleted file mode 100644 index 82f3c35..0000000 --- a/WebKit/android/jni/DeviceMotionClientImpl.cpp +++ /dev/null @@ -1,130 +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. - */ - -#include "config.h" -#include "DeviceMotionClientImpl.h" - -#include "WebViewCore.h" -#include <DeviceMotionController.h> -#include <Frame.h> -#include <JNIHelp.h> - -namespace android { - -using JSC::Bindings::getJNIEnv; - -enum javaServiceClassMethods { - ServiceMethodStart = 0, - ServiceMethodStop, - ServiceMethodSuspend, - ServiceMethodResume, - ServiceMethodCount -}; -static jmethodID javaServiceClassMethodIDs[ServiceMethodCount]; - -DeviceMotionClientImpl::DeviceMotionClientImpl(WebViewCore* webViewCore) - : m_webViewCore(webViewCore) - , m_javaServiceObject(0) -{ - ASSERT(m_webViewCore); -} - -DeviceMotionClientImpl::~DeviceMotionClientImpl() -{ - releaseJavaInstance(); -} - -jobject DeviceMotionClientImpl::getJavaInstance() -{ - // Lazily get the Java object. We can't do this until the WebViewCore is all - // set up. - if (m_javaServiceObject) - return m_javaServiceObject; - - JNIEnv* env = getJNIEnv(); - - ASSERT(m_webViewCore); - jobject object = m_webViewCore->getDeviceMotionService(); - - // Get the Java DeviceMotionService class. - jclass javaServiceClass = env->GetObjectClass(object); - ASSERT(javaServiceClass); - - // Set up the methods we wish to call on the Java DeviceMotionService - // class. - javaServiceClassMethodIDs[ServiceMethodStart] = - env->GetMethodID(javaServiceClass, "start", "()V"); - javaServiceClassMethodIDs[ServiceMethodStop] = - env->GetMethodID(javaServiceClass, "stop", "()V"); - javaServiceClassMethodIDs[ServiceMethodSuspend] = - env->GetMethodID(javaServiceClass, "suspend", "()V"); - javaServiceClassMethodIDs[ServiceMethodResume] = - env->GetMethodID(javaServiceClass, "resume", "()V"); - env->DeleteLocalRef(javaServiceClass); - - m_javaServiceObject = getJNIEnv()->NewGlobalRef(object); - getJNIEnv()->DeleteLocalRef(object); - - ASSERT(m_javaServiceObject); - return m_javaServiceObject; -} - -void DeviceMotionClientImpl::releaseJavaInstance() -{ - ASSERT(m_javaServiceObject); - getJNIEnv()->DeleteGlobalRef(m_javaServiceObject); -} - -void DeviceMotionClientImpl::startUpdating() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaServiceClassMethodIDs[ServiceMethodStart]); -} - -void DeviceMotionClientImpl::stopUpdating() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaServiceClassMethodIDs[ServiceMethodStop]); -} - -void DeviceMotionClientImpl::onMotionChange(PassRefPtr<DeviceMotionData> motion) -{ - m_lastMotion = motion; - m_controller->didChangeDeviceMotion(m_lastMotion.get()); -} - -void DeviceMotionClientImpl::suspend() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaServiceClassMethodIDs[ServiceMethodSuspend]); -} - -void DeviceMotionClientImpl::resume() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaServiceClassMethodIDs[ServiceMethodResume]); -} - -} // namespace android diff --git a/WebKit/android/jni/DeviceMotionClientImpl.h b/WebKit/android/jni/DeviceMotionClientImpl.h deleted file mode 100644 index c979098..0000000 --- a/WebKit/android/jni/DeviceMotionClientImpl.h +++ /dev/null @@ -1,70 +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 DeviceMotionClientImpl_h -#define DeviceMotionClientImpl_h - -#include <DeviceMotionClient.h> -#include <DeviceMotionData.h> -#include <JNIUtility.h> -#include <PassRefPtr.h> -#include <RefPtr.h> - -using namespace WebCore; - -namespace android { - -class DeviceMotionAndOrientationManager; -class WebViewCore; - -class DeviceMotionClientImpl : public DeviceMotionClient { -public: - DeviceMotionClientImpl(WebViewCore*); - virtual ~DeviceMotionClientImpl(); - - void onMotionChange(PassRefPtr<DeviceMotionData>); - void suspend(); - void resume(); - - // DeviceMotionClient methods - virtual void startUpdating(); - virtual void stopUpdating(); - virtual DeviceMotionData* currentDeviceMotion() const { return m_lastMotion.get(); } - virtual void setController(DeviceMotionController* controller) { m_controller = controller; } - virtual void deviceMotionControllerDestroyed() { } - -private: - jobject getJavaInstance(); - void releaseJavaInstance(); - - WebViewCore* m_webViewCore; - jobject m_javaServiceObject; - DeviceMotionController* m_controller; - RefPtr<DeviceMotionData> m_lastMotion; -}; - -} // namespace android - -#endif // DeviceMotionClientImpl_h diff --git a/WebKit/android/jni/DeviceOrientationClientImpl.cpp b/WebKit/android/jni/DeviceOrientationClientImpl.cpp deleted file mode 100644 index bf3b3c3..0000000 --- a/WebKit/android/jni/DeviceOrientationClientImpl.cpp +++ /dev/null @@ -1,130 +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. - */ - -#include "config.h" -#include "DeviceOrientationClientImpl.h" - -#include "WebViewCore.h" -#include <DeviceOrientationController.h> -#include <Frame.h> -#include <JNIHelp.h> - -namespace android { - -using JSC::Bindings::getJNIEnv; - -enum javaDeviceOrientationServiceClassMethods { - DeviceOrientationServiceMethodStart = 0, - DeviceOrientationServiceMethodStop, - DeviceOrientationServiceMethodSuspend, - DeviceOrientationServiceMethodResume, - DeviceOrientationServiceMethodCount -}; -static jmethodID javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodCount]; - -DeviceOrientationClientImpl::DeviceOrientationClientImpl(WebViewCore* webViewCore) - : m_webViewCore(webViewCore) - , m_javaDeviceOrientationServiceObject(0) -{ - ASSERT(m_webViewCore); -} - -DeviceOrientationClientImpl::~DeviceOrientationClientImpl() -{ - releaseJavaInstance(); -} - -jobject DeviceOrientationClientImpl::getJavaInstance() -{ - // Lazily get the Java object. We can't do this until the WebViewCore is all - // set up. - if (m_javaDeviceOrientationServiceObject) - return m_javaDeviceOrientationServiceObject; - - JNIEnv* env = getJNIEnv(); - - ASSERT(m_webViewCore); - jobject object = m_webViewCore->getDeviceOrientationService(); - - // Get the Java DeviceOrientationService class. - jclass javaDeviceOrientationServiceClass = env->GetObjectClass(object); - ASSERT(javaDeviceOrientationServiceClass); - - // Set up the methods we wish to call on the Java DeviceOrientationService - // class. - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodStart] = - env->GetMethodID(javaDeviceOrientationServiceClass, "start", "()V"); - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodStop] = - env->GetMethodID(javaDeviceOrientationServiceClass, "stop", "()V"); - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodSuspend] = - env->GetMethodID(javaDeviceOrientationServiceClass, "suspend", "()V"); - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodResume] = - env->GetMethodID(javaDeviceOrientationServiceClass, "resume", "()V"); - env->DeleteLocalRef(javaDeviceOrientationServiceClass); - - m_javaDeviceOrientationServiceObject = getJNIEnv()->NewGlobalRef(object); - getJNIEnv()->DeleteLocalRef(object); - - ASSERT(m_javaDeviceOrientationServiceObject); - return m_javaDeviceOrientationServiceObject; -} - -void DeviceOrientationClientImpl::releaseJavaInstance() -{ - ASSERT(m_javaDeviceOrientationServiceObject); - getJNIEnv()->DeleteGlobalRef(m_javaDeviceOrientationServiceObject); -} - -void DeviceOrientationClientImpl::startUpdating() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodStart]); -} - -void DeviceOrientationClientImpl::stopUpdating() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodStop]); -} - -void DeviceOrientationClientImpl::onOrientationChange(PassRefPtr<DeviceOrientation> orientation) -{ - m_lastOrientation = orientation; - m_controller->didChangeDeviceOrientation(m_lastOrientation.get()); -} - -void DeviceOrientationClientImpl::suspend() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodSuspend]); -} - -void DeviceOrientationClientImpl::resume() -{ - getJNIEnv()->CallVoidMethod(getJavaInstance(), - javaDeviceOrientationServiceClassMethodIDs[DeviceOrientationServiceMethodResume]); -} - -} // namespace android diff --git a/WebKit/android/jni/DeviceOrientationClientImpl.h b/WebKit/android/jni/DeviceOrientationClientImpl.h deleted file mode 100644 index 0e3f6b3..0000000 --- a/WebKit/android/jni/DeviceOrientationClientImpl.h +++ /dev/null @@ -1,70 +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 DeviceOrientationClientImpl_h -#define DeviceOrientationClientImpl_h - -#include <DeviceOrientation.h> -#include <DeviceOrientationClient.h> -#include <JNIUtility.h> -#include <PassRefPtr.h> -#include <RefPtr.h> - -using namespace WebCore; - -namespace android { - -class DeviceMotionAndOrientationManager; -class WebViewCore; - -class DeviceOrientationClientImpl : public DeviceOrientationClient { -public: - DeviceOrientationClientImpl(WebViewCore*); - virtual ~DeviceOrientationClientImpl(); - - void onOrientationChange(PassRefPtr<DeviceOrientation>); - void suspend(); - void resume(); - - // DeviceOrientationClient methods - virtual void startUpdating(); - virtual void stopUpdating(); - virtual DeviceOrientation* lastOrientation() const { return m_lastOrientation.get(); } - virtual void setController(DeviceOrientationController* controller) { m_controller = controller; } - virtual void deviceOrientationControllerDestroyed() { } - -private: - jobject getJavaInstance(); - void releaseJavaInstance(); - - WebViewCore* m_webViewCore; - jobject m_javaDeviceOrientationServiceObject; - DeviceOrientationController* m_controller; - RefPtr<DeviceOrientation> m_lastOrientation; -}; - -} // namespace android - -#endif // DeviceOrientationClientImpl_h diff --git a/WebKit/android/jni/GeolocationPermissionsBridge.cpp b/WebKit/android/jni/GeolocationPermissionsBridge.cpp deleted file mode 100755 index a366601..0000000 --- a/WebKit/android/jni/GeolocationPermissionsBridge.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 <JNIHelp.h> // For jniRegisterNativeMethods -#include "GeolocationPermissions.h" -#include "WebCoreJni.h" // For jstringToWtfString - - -/** - * This file provides a set of functions to bridge between the Java and C++ - * GeolocationPermissions classes. The java GeolocationPermissions object calls - * the functions provided here, which in turn call static methods on the C++ - * GeolocationPermissions class. - */ - -namespace android { - -static jobject getOrigins(JNIEnv* env, jobject obj) -{ - GeolocationPermissions::OriginSet origins = GeolocationPermissions::getOrigins(); - - jclass setClass = env->FindClass("java/util/HashSet"); - jmethodID constructor = env->GetMethodID(setClass, "<init>", "()V"); - jmethodID addMethod = env->GetMethodID(setClass, "add", "(Ljava/lang/Object;)Z"); - jobject set = env->NewObject(setClass, constructor); - env->DeleteLocalRef(setClass); - - GeolocationPermissions::OriginSet::const_iterator end = origins.end(); - for (GeolocationPermissions::OriginSet::const_iterator iter = origins.begin(); iter != end; ++iter) { - jstring originString = wtfStringToJstring(env, *iter); - env->CallBooleanMethod(set, addMethod, originString); - env->DeleteLocalRef(originString); - } - return set; -} - -static bool getAllowed(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originString = jstringToWtfString(env, origin); - return GeolocationPermissions::getAllowed(originString); -} - -static void clear(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originString = jstringToWtfString(env, origin); - GeolocationPermissions::clear(originString); -} - -static void allow(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originString = jstringToWtfString(env, origin); - GeolocationPermissions::allow(originString); -} - -static void clearAll(JNIEnv* env, jobject obj) -{ - GeolocationPermissions::clearAll(); -} - -/* - * JNI registration - */ -static JNINativeMethod gGeolocationPermissionsMethods[] = { - { "nativeGetOrigins", "()Ljava/util/Set;", - (void*) getOrigins }, - { "nativeGetAllowed", "(Ljava/lang/String;)Z", - (void*) getAllowed }, - { "nativeClear", "(Ljava/lang/String;)V", - (void*) clear }, - { "nativeAllow", "(Ljava/lang/String;)V", - (void*) allow }, - { "nativeClearAll", "()V", - (void*) clearAll } -}; - -int registerGeolocationPermissions(JNIEnv* env) -{ - const char* kGeolocationPermissionsClass = "android/webkit/GeolocationPermissions"; -#ifndef NDEBUG - jclass geolocationPermissions = env->FindClass(kGeolocationPermissionsClass); - LOG_ASSERT(geolocationPermissions, "Unable to find class"); - env->DeleteLocalRef(geolocationPermissions); -#endif - - return jniRegisterNativeMethods(env, kGeolocationPermissionsClass, - gGeolocationPermissionsMethods, NELEM(gGeolocationPermissionsMethods)); -} - -} diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp deleted file mode 100644 index 2fa12fc..0000000 --- a/WebKit/android/jni/JavaBridge.cpp +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright 2006, 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 "webcoreglue" - -#include "config.h" - -#include "MemoryCache.h" -#include "Connection.h" -#include "CookieClient.h" -#include "FileSystemClient.h" -#include "JavaSharedClient.h" -#include "KeyGeneratorClient.h" -#include "KURL.h" -#include "NetworkStateNotifier.h" -#include "PackageNotifier.h" -#include "Page.h" -#include "PluginClient.h" -#include "PluginDatabase.h" -#include "Timer.h" -#include "TimerClient.h" -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif -#include "WebCache.h" -#include "WebCoreJni.h" - -#include <JNIHelp.h> -#include <JNIUtility.h> -#include <SkUtils.h> -#include <jni.h> -#include <utils/misc.h> -#include <wtf/Platform.h> -#include <wtf/StdLibExtras.h> -#include <wtf/text/AtomicString.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -static jfieldID gJavaBridge_ObjectID; - -// ---------------------------------------------------------------------------- - -class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient, public FileSystemClient -{ -public: - JavaBridge(JNIEnv* env, jobject obj); - virtual ~JavaBridge(); - - /* - * WebCore -> Java API - */ - virtual void setSharedTimer(long long timemillis); - virtual void stopSharedTimer(); - - virtual void setCookies(WebCore::KURL const& url, WTF::String const& value); - virtual WTF::String cookies(WebCore::KURL const& url); - virtual bool cookiesEnabled(); - - virtual WTF::Vector<WTF::String> getPluginDirectories(); - virtual WTF::String getPluginSharedDataDirectory(); - - virtual WTF::Vector<String> getSupportedKeyStrengthList(); - virtual WTF::String getSignedPublicKeyAndChallengeString(unsigned index, - const WTF::String& challenge, const WebCore::KURL& url); - virtual WTF::String resolveFilePathForContentUri(const WTF::String& uri); - - //////////////////////////////////////////// - - virtual void setSharedTimerCallback(void (*f)()); - - //////////////////////////////////////////// - - virtual void signalServiceFuncPtrQueue(); - - // jni functions - static void Constructor(JNIEnv* env, jobject obj); - static void Finalize(JNIEnv* env, jobject obj); - static void SharedTimerFired(JNIEnv* env, jobject); - static void SetCacheSize(JNIEnv* env, jobject obj, jint bytes); - static void SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online); - static void SetNetworkType(JNIEnv* env, jobject obj, jstring type, jstring subtype); - static void SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer); - static void ServiceFuncPtrQueue(JNIEnv*); - static void UpdatePluginDirectories(JNIEnv* env, jobject obj, jobjectArray array, jboolean reload); - static void AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames); - static void AddPackageName(JNIEnv* env, jobject obj, jstring packageName); - static void RemovePackageName(JNIEnv* env, jobject obj, jstring packageName); - static void UpdateProxy(JNIEnv* env, jobject obj, jstring newProxy); - - -private: - jweak mJavaObject; - jmethodID mSetSharedTimer; - jmethodID mStopSharedTimer; - jmethodID mSetCookies; - jmethodID mCookies; - jmethodID mCookiesEnabled; - jmethodID mGetPluginDirectories; - jmethodID mGetPluginSharedDataDirectory; - jmethodID mSignalFuncPtrQueue; - jmethodID mGetKeyStrengthList; - jmethodID mGetSignedPublicKey; - jmethodID mResolveFilePathForContentUri; - AutoJObject javaObject(JNIEnv* env) { return getRealObject(env, mJavaObject); } -}; - -static void (*sSharedTimerFiredCallback)(); - -JavaBridge::JavaBridge(JNIEnv* env, jobject obj) -{ - mJavaObject = env->NewWeakGlobalRef(obj); - jclass clazz = env->GetObjectClass(obj); - - mSetSharedTimer = env->GetMethodID(clazz, "setSharedTimer", "(J)V"); - mStopSharedTimer = env->GetMethodID(clazz, "stopSharedTimer", "()V"); - mSetCookies = env->GetMethodID(clazz, "setCookies", "(Ljava/lang/String;Ljava/lang/String;)V"); - mCookies = env->GetMethodID(clazz, "cookies", "(Ljava/lang/String;)Ljava/lang/String;"); - mCookiesEnabled = env->GetMethodID(clazz, "cookiesEnabled", "()Z"); - mGetPluginDirectories = env->GetMethodID(clazz, "getPluginDirectories", "()[Ljava/lang/String;"); - mGetPluginSharedDataDirectory = env->GetMethodID(clazz, "getPluginSharedDataDirectory", "()Ljava/lang/String;"); - mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V"); - mGetKeyStrengthList = env->GetMethodID(clazz, "getKeyStrengthList", "()[Ljava/lang/String;"); - mGetSignedPublicKey = env->GetMethodID(clazz, "getSignedPublicKey", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - mResolveFilePathForContentUri = env->GetMethodID(clazz, "resolveFilePathForContentUri", "(Ljava/lang/String;)Ljava/lang/String;"); - env->DeleteLocalRef(clazz); - - LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer"); - LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer"); - LOG_ASSERT(mSetCookies, "Could not find method setCookies"); - LOG_ASSERT(mCookies, "Could not find method cookies"); - LOG_ASSERT(mCookiesEnabled, "Could not find method cookiesEnabled"); - LOG_ASSERT(mGetPluginDirectories, "Could not find method getPluginDirectories"); - LOG_ASSERT(mGetPluginSharedDataDirectory, "Could not find method getPluginSharedDataDirectory"); - LOG_ASSERT(mGetKeyStrengthList, "Could not find method getKeyStrengthList"); - LOG_ASSERT(mGetSignedPublicKey, "Could not find method getSignedPublicKey"); - - JavaSharedClient::SetTimerClient(this); - JavaSharedClient::SetCookieClient(this); - JavaSharedClient::SetPluginClient(this); - JavaSharedClient::SetKeyGeneratorClient(this); - JavaSharedClient::SetFileSystemClient(this); -} - -JavaBridge::~JavaBridge() -{ - if (mJavaObject) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->DeleteWeakGlobalRef(mJavaObject); - mJavaObject = 0; - } - - JavaSharedClient::SetTimerClient(NULL); - JavaSharedClient::SetCookieClient(NULL); - JavaSharedClient::SetPluginClient(NULL); - JavaSharedClient::SetKeyGeneratorClient(NULL); - JavaSharedClient::SetFileSystemClient(NULL); -} - -void -JavaBridge::setSharedTimer(long long timemillis) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - env->CallVoidMethod(obj.get(), mSetSharedTimer, timemillis); -} - -void -JavaBridge::stopSharedTimer() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - env->CallVoidMethod(obj.get(), mStopSharedTimer); -} - -void -JavaBridge::setCookies(WebCore::KURL const& url, WTF::String const& value) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - const WTF::String& urlStr = url.string(); - jstring jUrlStr = wtfStringToJstring(env, urlStr); - jstring jValueStr = wtfStringToJstring(env, value); - - AutoJObject obj = javaObject(env); - env->CallVoidMethod(obj.get(), mSetCookies, jUrlStr, jValueStr); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jValueStr); -} - -WTF::String -JavaBridge::cookies(WebCore::KURL const& url) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - const WTF::String& urlStr = url.string(); - jstring jUrlStr = wtfStringToJstring(env, urlStr); - - AutoJObject obj = javaObject(env); - jstring string = (jstring)(env->CallObjectMethod(obj.get(), mCookies, jUrlStr)); - - WTF::String ret = jstringToWtfString(env, string); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(string); - return ret; -} - -bool -JavaBridge::cookiesEnabled() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - jboolean ret = env->CallBooleanMethod(obj.get(), mCookiesEnabled); - return (ret != 0); -} - -WTF::Vector<WTF::String> -JavaBridge::getPluginDirectories() -{ - WTF::Vector<WTF::String> directories; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - jobjectArray array = (jobjectArray) - env->CallObjectMethod(obj.get(), mGetPluginDirectories); - int count = env->GetArrayLength(array); - for (int i = 0; i < count; i++) { - jstring dir = (jstring) env->GetObjectArrayElement(array, i); - directories.append(jstringToWtfString(env, dir)); - env->DeleteLocalRef(dir); - } - env->DeleteLocalRef(array); - checkException(env); - return directories; -} - -WTF::String -JavaBridge::getPluginSharedDataDirectory() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - jstring ret = (jstring)env->CallObjectMethod(obj.get(), mGetPluginSharedDataDirectory); - WTF::String path = jstringToWtfString(env, ret); - checkException(env); - return path; -} - -void -JavaBridge::setSharedTimerCallback(void (*f)()) -{ - LOG_ASSERT(!sSharedTimerFiredCallback || sSharedTimerFiredCallback==f, - "Shared timer callback may already be set or null!"); - - sSharedTimerFiredCallback = f; -} - -void JavaBridge::signalServiceFuncPtrQueue() -{ - // In order to signal the main thread we must go through JNI. This - // is the only usage on most threads, so we need to ensure a JNI - // environment is setup. - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue); -} - -WTF::Vector<WTF::String>JavaBridge::getSupportedKeyStrengthList() { - WTF::Vector<WTF::String> list; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = javaObject(env); - jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(), - mGetKeyStrengthList); - int count = env->GetArrayLength(array); - for (int i = 0; i < count; ++i) { - jstring keyStrength = (jstring) env->GetObjectArrayElement(array, i); - list.append(jstringToWtfString(env, keyStrength)); - env->DeleteLocalRef(keyStrength); - } - env->DeleteLocalRef(array); - checkException(env); - return list; -} - -WTF::String JavaBridge::getSignedPublicKeyAndChallengeString(unsigned index, - const WTF::String& challenge, const WebCore::KURL& url) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jChallenge = wtfStringToJstring(env, challenge); - const WTF::String& urlStr = url.string(); - jstring jUrl = wtfStringToJstring(env, urlStr); - AutoJObject obj = javaObject(env); - jstring key = (jstring) env->CallObjectMethod(obj.get(), - mGetSignedPublicKey, index, jChallenge, jUrl); - WTF::String ret = jstringToWtfString(env, key); - env->DeleteLocalRef(jChallenge); - env->DeleteLocalRef(jUrl); - env->DeleteLocalRef(key); - return ret; -} - -WTF::String JavaBridge::resolveFilePathForContentUri(const WTF::String& uri) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jUri = wtfStringToJstring(env, uri); - AutoJObject obj = javaObject(env); - jstring path = static_cast<jstring>(env->CallObjectMethod(obj.get(), mResolveFilePathForContentUri, jUri)); - WTF::String ret = jstringToWtfString(env, path); - env->DeleteLocalRef(jUri); - env->DeleteLocalRef(path); - return ret; -} - -// ---------------------------------------------------------------------------- - -void JavaBridge::Constructor(JNIEnv* env, jobject obj) -{ - JavaBridge* javaBridge = new JavaBridge(env, obj); - env->SetIntField(obj, gJavaBridge_ObjectID, (jint)javaBridge); -} - -void JavaBridge::Finalize(JNIEnv* env, jobject obj) -{ - JavaBridge* javaBridge = (JavaBridge*) - (env->GetIntField(obj, gJavaBridge_ObjectID)); - LOG_ASSERT(javaBridge, "Finalize should not be called twice for the same java bridge!"); - LOGV("webcore_javabridge::nativeFinalize(%p)\n", javaBridge); - delete javaBridge; - env->SetIntField(obj, gJavaBridge_ObjectID, 0); -} - -// we don't use the java bridge object, as we're just looking at a global -void JavaBridge::SharedTimerFired(JNIEnv* env, jobject) -{ - if (sSharedTimerFiredCallback) - { -#ifdef ANDROID_INSTRUMENT - TimeCounter::start(TimeCounter::SharedTimerTimeCounter); -#endif - SkAutoMemoryUsageProbe mup("JavaBridge::sharedTimerFired"); - sSharedTimerFiredCallback(); -#ifdef ANDROID_INSTRUMENT - TimeCounter::record(TimeCounter::SharedTimerTimeCounter, __FUNCTION__); -#endif - } -} - -void JavaBridge::SetCacheSize(JNIEnv* env, jobject obj, jint bytes) -{ - WebCore::cache()->setCapacities(0, bytes/2, bytes); -} - -void JavaBridge::SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online) -{ - WebCore::networkStateNotifier().networkStateChange(online); -} - -void JavaBridge::SetNetworkType(JNIEnv* env, jobject obj, jstring javatype, jstring javasubtype) -{ - DEFINE_STATIC_LOCAL(AtomicString, wifi, ("wifi")); - DEFINE_STATIC_LOCAL(AtomicString, mobile, ("mobile")); - DEFINE_STATIC_LOCAL(AtomicString, mobileSupl, ("mobile_supl")); - DEFINE_STATIC_LOCAL(AtomicString, gprs, ("gprs")); - DEFINE_STATIC_LOCAL(AtomicString, edge, ("edge")); - DEFINE_STATIC_LOCAL(AtomicString, umts, ("umts")); - - String type = jstringToWtfString(env, javatype); - String subtype = jstringToWtfString(env, javasubtype); - Connection::ConnectionType connectionType = Connection::UNKNOWN; - if (type == wifi) - connectionType = Connection::WIFI; - else if (type == mobile || type == mobileSupl) { - if (subtype == edge || subtype == gprs) - connectionType = Connection::CELL_2G; - else if (subtype == umts) - connectionType = Connection::CELL_3G; - } - WebCore::networkStateNotifier().networkTypeChange(connectionType); -} - -void JavaBridge::ServiceFuncPtrQueue(JNIEnv*) -{ - JavaSharedClient::ServiceFunctionPtrQueue(); -} - -void JavaBridge::UpdatePluginDirectories(JNIEnv* env, jobject obj, - jobjectArray array, jboolean reload) { - WTF::Vector<WTF::String> directories; - int count = env->GetArrayLength(array); - for (int i = 0; i < count; i++) { - jstring dir = (jstring) env->GetObjectArrayElement(array, i); - directories.append(jstringToWtfString(env, dir)); - env->DeleteLocalRef(dir); - } - checkException(env); - WebCore::PluginDatabase *pluginDatabase = - WebCore::PluginDatabase::installedPlugins(); - pluginDatabase->setPluginDirectories(directories); - // refreshPlugins() should refresh both PluginDatabase and Page's PluginData - WebCore::Page::refreshPlugins(reload); -} - -void JavaBridge::AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames) -{ - if (!packageNames) - return; - - // dalvikvm will raise exception if any of these fail - jclass setClass = env->FindClass("java/util/Set"); - jmethodID iterator = env->GetMethodID(setClass, "iterator", - "()Ljava/util/Iterator;"); - jobject iter = env->CallObjectMethod(packageNames, iterator); - - jclass iteratorClass = env->FindClass("java/util/Iterator"); - jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z"); - jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;"); - - HashSet<WTF::String> namesSet; - while (env->CallBooleanMethod(iter, hasNext)) { - jstring name = static_cast<jstring>(env->CallObjectMethod(iter, next)); - namesSet.add(jstringToWtfString(env, name)); - env->DeleteLocalRef(name); - } - - packageNotifier().addPackageNames(namesSet); - - env->DeleteLocalRef(iteratorClass); - env->DeleteLocalRef(iter); - env->DeleteLocalRef(setClass); -} - -void JavaBridge::AddPackageName(JNIEnv* env, jobject obj, jstring packageName) -{ - packageNotifier().addPackageName(jstringToWtfString(env, packageName)); -} - -void JavaBridge::RemovePackageName(JNIEnv* env, jobject obj, jstring packageName) -{ - packageNotifier().removePackageName(jstringToWtfString(env, packageName)); -} - -void JavaBridge::UpdateProxy(JNIEnv* env, jobject obj, jstring newProxy) -{ -#if USE(CHROME_NETWORK_STACK) - std::string proxy = jstringToStdString(env, newProxy); - WebCache::get(false)->proxy()->UpdateProxySettings(proxy); - WebCache::get(true)->proxy()->UpdateProxySettings(proxy); -#endif -} - - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gWebCoreJavaBridgeMethods[] = { - /* name, signature, funcPtr */ - { "nativeConstructor", "()V", - (void*) JavaBridge::Constructor }, - { "nativeFinalize", "()V", - (void*) JavaBridge::Finalize }, - { "sharedTimerFired", "()V", - (void*) JavaBridge::SharedTimerFired }, - { "setCacheSize", "(I)V", - (void*) JavaBridge::SetCacheSize }, - { "setNetworkOnLine", "(Z)V", - (void*) JavaBridge::SetNetworkOnLine }, - { "setNetworkType", "(Ljava/lang/String;Ljava/lang/String;)V", - (void*) JavaBridge::SetNetworkType }, - { "nativeServiceFuncPtrQueue", "()V", - (void*) JavaBridge::ServiceFuncPtrQueue }, - { "nativeUpdatePluginDirectories", "([Ljava/lang/String;Z)V", - (void*) JavaBridge::UpdatePluginDirectories }, - { "addPackageNames", "(Ljava/util/Set;)V", - (void*) JavaBridge::AddPackageNames }, - { "addPackageName", "(Ljava/lang/String;)V", - (void*) JavaBridge::AddPackageName }, - { "removePackageName", "(Ljava/lang/String;)V", - (void*) JavaBridge::RemovePackageName }, - { "updateProxy", "(Ljava/lang/String;)V", - (void*) JavaBridge::UpdateProxy } -}; - -int registerJavaBridge(JNIEnv* env) -{ - jclass javaBridge = env->FindClass("android/webkit/JWebCoreJavaBridge"); - LOG_FATAL_IF(javaBridge == NULL, "Unable to find class android/webkit/JWebCoreJavaBridge"); - gJavaBridge_ObjectID = env->GetFieldID(javaBridge, "mNativeBridge", "I"); - LOG_FATAL_IF(gJavaBridge_ObjectID == NULL, "Unable to find android/webkit/JWebCoreJavaBridge.mNativeBridge"); - env->DeleteLocalRef(javaBridge); - - return jniRegisterNativeMethods(env, "android/webkit/JWebCoreJavaBridge", - gWebCoreJavaBridgeMethods, NELEM(gWebCoreJavaBridgeMethods)); -} - -} /* namespace android */ diff --git a/WebKit/android/jni/JavaSharedClient.cpp b/WebKit/android/jni/JavaSharedClient.cpp deleted file mode 100644 index e884c99..0000000 --- a/WebKit/android/jni/JavaSharedClient.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2007, 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 "FileSystemClient.h" -#include "JavaSharedClient.h" -#include "TimerClient.h" -#include "SkDeque.h" -#include "SkThread.h" - -namespace android { - TimerClient* JavaSharedClient::GetTimerClient() - { - return gTimerClient; - } - - CookieClient* JavaSharedClient::GetCookieClient() - { - return gCookieClient; - } - - PluginClient* JavaSharedClient::GetPluginClient() - { - return gPluginClient; - } - - KeyGeneratorClient* JavaSharedClient::GetKeyGeneratorClient() - { - return gKeyGeneratorClient; - } - - FileSystemClient* JavaSharedClient::GetFileSystemClient() - { - return gFileSystemClient; - } - - void JavaSharedClient::SetTimerClient(TimerClient* client) - { - gTimerClient = client; - } - - void JavaSharedClient::SetCookieClient(CookieClient* client) - { - gCookieClient = client; - } - - void JavaSharedClient::SetPluginClient(PluginClient* client) - { - gPluginClient = client; - } - - void JavaSharedClient::SetKeyGeneratorClient(KeyGeneratorClient* client) - { - gKeyGeneratorClient = client; - } - - void JavaSharedClient::SetFileSystemClient(FileSystemClient* client) - { - gFileSystemClient = client; - } - - TimerClient* JavaSharedClient::gTimerClient = NULL; - CookieClient* JavaSharedClient::gCookieClient = NULL; - PluginClient* JavaSharedClient::gPluginClient = NULL; - KeyGeneratorClient* JavaSharedClient::gKeyGeneratorClient = NULL; - FileSystemClient* JavaSharedClient::gFileSystemClient = NULL; - - /////////////////////////////////////////////////////////////////////////// - - struct FuncPtrRec { - void (*fProc)(void* payload); - void* fPayload; - }; - - static SkMutex gFuncPtrQMutex; - static SkDeque gFuncPtrQ(sizeof(FuncPtrRec)); - - void JavaSharedClient::EnqueueFunctionPtr(void (*proc)(void* payload), - void* payload) - { - gFuncPtrQMutex.acquire(); - - FuncPtrRec* rec = (FuncPtrRec*)gFuncPtrQ.push_back(); - rec->fProc = proc; - rec->fPayload = payload; - - gFuncPtrQMutex.release(); - - gTimerClient->signalServiceFuncPtrQueue(); - } - - void JavaSharedClient::ServiceFunctionPtrQueue() - { - for (;;) { - void (*proc)(void*) = 0; - void* payload = 0; - const FuncPtrRec* rec; - - // we have to copy the proc/payload (if present). we do this so we - // don't call the proc inside the mutex (possible deadlock!) - gFuncPtrQMutex.acquire(); - rec = (const FuncPtrRec*)gFuncPtrQ.front(); - if (rec) { - proc = rec->fProc; - payload = rec->fPayload; - gFuncPtrQ.pop_front(); - } - gFuncPtrQMutex.release(); - - if (!rec) - break; - proc(payload); - } - } -} diff --git a/WebKit/android/jni/JavaSharedClient.h b/WebKit/android/jni/JavaSharedClient.h deleted file mode 100644 index 9a09280..0000000 --- a/WebKit/android/jni/JavaSharedClient.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2007, 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 JAVA_SHARED_CLIENT_H -#define JAVA_SHARED_CLIENT_H - -namespace android { - - class TimerClient; - class CookieClient; - class PluginClient; - class KeyGeneratorClient; - class FileSystemClient; - - class JavaSharedClient - { - public: - static TimerClient* GetTimerClient(); - static CookieClient* GetCookieClient(); - static PluginClient* GetPluginClient(); - static KeyGeneratorClient* GetKeyGeneratorClient(); - static FileSystemClient* GetFileSystemClient(); - - static void SetTimerClient(TimerClient* client); - static void SetCookieClient(CookieClient* client); - static void SetPluginClient(PluginClient* client); - static void SetKeyGeneratorClient(KeyGeneratorClient* client); - static void SetFileSystemClient(FileSystemClient* client); - - // can be called from any thread, to be executed in webkit thread - static void EnqueueFunctionPtr(void (*proc)(void*), void* payload); - // only call this from webkit thread - static void ServiceFunctionPtrQueue(); - - private: - static TimerClient* gTimerClient; - static CookieClient* gCookieClient; - static PluginClient* gPluginClient; - static KeyGeneratorClient* gKeyGeneratorClient; - static FileSystemClient* gFileSystemClient; - }; -} -#endif diff --git a/WebKit/android/jni/JniUtil.cpp b/WebKit/android/jni/JniUtil.cpp deleted file mode 100644 index ee1e3f9..0000000 --- a/WebKit/android/jni/JniUtil.cpp +++ /dev/null @@ -1,58 +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. - */ - -#include "config.h" - -#include "ChromiumIncludes.h" -#include <JNIHelp.h> - -namespace android { - -static const char* javaJniUtilClass = "android/webkit/JniUtil"; - -static bool useChromiumHttpStack(JNIEnv*, jobject) -{ -#if USE(CHROME_NETWORK_STACK) - return true; -#else - return false; -#endif -} - -static JNINativeMethod gJniUtilMethods[] = { - { "nativeUseChromiumHttpStack", "()Z", (void*) useChromiumHttpStack }, -}; - -int registerJniUtil(JNIEnv* env) -{ -#ifndef NDEBUG - jclass jniUtil = env->FindClass(javaJniUtilClass); - LOG_ASSERT(jniUtil, "Unable to find class"); - env->DeleteLocalRef(jniUtil); -#endif - return jniRegisterNativeMethods(env, javaJniUtilClass, gJniUtilMethods, NELEM(gJniUtilMethods)); -} - -} // namespace android diff --git a/WebKit/android/jni/MIMETypeRegistry.cpp b/WebKit/android/jni/MIMETypeRegistry.cpp deleted file mode 100644 index 40f8cef..0000000 --- a/WebKit/android/jni/MIMETypeRegistry.cpp +++ /dev/null @@ -1,67 +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 "WebCore" - -#include "config.h" -#include "MIMETypeRegistry.h" - -#include "PlatformString.h" -#include "WebCoreJni.h" - -#include <JNIUtility.h> -#include <jni.h> -#include <utils/Log.h> - -using namespace android; - -namespace WebCore { - -String MIMETypeRegistry::getMIMETypeForExtension(const String& ext) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass mimeClass = env->FindClass("android/webkit/MimeTypeMap"); - LOG_ASSERT(mimeClass, "Could not find class MimeTypeMap"); - jmethodID mimeTypeFromExtension = env->GetStaticMethodID(mimeClass, - "mimeTypeFromExtension", - "(Ljava/lang/String;)Ljava/lang/String;"); - LOG_ASSERT(mimeTypeFromExtension, - "Could not find method mimeTypeFromExtension"); - jstring extString = wtfStringToJstring(env, ext); - jobject mimeType = env->CallStaticObjectMethod(mimeClass, - mimeTypeFromExtension, extString); - String result = android::jstringToWtfString(env, (jstring) mimeType); - env->DeleteLocalRef(mimeClass); - env->DeleteLocalRef(extString); - env->DeleteLocalRef(mimeType); - return result; -} - -bool MIMETypeRegistry::isApplicationPluginMIMEType(const String&) -{ - return false; -} - -} diff --git a/WebKit/android/jni/MockGeolocation.cpp b/WebKit/android/jni/MockGeolocation.cpp deleted file mode 100755 index 1370715..0000000 --- a/WebKit/android/jni/MockGeolocation.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// The functions in this file are used to configure the mock GeolocationService -// 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 <wtf/CurrentTime.h> - -using namespace WebCore; - -namespace android { - -static const char* javaMockGeolocationClass = "android/webkit/MockGeolocation"; - -static void setPosition(JNIEnv* env, jobject, double latitude, double longitude, double accuracy) -{ - 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()); -} - -static void setError(JNIEnv* env, jobject, int code, jstring message) -{ - PositionError::ErrorCode codeEnum = static_cast<PositionError::ErrorCode>(code); - String messageString = jstringToWtfString(env, message); - RefPtr<PositionError> error = PositionError::create(codeEnum, messageString); - GeolocationServiceMock::setError(error.release()); -} - -static JNINativeMethod gMockGeolocationMethods[] = { - { "nativeSetPosition", "(DDD)V", (void*) setPosition }, - { "nativeSetError", "(ILjava/lang/String;)V", (void*) setError } -}; - -int registerMockGeolocation(JNIEnv* env) -{ -#ifndef NDEBUG - jclass mockGeolocation = env->FindClass(javaMockGeolocationClass); - LOG_ASSERT(mockGeolocation, "Unable to find class"); - env->DeleteLocalRef(mockGeolocation); -#endif - - return jniRegisterNativeMethods(env, javaMockGeolocationClass, gMockGeolocationMethods, NELEM(gMockGeolocationMethods)); -} - -} diff --git a/WebKit/android/jni/PictureSet.cpp b/WebKit/android/jni/PictureSet.cpp deleted file mode 100644 index 6dafd26..0000000 --- a/WebKit/android/jni/PictureSet.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright 2008, 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_NDEBUG 0 -#define LOG_TAG "pictureset" - -//#include <config.h> -#include "CachedPrefix.h" -#include "android_graphics.h" -#include "PictureSet.h" -#include "SkBounder.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "SkStream.h" -#include "TimeCounter.h" - -#define MAX_DRAW_TIME 100 -#define MIN_SPLITTABLE 400 - -#if PICTURE_SET_DEBUG -class MeasureStream : public SkWStream { -public: - MeasureStream() : mTotal(0) {} - virtual bool write(const void* , size_t size) { - mTotal += size; - return true; - } - size_t mTotal; -}; -#endif - -namespace android { - -PictureSet::PictureSet() -{ - mWidth = mHeight = 0; -} - -PictureSet::~PictureSet() -{ - clear(); -} - -void PictureSet::add(const Pictures* temp) -{ - Pictures pictureAndBounds = *temp; - SkSafeRef(pictureAndBounds.mPicture); - pictureAndBounds.mWroteElapsed = false; - mPictures.append(pictureAndBounds); -} - -void PictureSet::add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split, bool empty) -{ - DBG_SET_LOGD("%p area={%d,%d,r=%d,b=%d} pict=%p elapsed=%d split=%d", this, - area.getBounds().fLeft, area.getBounds().fTop, - area.getBounds().fRight, area.getBounds().fBottom, picture, - elapsed, split); - SkSafeRef(picture); - /* if nothing is drawn beneath part of the new picture, mark it as a base */ - SkRegion diff = SkRegion(area); - Pictures* last = mPictures.end(); - for (Pictures* working = mPictures.begin(); working != last; working++) - diff.op(working->mArea, SkRegion::kDifference_Op); - Pictures pictureAndBounds = {area, picture, area.getBounds(), - elapsed, split, false, diff.isEmpty() == false, empty}; - mPictures.append(pictureAndBounds); -} - -/* -Pictures are discarded when they are fully drawn over. -When a picture is partially drawn over, it is discarded if it is not a base, and -its rectangular bounds is reduced if it is a base. -*/ -bool PictureSet::build() -{ - bool rebuild = false; - DBG_SET_LOGD("%p", this); - // walk pictures back to front, removing or trimming obscured ones - SkRegion drawn; - SkRegion inval; - Pictures* first = mPictures.begin(); - Pictures* last = mPictures.end(); - Pictures* working; - bool checkForNewBases = false; - for (working = last; working != first; ) { - --working; - SkRegion& area = working->mArea; - SkRegion visibleArea(area); - visibleArea.op(drawn, SkRegion::kDifference_Op); -#if PICTURE_SET_DEBUG - const SkIRect& a = area.getBounds(); - const SkIRect& d = drawn.getBounds(); - const SkIRect& i = inval.getBounds(); - const SkIRect& v = visibleArea.getBounds(); - DBG_SET_LOGD("%p [%d] area={%d,%d,r=%d,b=%d} drawn={%d,%d,r=%d,b=%d}" - " inval={%d,%d,r=%d,b=%d} vis={%d,%d,r=%d,b=%d}", - this, working - first, - a.fLeft, a.fTop, a.fRight, a.fBottom, - d.fLeft, d.fTop, d.fRight, d.fBottom, - i.fLeft, i.fTop, i.fRight, i.fBottom, - v.fLeft, v.fTop, v.fRight, v.fBottom); -#endif - bool tossPicture = false; - if (working->mBase == false) { - if (area != visibleArea) { - if (visibleArea.isEmpty() == false) { - DBG_SET_LOGD("[%d] partially overdrawn", working - first); - inval.op(visibleArea, SkRegion::kUnion_Op); - } else - DBG_SET_LOGD("[%d] fully hidden", working - first); - area.setEmpty(); - tossPicture = true; - } - } else { - const SkIRect& visibleBounds = visibleArea.getBounds(); - const SkIRect& areaBounds = area.getBounds(); - if (visibleBounds != areaBounds) { - DBG_SET_LOGD("[%d] base to be reduced", working - first); - area.setRect(visibleBounds); - checkForNewBases = tossPicture = true; - } - if (area.intersects(inval)) { - DBG_SET_LOGD("[%d] base to be redrawn", working - first); - tossPicture = true; - } - } - if (tossPicture) { - SkSafeUnref(working->mPicture); - working->mPicture = NULL; // mark to redraw - } - if (working->mPicture == NULL) // may have been set to null elsewhere - rebuild = true; - drawn.op(area, SkRegion::kUnion_Op); - } - // collapse out empty regions - Pictures* writer = first; - for (working = first; working != last; working++) { - if (working->mArea.isEmpty()) - continue; - *writer++ = *working; - } -#if PICTURE_SET_DEBUG - if ((unsigned) (writer - first) != mPictures.size()) - DBG_SET_LOGD("shrink=%d (was %d)", writer - first, mPictures.size()); -#endif - mPictures.shrink(writer - first); - /* When a base is discarded because it was entirely drawn over, all - remaining pictures are checked to see if one has become a base. */ - if (checkForNewBases) { - drawn.setEmpty(); - Pictures* last = mPictures.end(); - for (working = mPictures.begin(); working != last; working++) { - SkRegion& area = working->mArea; - if (drawn.contains(working->mArea) == false) { - working->mBase = true; - DBG_SET_LOGD("[%d] new base", working - mPictures.begin()); - } - drawn.op(working->mArea, SkRegion::kUnion_Op); - } - } - validate(__FUNCTION__); - return rebuild; -} - -void PictureSet::checkDimensions(int width, int height, SkRegion* inval) -{ - if (mWidth == width && mHeight == height) - return; - DBG_SET_LOGD("%p old:(w=%d,h=%d) new:(w=%d,h=%d)", this, - mWidth, mHeight, width, height); - if (mWidth == width && height > mHeight) { // only grew vertically - SkIRect rect; - rect.set(0, mHeight, width, height - mHeight); - inval->op(rect, SkRegion::kUnion_Op); - } else { - clear(); // if both width/height changed, clear the old cache - inval->setRect(0, 0, width, height); - } - mWidth = width; - mHeight = height; -} - -void PictureSet::clear() -{ - DBG_SET_LOG(""); - Pictures* last = mPictures.end(); - for (Pictures* working = mPictures.begin(); working != last; working++) { - working->mArea.setEmpty(); - SkSafeUnref(working->mPicture); - } - mPictures.clear(); - mWidth = mHeight = 0; -} - -bool PictureSet::draw(SkCanvas* canvas) -{ - validate(__FUNCTION__); - Pictures* first = mPictures.begin(); - Pictures* last = mPictures.end(); - Pictures* working; - SkRect bounds; - if (canvas->getClipBounds(&bounds) == false) - return false; - SkIRect irect; - bounds.roundOut(&irect); - for (working = last; working != first; ) { - --working; - if (working->mArea.contains(irect)) { -#if PICTURE_SET_DEBUG - const SkIRect& b = working->mArea.getBounds(); - DBG_SET_LOGD("contains working->mArea={%d,%d,%d,%d}" - " irect={%d,%d,%d,%d}", b.fLeft, b.fTop, b.fRight, b.fBottom, - irect.fLeft, irect.fTop, irect.fRight, irect.fBottom); -#endif - first = working; - break; - } - } - DBG_SET_LOGD("%p first=%d last=%d", this, first - mPictures.begin(), - last - mPictures.begin()); - uint32_t maxElapsed = 0; - for (working = first; working != last; working++) { - const SkRegion& area = working->mArea; - if (area.quickReject(irect)) { -#if PICTURE_SET_DEBUG - const SkIRect& b = area.getBounds(); - DBG_SET_LOGD("[%d] %p quickReject working->mArea={%d,%d,%d,%d}" - " irect={%d,%d,%d,%d}", working - first, working, - b.fLeft, b.fTop, b.fRight, b.fBottom, - irect.fLeft, irect.fTop, irect.fRight, irect.fBottom); -#endif - working->mElapsed = 0; - continue; - } - int saved = canvas->save(); - SkRect pathBounds; - if (area.isComplex()) { - SkPath pathClip; - area.getBoundaryPath(&pathClip); - canvas->clipPath(pathClip); - pathBounds = pathClip.getBounds(); - } else { - pathBounds.set(area.getBounds()); - canvas->clipRect(pathBounds); - } - canvas->translate(pathBounds.fLeft, pathBounds.fTop); - canvas->save(); - uint32_t startTime = getThreadMsec(); - canvas->drawPicture(*working->mPicture); - size_t elapsed = working->mElapsed = getThreadMsec() - startTime; - working->mWroteElapsed = true; - if (maxElapsed < elapsed && (pathBounds.width() >= MIN_SPLITTABLE || - pathBounds.height() >= MIN_SPLITTABLE)) - maxElapsed = elapsed; - canvas->restoreToCount(saved); -#define DRAW_TEST_IMAGE 01 -#if DRAW_TEST_IMAGE && PICTURE_SET_DEBUG - SkColor color = 0x3f000000 | (0xffffff & (unsigned) working); - canvas->drawColor(color); - SkPaint paint; - color ^= 0x00ffffff; - paint.setColor(color); - char location[256]; - for (int x = area.getBounds().fLeft & ~0x3f; - x < area.getBounds().fRight; x += 0x40) { - for (int y = area.getBounds().fTop & ~0x3f; - y < area.getBounds().fBottom; y += 0x40) { - int len = snprintf(location, sizeof(location) - 1, "(%d,%d)", x, y); - canvas->drawText(location, len, x, y, paint); - } - } -#endif - DBG_SET_LOGD("[%d] %p working->mArea={%d,%d,%d,%d} elapsed=%d base=%s", - working - first, working, - area.getBounds().fLeft, area.getBounds().fTop, - area.getBounds().fRight, area.getBounds().fBottom, - working->mElapsed, working->mBase ? "true" : "false"); - } - // dump(__FUNCTION__); - return maxElapsed >= MAX_DRAW_TIME; -} - -void PictureSet::dump(const char* label) const -{ -#if PICTURE_SET_DUMP - DBG_SET_LOGD("%p %s (%d) (w=%d,h=%d)", this, label, mPictures.size(), - mWidth, mHeight); - const Pictures* last = mPictures.end(); - for (const Pictures* working = mPictures.begin(); working != last; working++) { - const SkIRect& bounds = working->mArea.getBounds(); - const SkIRect& unsplit = working->mUnsplit; - MeasureStream measure; - if (working->mPicture != NULL) - working->mPicture->serialize(&measure); - LOGD(" [%d]" - " mArea.bounds={%d,%d,r=%d,b=%d}" - " mPicture=%p" - " mUnsplit={%d,%d,r=%d,b=%d}" - " mElapsed=%d" - " mSplit=%s" - " mWroteElapsed=%s" - " mBase=%s" - " pict-size=%d", - working - mPictures.begin(), - bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, - working->mPicture, - unsplit.fLeft, unsplit.fTop, unsplit.fRight, unsplit.fBottom, - working->mElapsed, working->mSplit ? "true" : "false", - working->mWroteElapsed ? "true" : "false", - working->mBase ? "true" : "false", - measure.mTotal); - } -#endif -} - -class IsEmptyBounder : public SkBounder { - virtual bool onIRect(const SkIRect& rect) { - return false; - } -}; - -class IsEmptyCanvas : public SkCanvas { -public: - IsEmptyCanvas(SkBounder* bounder, SkPicture* picture) : - mPicture(picture), mEmpty(true) { - setBounder(bounder); - } - - void notEmpty() { - mEmpty = false; - mPicture->abortPlayback(); - } - - virtual bool clipPath(const SkPath&, SkRegion::Op) { - // this can be expensive to actually do, and doesn't affect the - // question of emptiness, so we make it a no-op - return true; - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& , const SkPaint& ) { - if (bitmap.width() <= 1 || bitmap.height() <= 1) - return; - DBG_SET_LOGD("abort {%d,%d}", bitmap.width(), bitmap.height()); - notEmpty(); - } - - virtual void drawPaint(const SkPaint& paint) { - } - - virtual void drawPath(const SkPath& , const SkPaint& paint) { - DBG_SET_LOG("abort"); - notEmpty(); - } - - virtual void drawPoints(PointMode , size_t , const SkPoint [], - const SkPaint& paint) { - } - - virtual void drawRect(const SkRect& , const SkPaint& paint) { - // wait for visual content - if (paint.getColor() != SK_ColorWHITE) - notEmpty(); - } - - virtual void drawSprite(const SkBitmap& , int , int , - const SkPaint* paint = NULL) { - DBG_SET_LOG("abort"); - notEmpty(); - } - - virtual void drawText(const void* , size_t byteLength, SkScalar , - SkScalar , const SkPaint& paint) { - DBG_SET_LOGD("abort %d", byteLength); - notEmpty(); - } - - virtual void drawPosText(const void* , size_t byteLength, - const SkPoint [], const SkPaint& paint) { - DBG_SET_LOGD("abort %d", byteLength); - notEmpty(); - } - - virtual void drawPosTextH(const void* , size_t byteLength, - const SkScalar [], SkScalar , - const SkPaint& paint) { - DBG_SET_LOGD("abort %d", byteLength); - notEmpty(); - } - - virtual void drawTextOnPath(const void* , size_t byteLength, - const SkPath& , const SkMatrix* , - const SkPaint& paint) { - DBG_SET_LOGD("abort %d", byteLength); - notEmpty(); - } - - virtual void drawPicture(SkPicture& picture) { - SkCanvas::drawPicture(picture); - } - - SkPicture* mPicture; - bool mEmpty; -}; - -bool PictureSet::emptyPicture(SkPicture* picture) const -{ - IsEmptyBounder isEmptyBounder; - IsEmptyCanvas checker(&isEmptyBounder, picture); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, mWidth, mHeight); - checker.setBitmapDevice(bitmap); - checker.drawPicture(*picture); - return checker.mEmpty; -} - -bool PictureSet::isEmpty() const -{ - const Pictures* last = mPictures.end(); - for (const Pictures* working = mPictures.begin(); working != last; working++) { - if (!working->mEmpty) - return false; - } - return true; -} - -bool PictureSet::reuseSubdivided(const SkRegion& inval) -{ - validate(__FUNCTION__); - if (inval.isComplex()) - return false; - Pictures* working, * last = mPictures.end(); - const SkIRect& invalBounds = inval.getBounds(); - bool steal = false; - for (working = mPictures.begin(); working != last; working++) { - if (working->mSplit && invalBounds == working->mUnsplit) { - steal = true; - continue; - } - if (steal == false) - continue; - SkRegion temp = SkRegion(inval); - temp.op(working->mArea, SkRegion::kIntersect_Op); - if (temp.isEmpty() || temp == working->mArea) - continue; - return false; - } - if (steal == false) - return false; - for (working = mPictures.begin(); working != last; working++) { - if ((working->mSplit == false || invalBounds != working->mUnsplit) && - inval.contains(working->mArea) == false) - continue; - SkSafeUnref(working->mPicture); - working->mPicture = NULL; - } - return true; -} - -void PictureSet::set(const PictureSet& src) -{ - DBG_SET_LOGD("start %p src=%p", this, &src); - clear(); - mWidth = src.mWidth; - mHeight = src.mHeight; - const Pictures* last = src.mPictures.end(); - for (const Pictures* working = src.mPictures.begin(); working != last; working++) - add(working); - // dump(__FUNCTION__); - validate(__FUNCTION__); - DBG_SET_LOG("end"); -} - -void PictureSet::setDrawTimes(const PictureSet& src) -{ - validate(__FUNCTION__); - if (mWidth != src.mWidth || mHeight != src.mHeight) - return; - Pictures* last = mPictures.end(); - Pictures* working = mPictures.begin(); - if (working == last) - return; - const Pictures* srcLast = src.mPictures.end(); - const Pictures* srcWorking = src.mPictures.begin(); - for (; srcWorking != srcLast; srcWorking++) { - if (srcWorking->mWroteElapsed == false) - continue; - while ((srcWorking->mArea != working->mArea || - srcWorking->mPicture != working->mPicture)) { - if (++working == last) - return; - } - DBG_SET_LOGD("%p [%d] [%d] {%d,%d,r=%d,b=%d} working->mElapsed=%d <- %d", - this, working - mPictures.begin(), srcWorking - src.mPictures.begin(), - working->mArea.getBounds().fLeft, working->mArea.getBounds().fTop, - working->mArea.getBounds().fRight, working->mArea.getBounds().fBottom, - working->mElapsed, srcWorking->mElapsed); - working->mElapsed = srcWorking->mElapsed; - } -} - -void PictureSet::setPicture(size_t i, SkPicture* p) -{ - SkSafeUnref(mPictures[i].mPicture); - mPictures[i].mPicture = p; - mPictures[i].mEmpty = emptyPicture(p); -} - -void PictureSet::split(PictureSet* out) const -{ - dump(__FUNCTION__); - DBG_SET_LOGD("%p", this); - SkIRect totalBounds; - out->mWidth = mWidth; - out->mHeight = mHeight; - totalBounds.set(0, 0, mWidth, mHeight); - SkRegion* total = new SkRegion(totalBounds); - const Pictures* last = mPictures.end(); - const Pictures* working; - uint32_t balance = 0; - int multiUnsplitFastPictures = 0; // > 1 has more than 1 - for (working = mPictures.begin(); working != last; working++) { - if (working->mElapsed >= MAX_DRAW_TIME || working->mSplit) - continue; - if (++multiUnsplitFastPictures > 1) - break; - } - for (working = mPictures.begin(); working != last; working++) { - uint32_t elapsed = working->mElapsed; - if (elapsed < MAX_DRAW_TIME) { - bool split = working->mSplit; - DBG_SET_LOGD("elapsed=%d working=%p total->getBounds()=" - "{%d,%d,r=%d,b=%d} split=%s", elapsed, working, - total->getBounds().fLeft, total->getBounds().fTop, - total->getBounds().fRight, total->getBounds().fBottom, - split ? "true" : "false"); - if (multiUnsplitFastPictures <= 1 || split) { - total->op(working->mArea, SkRegion::kDifference_Op); - out->add(working->mArea, working->mPicture, elapsed, split, - working->mEmpty); - } else if (balance < elapsed) - balance = elapsed; - continue; - } - total->op(working->mArea, SkRegion::kDifference_Op); - const SkIRect& bounds = working->mArea.getBounds(); - int width = bounds.width(); - int height = bounds.height(); - int across = 1; - int down = 1; - while (height >= MIN_SPLITTABLE || width >= MIN_SPLITTABLE) { - if (height >= width) { - height >>= 1; - down <<= 1; - } else { - width >>= 1; - across <<= 1 ; - } - if ((elapsed >>= 1) < MAX_DRAW_TIME) - break; - } - width = bounds.width(); - height = bounds.height(); - int top = bounds.fTop; - for (int indexY = 0; indexY < down; ) { - int bottom = bounds.fTop + height * ++indexY / down; - int left = bounds.fLeft; - for (int indexX = 0; indexX < across; ) { - int right = bounds.fLeft + width * ++indexX / across; - SkIRect cBounds; - cBounds.set(left, top, right, bottom); - out->add(SkRegion(cBounds), (across | down) != 1 ? NULL : - working->mPicture, elapsed, true, - (across | down) != 1 ? false : working->mEmpty); - left = right; - } - top = bottom; - } - } - DBG_SET_LOGD("%p w=%d h=%d total->isEmpty()=%s multiUnsplitFastPictures=%d", - this, mWidth, mHeight, total->isEmpty() ? "true" : "false", - multiUnsplitFastPictures); - if (!total->isEmpty() && multiUnsplitFastPictures > 1) - out->add(*total, NULL, balance, false, false); - delete total; - validate(__FUNCTION__); - out->dump("split-out"); -} - -bool PictureSet::validate(const char* funct) const -{ - bool valid = true; -#if PICTURE_SET_VALIDATE - SkRegion all; - const Pictures* first = mPictures.begin(); - for (const Pictures* working = mPictures.end(); working != first; ) { - --working; - const SkPicture* pict = working->mPicture; - const SkRegion& area = working->mArea; - const SkIRect& bounds = area.getBounds(); - bool localValid = false; - if (working->mUnsplit.isEmpty()) - LOGD("%s working->mUnsplit.isEmpty()", funct); - else if (working->mUnsplit.contains(bounds) == false) - LOGD("%s working->mUnsplit.contains(bounds) == false", funct); - else if (working->mElapsed >= 1000) - LOGD("%s working->mElapsed >= 1000", funct); - else if ((working->mSplit & 0xfe) != 0) - LOGD("%s (working->mSplit & 0xfe) != 0", funct); - else if ((working->mWroteElapsed & 0xfe) != 0) - LOGD("%s (working->mWroteElapsed & 0xfe) != 0", funct); - else if (pict != NULL) { - int pictWidth = pict->width(); - int pictHeight = pict->height(); - if (pictWidth < bounds.width()) - LOGD("%s pictWidth=%d < bounds.width()=%d", funct, pictWidth, bounds.width()); - else if (pictHeight < bounds.height()) - LOGD("%s pictHeight=%d < bounds.height()=%d", funct, pictHeight, bounds.height()); - else if (working->mArea.isEmpty()) - LOGD("%s working->mArea.isEmpty()", funct); - else - localValid = true; - } else - localValid = true; - working->mArea.validate(); - if (localValid == false) { - if (all.contains(area) == true) - LOGD("%s all.contains(area) == true", funct); - else - localValid = true; - } - valid &= localValid; - all.op(area, SkRegion::kUnion_Op); - } - const SkIRect& allBounds = all.getBounds(); - if (valid) { - valid = false; - if (allBounds.width() != mWidth) - LOGD("%s allBounds.width()=%d != mWidth=%d", funct, allBounds.width(), mWidth); - else if (allBounds.height() != mHeight) - LOGD("%s allBounds.height()=%d != mHeight=%d", funct, allBounds.height(), mHeight); - else - valid = true; - } - while (valid == false) - ; -#endif - return valid; -} - -} /* namespace android */ diff --git a/WebKit/android/jni/PictureSet.h b/WebKit/android/jni/PictureSet.h deleted file mode 100644 index b177958..0000000 --- a/WebKit/android/jni/PictureSet.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2008, 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 PICTURESET_H -#define PICTURESET_H - -#define PICTURE_SET_DUMP 0 -#define PICTURE_SET_DEBUG 0 -#define PICTURE_SET_VALIDATE 0 - -#if PICTURE_SET_DEBUG -#define DBG_SET_LOG(message) LOGD("%s %s", __FUNCTION__, message) -#define DBG_SET_LOGD(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#define DEBUG_SET_UI_LOGD(...) LOGD(__VA_ARGS__) -#else -#define DBG_SET_LOG(message) ((void)0) -#define DBG_SET_LOGD(format, ...) ((void)0) -#define DEBUG_SET_UI_LOGD(...) ((void)0) -#endif - -#include "jni.h" -#include "SkRegion.h" -#include <wtf/Vector.h> - -class SkCanvas; -class SkPicture; -class SkIRect; - -namespace android { - - class PictureSet { - public: - PictureSet(); - PictureSet(const PictureSet& src) { set(src); } - virtual ~PictureSet(); - void add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split) - { - add(area, picture, elapsed, split, emptyPicture(picture)); - } - void add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split, bool empty); - const SkIRect& bounds(size_t i) const { - return mPictures[i].mArea.getBounds(); } - bool build(); - // Update mWidth/mHeight, and adds any additional inval region - void checkDimensions(int width, int height, SkRegion* inval); - void clear(); - bool draw(SkCanvas* ); - static PictureSet* GetNativePictureSet(JNIEnv* env, jobject jpic); - int height() const { return mHeight; } - bool isEmpty() const; // returns true if empty or only trivial content - bool reuseSubdivided(const SkRegion& ); - void set(const PictureSet& ); - void setDrawTimes(const PictureSet& ); - void setPicture(size_t i, SkPicture* p); - size_t size() const { return mPictures.size(); } - void split(PictureSet* result) const; - bool upToDate(size_t i) const { return mPictures[i].mPicture != NULL; } - int width() const { return mWidth; } - void dump(const char* label) const; - bool validate(const char* label) const; - private: - bool emptyPicture(SkPicture* ) const; // true if no text, images, paths - struct Pictures { - SkRegion mArea; - SkPicture* mPicture; - SkIRect mUnsplit; - uint32_t mElapsed; - bool mSplit : 8; - bool mWroteElapsed : 8; - bool mBase : 8; // true if nothing is drawn underneath this - bool mEmpty : 8; // true if the picture only draws white - }; - void add(const Pictures* temp); - WTF::Vector<Pictures> mPictures; - int mHeight; - int mWidth; - }; -} - -#endif diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp deleted file mode 100644 index 15b6d20..0000000 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ /dev/null @@ -1,2125 +0,0 @@ -/* - * Copyright 2006, 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 "webcoreglue" - -#include "config.h" -#include "WebCoreFrameBridge.h" - -#include "Arena.h" -#include "BackForwardList.h" -#include "MemoryCache.h" -#include "Chrome.h" -#include "ChromeClientAndroid.h" -#include "ChromiumInit.h" -#include "ContextMenuClientAndroid.h" -#include "DeviceMotionClientAndroid.h" -#include "DeviceOrientationClientAndroid.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "DragClientAndroid.h" -#include "EditorClientAndroid.h" -#include "Element.h" -#include "FocusController.h" -#include "Font.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameLoadRequest.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HistoryItem.h" -#include "HTMLCollection.h" -#include "HTMLElement.h" -#include "HTMLFormElement.h" -#include "HTMLInputElement.h" -#include "HTMLNames.h" -#include "IconDatabase.h" -#include "Image.h" -#include "InspectorClientAndroid.h" -#include "KURL.h" -#include "Page.h" -#include "PageCache.h" -#include "PlatformString.h" -#include "RenderPart.h" -#include "RenderSkinAndroid.h" -#include "RenderTreeAsText.h" -#include "RenderView.h" -#include "ResourceHandle.h" -#include "ResourceHandleInternal.h" -#include "ScriptController.h" -#include "ScriptValue.h" -#include "SecurityOrigin.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SubstituteData.h" -#include "UrlInterceptResponse.h" -#include "UserGestureIndicator.h" -#include "WebCache.h" -#include "WebCoreJni.h" -#include "WebCoreResourceLoader.h" -#include "WebHistory.h" -#include "WebIconDatabase.h" -#include "WebFrameView.h" -#include "WebUrlLoaderClient.h" -#include "WebViewCore.h" -#include "android_graphics.h" -#include "jni.h" -#include "wds/DebugServer.h" - -#include <JNIUtility.h> -#include <JNIHelp.h> -#include <SkGraphics.h> -#include <android_runtime/android_util_AssetManager.h> -#include <utils/misc.h> -#include <utils/AssetManager.h> -#include <wtf/CurrentTime.h> -#include <wtf/Platform.h> -#include <wtf/text/AtomicString.h> -#include <wtf/text/CString.h> -#include <wtf/text/StringBuilder.h> - -#if USE(JSC) -#include "GCController.h" -#include "JSDOMWindow.h" -#include "JavaInstanceJSC.h" -#include <runtime_object.h> -#include <runtime_root.h> -#include <runtime/JSLock.h> -#elif USE(V8) -#include "JavaNPObjectV8.h" -#include "JavaInstanceV8.h" -#include "V8Counters.h" -#endif // USE(JSC) - -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif - -#if ENABLE(ARCHIVE) -#include "WebArchiveAndroid.h" -#endif - -#if ENABLE(WEB_AUTOFILL) -#include "autofill/WebAutoFill.h" -#endif - -using namespace JSC::Bindings; - -static String* gUploadFileLabel; -static String* gResetLabel; -static String* gSubmitLabel; -static String* gNoFileChosenLabel; - -String* WebCore::PlatformBridge::globalLocalizedName( - WebCore::PlatformBridge::rawResId resId) -{ - switch (resId) { - case WebCore::PlatformBridge::FileUploadLabel: - return gUploadFileLabel; - case WebCore::PlatformBridge::ResetLabel: - return gResetLabel; - case WebCore::PlatformBridge::SubmitLabel: - return gSubmitLabel; - case WebCore::PlatformBridge::FileUploadNoFileChosenLabel: - return gNoFileChosenLabel; - - default: - return 0; - } -} -/** - * Instantiate the localized name desired. - */ -void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId, - android::WebFrame* webFrame) -{ - String** pointer; - switch (resId) { - case WebCore::PlatformBridge::FileUploadLabel: - pointer = &gUploadFileLabel; - break; - case WebCore::PlatformBridge::ResetLabel: - pointer = &gResetLabel; - break; - case WebCore::PlatformBridge::SubmitLabel: - pointer = &gSubmitLabel; - break; - case WebCore::PlatformBridge::FileUploadNoFileChosenLabel: - pointer = &gNoFileChosenLabel; - break; - default: - return; - } - if (!(*pointer) && webFrame) { - (*pointer) = new String(webFrame->getRawResourceFilename(resId).impl()); - } -} - -namespace android { - -// ---------------------------------------------------------------------------- - -#define WEBCORE_MEMORY_CAP 15 * 1024 * 1024 - -// ---------------------------------------------------------------------------- - -struct WebFrame::JavaBrowserFrame -{ - jweak mObj; - jweak mHistoryList; // WebBackForwardList object - jmethodID mStartLoadingResource; - jmethodID mMaybeSavePassword; - jmethodID mShouldInterceptRequest; - jmethodID mLoadStarted; - jmethodID mTransitionToCommitted; - jmethodID mLoadFinished; - jmethodID mReportError; - jmethodID mSetTitle; - jmethodID mWindowObjectCleared; - jmethodID mSetProgress; - jmethodID mDidReceiveIcon; - jmethodID mDidReceiveTouchIconUrl; - jmethodID mUpdateVisitedHistory; - jmethodID mHandleUrl; - jmethodID mCreateWindow; - jmethodID mCloseWindow; - jmethodID mDecidePolicyForFormResubmission; - jmethodID mRequestFocus; - jmethodID mGetRawResFilename; - jmethodID mDensity; - jmethodID mGetFileSize; - jmethodID mGetFile; - jmethodID mDidReceiveAuthenticationChallenge; - jmethodID mReportSslCertError; - jmethodID mDownloadStart; - jmethodID mDidReceiveData; - jmethodID mDidFinishLoading; - jmethodID mSetCertificate; - jmethodID mShouldSaveFormData; - jmethodID mSaveFormData; - jmethodID mAutoLogin; - AutoJObject frame(JNIEnv* env) { - return getRealObject(env, mObj); - } - AutoJObject history(JNIEnv* env) { - return getRealObject(env, mHistoryList); - } -}; - -static jfieldID gFrameField; -#define GET_NATIVE_FRAME(env, obj) ((WebCore::Frame*)env->GetIntField(obj, gFrameField)) -#define SET_NATIVE_FRAME(env, obj, frame) (env->SetIntField(obj, gFrameField, frame)) - -// ---------------------------------------------------------------------------- - -WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* page) - : mPage(page) -{ - jclass clazz = env->GetObjectClass(obj); - mJavaFrame = new JavaBrowserFrame; - mJavaFrame->mObj = env->NewWeakGlobalRef(obj); - mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList); - mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource", - "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;[BJIZZZLjava/lang/String;Ljava/lang/String;)Landroid/webkit/LoadListener;"); - mJavaFrame->mMaybeSavePassword = env->GetMethodID(clazz, "maybeSavePassword", - "([BLjava/lang/String;Ljava/lang/String;)V"); - mJavaFrame->mShouldInterceptRequest = - env->GetMethodID(clazz, "shouldInterceptRequest", - "(Ljava/lang/String;)Landroid/webkit/WebResourceResponse;"); - mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted", - "(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V"); - mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted", - "(IZ)V"); - mJavaFrame->mLoadFinished = env->GetMethodID(clazz, "loadFinished", - "(Ljava/lang/String;IZ)V"); - mJavaFrame->mReportError = env->GetMethodID(clazz, "reportError", - "(ILjava/lang/String;Ljava/lang/String;)V"); - mJavaFrame->mSetTitle = env->GetMethodID(clazz, "setTitle", - "(Ljava/lang/String;)V"); - mJavaFrame->mWindowObjectCleared = env->GetMethodID(clazz, "windowObjectCleared", - "(I)V"); - mJavaFrame->mSetProgress = env->GetMethodID(clazz, "setProgress", - "(I)V"); - mJavaFrame->mDidReceiveIcon = env->GetMethodID(clazz, "didReceiveIcon", - "(Landroid/graphics/Bitmap;)V"); - mJavaFrame->mDidReceiveTouchIconUrl = env->GetMethodID(clazz, "didReceiveTouchIconUrl", - "(Ljava/lang/String;Z)V"); - mJavaFrame->mUpdateVisitedHistory = env->GetMethodID(clazz, "updateVisitedHistory", - "(Ljava/lang/String;Z)V"); - mJavaFrame->mHandleUrl = env->GetMethodID(clazz, "handleUrl", - "(Ljava/lang/String;)Z"); - mJavaFrame->mCreateWindow = env->GetMethodID(clazz, "createWindow", - "(ZZ)Landroid/webkit/BrowserFrame;"); - mJavaFrame->mCloseWindow = env->GetMethodID(clazz, "closeWindow", - "(Landroid/webkit/WebViewCore;)V"); - mJavaFrame->mDecidePolicyForFormResubmission = env->GetMethodID(clazz, - "decidePolicyForFormResubmission", "(I)V"); - mJavaFrame->mRequestFocus = env->GetMethodID(clazz, "requestFocus", - "()V"); - mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename", - "(I)Ljava/lang/String;"); - mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F"); - mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I"); - mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I"); - mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge", - "(ILjava/lang/String;Ljava/lang/String;Z)V"); - mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[B)V"); - mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart", - "(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"); - mJavaFrame->mShouldSaveFormData = env->GetMethodID(clazz, "shouldSaveFormData", "()Z"); - mJavaFrame->mSaveFormData = env->GetMethodID(clazz, "saveFormData", "(Ljava/util/HashMap;)V"); - mJavaFrame->mAutoLogin = env->GetMethodID(clazz, "autoLogin", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - env->DeleteLocalRef(clazz); - - LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource"); - LOG_ASSERT(mJavaFrame->mMaybeSavePassword, "Could not find method maybeSavePassword"); - LOG_ASSERT(mJavaFrame->mShouldInterceptRequest, "Could not find method shouldInterceptRequest"); - LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted"); - LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted"); - LOG_ASSERT(mJavaFrame->mLoadFinished, "Could not find method loadFinished"); - LOG_ASSERT(mJavaFrame->mReportError, "Could not find method reportError"); - LOG_ASSERT(mJavaFrame->mSetTitle, "Could not find method setTitle"); - LOG_ASSERT(mJavaFrame->mWindowObjectCleared, "Could not find method windowObjectCleared"); - LOG_ASSERT(mJavaFrame->mSetProgress, "Could not find method setProgress"); - LOG_ASSERT(mJavaFrame->mDidReceiveIcon, "Could not find method didReceiveIcon"); - LOG_ASSERT(mJavaFrame->mDidReceiveTouchIconUrl, "Could not find method didReceiveTouchIconUrl"); - LOG_ASSERT(mJavaFrame->mUpdateVisitedHistory, "Could not find method updateVisitedHistory"); - LOG_ASSERT(mJavaFrame->mHandleUrl, "Could not find method handleUrl"); - LOG_ASSERT(mJavaFrame->mCreateWindow, "Could not find method createWindow"); - LOG_ASSERT(mJavaFrame->mCloseWindow, "Could not find method closeWindow"); - LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission"); - LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus"); - LOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename"); - LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density"); - LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize"); - LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile"); - LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge"); - LOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError"); - LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart"); - LOG_ASSERT(mJavaFrame->mDidReceiveData, "Could not find method didReceiveData"); - LOG_ASSERT(mJavaFrame->mDidFinishLoading, "Could not find method didFinishLoading"); - LOG_ASSERT(mJavaFrame->mSetCertificate, "Could not find method setCertificate"); - LOG_ASSERT(mJavaFrame->mShouldSaveFormData, "Could not find method shouldSaveFormData"); - LOG_ASSERT(mJavaFrame->mSaveFormData, "Could not find method saveFormData"); - LOG_ASSERT(mJavaFrame->mAutoLogin, "Could not find method autoLogin"); - - mUserAgent = WTF::String(); - mUserInitiatedAction = false; - mBlockNetworkLoads = false; - m_renderSkins = 0; -} - -WebFrame::~WebFrame() -{ - if (mJavaFrame->mObj) { - JNIEnv* env = getJNIEnv(); - env->DeleteWeakGlobalRef(mJavaFrame->mObj); - env->DeleteWeakGlobalRef(mJavaFrame->mHistoryList); - mJavaFrame->mObj = 0; - } - delete mJavaFrame; - delete m_renderSkins; -} - -WebFrame* WebFrame::getWebFrame(const WebCore::Frame* frame) -{ - FrameLoaderClientAndroid* client = - static_cast<FrameLoaderClientAndroid*> (frame->loader()->client()); - return client->webFrame(); -} - -static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHeaderMap& map) -{ - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - jobject hashMap = env->NewObject(mapClass, init, map.size()); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - - WebCore::HTTPHeaderMap::const_iterator end = map.end(); - for (WebCore::HTTPHeaderMap::const_iterator i = map.begin(); i != end; ++i) { - if (i->first.length() == 0 || i->second.length() == 0) - continue; - jstring key = wtfStringToJstring(env, i->first); - jstring val = wtfStringToJstring(env, i->second); - if (key && val) { - env->CallObjectMethod(hashMap, put, key, val); - } - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - - env->DeleteLocalRef(mapClass); - - return hashMap; -} - -// This class stores the URI and the size of each file for upload. The URI is -// stored so we do not have to create it again. The size is stored so we can -// compare the actual size of the file with the stated size. If the actual size -// is larger, we will not copy it, since we will not have enough space in our -// buffer. -class FileInfo { -public: - FileInfo(JNIEnv* env, const WTF::String& name) { - m_uri = wtfStringToJstring(env, name); - checkException(env); - m_size = 0; - m_env = env; - } - ~FileInfo() { - m_env->DeleteLocalRef(m_uri); - } - int getSize() { return m_size; } - jstring getUri() { return m_uri; } - void setSize(int size) { m_size = size; } -private: - // This is only a pointer to the JNIEnv* returned by - // JSC::Bindings::getJNIEnv(). Used to delete the jstring when finished. - JNIEnv* m_env; - jstring m_uri; - int m_size; -}; - -PassRefPtr<WebCore::ResourceLoaderAndroid> -WebFrame::startLoadingResource(WebCore::ResourceHandle* loader, - const WebCore::ResourceRequest& request, - bool mainResource, - bool synchronous) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: startLoadingResource(%p, %s)", - loader, request.url().string().latin1().data()); - - WTF::String method = request.httpMethod(); - WebCore::HTTPHeaderMap headers = request.httpHeaderFields(); - - JNIEnv* env = getJNIEnv(); - WTF::String urlStr = request.url().string(); - int colon = urlStr.find(':'); - bool allLower = true; - for (int index = 0; index < colon; index++) { - UChar ch = urlStr[index]; - if (!WTF::isASCIIAlpha(ch)) - break; - allLower &= WTF::isASCIILower(ch); - if (index == colon - 1 && !allLower) { - urlStr = urlStr.substring(0, colon).lower() - + urlStr.substring(colon); - } - } - LOGV("%s lower=%s", __FUNCTION__, urlStr.latin1().data()); - jstring jUrlStr = wtfStringToJstring(env, urlStr); - jstring jMethodStr = NULL; - if (!method.isEmpty()) - jMethodStr = wtfStringToJstring(env, method); - WebCore::FormData* formdata = request.httpBody(); - jbyteArray jPostDataStr = getPostData(request); - jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers); - - // Convert the WebCore Cache Policy to a WebView Cache Policy. - int cacheMode = 0; // WebSettings.LOAD_NORMAL - switch (request.cachePolicy()) { - case WebCore::ReloadIgnoringCacheData: - cacheMode = 2; // WebSettings.LOAD_NO_CACHE - break; - case WebCore::ReturnCacheDataDontLoad: - cacheMode = 3; // WebSettings.LOAD_CACHE_ONLY - break; - case WebCore::ReturnCacheDataElseLoad: - cacheMode = 1; // WebSettings.LOAD_CACHE_ELSE_NETWORK - break; - case WebCore::UseProtocolCachePolicy: - default: - break; - } - - LOGV("::WebCore:: startLoadingResource %s with cacheMode %d", urlStr.ascii().data(), cacheMode); - - ResourceHandleInternal* loaderInternal = loader->getInternal(); - jstring jUsernameString = loaderInternal->m_user.isEmpty() ? - NULL : wtfStringToJstring(env, loaderInternal->m_user); - jstring jPasswordString = loaderInternal->m_pass.isEmpty() ? - NULL : wtfStringToJstring(env, loaderInternal->m_pass); - - bool isUserGesture = UserGestureIndicator::processingUserGesture(); - jobject jLoadListener = - env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mStartLoadingResource, - (int)loader, jUrlStr, jMethodStr, jHeaderMap, - jPostDataStr, formdata ? formdata->identifier(): 0, - cacheMode, mainResource, isUserGesture, - synchronous, jUsernameString, jPasswordString); - - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jMethodStr); - env->DeleteLocalRef(jPostDataStr); - env->DeleteLocalRef(jHeaderMap); - env->DeleteLocalRef(jUsernameString); - env->DeleteLocalRef(jPasswordString); - if (checkException(env)) - return NULL; - - PassRefPtr<WebCore::ResourceLoaderAndroid> h; - if (jLoadListener) - h = WebCoreResourceLoader::create(env, jLoadListener); - env->DeleteLocalRef(jLoadListener); - return h; -} - -UrlInterceptResponse* -WebFrame::shouldInterceptRequest(const WTF::String& url) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: shouldInterceptRequest(%s)", url.latin1().data()); - - JNIEnv* env = getJNIEnv(); - jstring urlStr = wtfStringToJstring(env, url); - jobject response = env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mShouldInterceptRequest, urlStr); - env->DeleteLocalRef(urlStr); - if (response == 0) - return 0; - return new UrlInterceptResponse(env, response); -} - -void -WebFrame::reportError(int errorCode, const WTF::String& description, - const WTF::String& failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data()); - JNIEnv* env = getJNIEnv(); - - jstring descStr = wtfStringToJstring(env, description); - jstring failUrl = wtfStringToJstring(env, failingUrl); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mReportError, - errorCode, descStr, failUrl); - env->DeleteLocalRef(descStr); - env->DeleteLocalRef(failUrl); -} - -void -WebFrame::loadStarted(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - // activeDocumentLoader() can return null. - DocumentLoader* documentLoader = frame->loader()->activeDocumentLoader(); - if (documentLoader == NULL) - return; - - const WebCore::KURL& url = documentLoader->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: loadStarted %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - - if (loadType == WebCore::FrameLoadTypeReplace || - (loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList && - !isMainFrame)) - return; - - JNIEnv* env = getJNIEnv(); - const WTF::String& urlString = url.string(); - // If this is the main frame and we already have a favicon in the database, - // send it along with the page started notification. - jobject favicon = NULL; - if (isMainFrame) { - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlString, WebCore::IntSize(16, 16)); - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - LOGV("favicons", "Starting load with icon %p for %s", icon, url.string().utf8().data()); - } - jstring urlStr = wtfStringToJstring(env, urlString); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadStarted, urlStr, favicon, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); - 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(); - } - } -} - -void -WebFrame::transitionToCommitted(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - WebCore::FrameLoadType loadType = frame->loader()->loadType(); - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mTransitionToCommitted, - (int)loadType, isMainFrame); - checkException(env); -} - -void -WebFrame::didFinishLoad(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - - // activeDocumentLoader() can return null. - WebCore::FrameLoader* loader = frame->loader(); - DocumentLoader* documentLoader = loader->activeDocumentLoader(); - if (documentLoader == NULL) - return; - - const WebCore::KURL& url = documentLoader->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data()); - - bool isMainFrame = (!frame->tree() || !frame->tree()->parent()); - WebCore::FrameLoadType loadType = loader->loadType(); - const WTF::String& urlString = url.string(); - jstring urlStr = wtfStringToJstring(env, urlString); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadFinished, urlStr, - (int)loadType, isMainFrame); - checkException(env); - env->DeleteLocalRef(urlStr); -} - -void -WebFrame::addHistoryItem(WebCore::HistoryItem* item) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: addHistoryItem"); - JNIEnv* env = getJNIEnv(); - WebHistory::AddItem(mJavaFrame->history(env), item); -} - -void -WebFrame::removeHistoryItem(int index) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: removeHistoryItem at %d", index); - JNIEnv* env = getJNIEnv(); - WebHistory::RemoveItem(mJavaFrame->history(env), index); -} - -void -WebFrame::updateHistoryIndex(int newIndex) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: updateHistoryIndex to %d", newIndex); - JNIEnv* env = getJNIEnv(); - WebHistory::UpdateHistoryIndex(mJavaFrame->history(env), newIndex); -} - -void -WebFrame::setTitle(const WTF::String& title) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif -#ifndef NDEBUG - LOGV("setTitle(%s)", title.ascii().data()); -#endif - JNIEnv* env = getJNIEnv(); - jstring jTitleStr = wtfStringToJstring(env, title); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetTitle, jTitleStr); - checkException(env); - env->DeleteLocalRef(jTitleStr); -} - -void -WebFrame::windowObjectCleared(WebCore::Frame* frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOGV("::WebCore:: windowObjectCleared"); - JNIEnv* env = getJNIEnv(); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mWindowObjectCleared, (int)frame); - checkException(env); -} - -void -WebFrame::setProgress(float newProgress) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - int progress = (int) (100 * newProgress); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetProgress, progress); - checkException(env); -} - -const WTF::String -WebFrame::userAgentForURL(const WebCore::KURL* url) -{ - return mUserAgent; -} - -void -WebFrame::didReceiveIcon(WebCore::Image* icon) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - LOG_ASSERT(icon, "DidReceiveIcon called without an image!"); - JNIEnv* env = getJNIEnv(); - jobject bitmap = webcoreImageToJavaBitmap(env, icon); - if (!bitmap) - return; - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidReceiveIcon, bitmap); - env->DeleteLocalRef(bitmap); - checkException(env); -} - -void -WebFrame::didReceiveTouchIconURL(const WTF::String& url, bool precomposed) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - jstring jUrlStr = wtfStringToJstring(env, url); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mDidReceiveTouchIconUrl, jUrlStr, precomposed); - env->DeleteLocalRef(jUrlStr); - checkException(env); -} - -void -WebFrame::updateVisitedHistory(const WebCore::KURL& url, bool reload) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - const WTF::String& urlStr = url.string(); - JNIEnv* env = getJNIEnv(); - jstring jUrlStr = wtfStringToJstring(env, urlStr); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload); - env->DeleteLocalRef(jUrlStr); - checkException(env); -} - -bool -WebFrame::canHandleRequest(const WebCore::ResourceRequest& request) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - // always handle "POST" in place - if (equalIgnoringCase(request.httpMethod(), "POST")) - return true; - const WebCore::KURL& requestUrl = request.url(); - bool isUserGesture = UserGestureIndicator::processingUserGesture(); - if (!mUserInitiatedAction && !isUserGesture && - (requestUrl.protocolIs("http") || requestUrl.protocolIs("https") || - requestUrl.protocolIs("file") || requestUrl.protocolIs("about") || - WebCore::protocolIsJavaScript(requestUrl.string()))) - return true; - const WTF::String& url = requestUrl.string(); - // Empty urls should not be sent to java - if (url.isEmpty()) - return true; - JNIEnv* env = getJNIEnv(); - jstring jUrlStr = wtfStringToJstring(env, url); - - // check to see whether browser app wants to hijack url loading. - // if browser app handles the url, we will return false to bail out WebCore loading - jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(), mJavaFrame->mHandleUrl, jUrlStr); - checkException(env); - env->DeleteLocalRef(jUrlStr); - return (ret == 0); -} - -bool -WebFrame::shouldSaveFormData() -{ - JNIEnv* env = getJNIEnv(); - jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mShouldSaveFormData); - checkException(env); - return ret; -} - -WebCore::Frame* -WebFrame::createWindow(bool dialog, bool userGesture) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - jobject obj = env->CallObjectMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mCreateWindow, dialog, userGesture); - if (obj) { - WebCore::Frame* frame = GET_NATIVE_FRAME(env, obj); - return frame; - } - return NULL; -} - -void -WebFrame::requestFocus() const -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mRequestFocus); - checkException(env); -} - -void -WebFrame::closeWindow(WebViewCore* webViewCore) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - assert(webViewCore); - JNIEnv* env = getJNIEnv(); - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mCloseWindow, - webViewCore->getJavaObject().get()); -} - -struct PolicyFunctionWrapper { - WebCore::FramePolicyFunction func; -}; - -void -WebFrame::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - PolicyFunctionWrapper* p = new PolicyFunctionWrapper; - p->func = func; - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDecidePolicyForFormResubmission, p); -} - -WTF::String -WebFrame::getRawResourceFilename(WebCore::PlatformBridge::rawResId id) const -{ - JNIEnv* env = getJNIEnv(); - jstring ret = (jstring) env->CallObjectMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mGetRawResFilename, (int)id); - - return jstringToWtfString(env, ret); -} - -float -WebFrame::density() const -{ - JNIEnv* env = getJNIEnv(); - jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity); - checkException(env); - return dpi; -} - -#if USE(CHROME_NETWORK_STACK) -void -WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const std::string& host, const std::string& realm, bool useCachedCredentials) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - int jHandle = reinterpret_cast<int>(client); - jstring jHost = stdStringToJstring(env, host, true); - jstring jRealm = stdStringToJstring(env, realm, true); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mDidReceiveAuthenticationChallenge, jHandle, jHost, jRealm, useCachedCredentials); - env->DeleteLocalRef(jHost); - env->DeleteLocalRef(jRealm); - checkException(env); -} -#endif - -void -WebFrame::reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - int jHandle = reinterpret_cast<int>(client); - - int len = cert.length(); - jbyteArray jCert = env->NewByteArray(len); - jbyte* bytes = env->GetByteArrayElements(jCert, NULL); - cert.copy(reinterpret_cast<char*>(bytes), len); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mReportSslCertError, jHandle, cert_error, jCert); - env->DeleteLocalRef(jCert); - checkException(env); -} - -#if USE(CHROME_NETWORK_STACK) -void -WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - jstring jUrl = stdStringToJstring(env, url, true); - jstring jUserAgent = stdStringToJstring(env, userAgent, true); - jstring jContentDisposition = stdStringToJstring(env, contentDisposition, true); - jstring jMimetype = stdStringToJstring(env, mimetype, true); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, contentLength); - - env->DeleteLocalRef(jUrl); - env->DeleteLocalRef(jUserAgent); - env->DeleteLocalRef(jContentDisposition); - env->DeleteLocalRef(jMimetype); - checkException(env); -} - -void -WebFrame::didReceiveData(const char* data, int size) { -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - - jbyteArray jData = env->NewByteArray(size); - jbyte* bytes = env->GetByteArrayElements(jData, NULL); - memcpy(reinterpret_cast<char*>(bytes), data, size); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mDidReceiveData, jData, size); - env->DeleteLocalRef(jData); - checkException(env); -} - -void -WebFrame::didFinishLoading() { -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidFinishLoading); - checkException(env); -} - -#endif - -#if USE(CHROME_NETWORK_STACK) -void WebFrame::setCertificate(const std::string& cert) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); -#endif - JNIEnv* env = getJNIEnv(); - - int len = cert.length(); - jbyteArray jCert = env->NewByteArray(len); - jbyte* bytes = env->GetByteArrayElements(jCert, NULL); - cert.copy(reinterpret_cast<char*>(bytes), len); - - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetCertificate, jCert); - - env->DeleteLocalRef(jCert); - checkException(env); -} -#endif - -void WebFrame::autoLogin(const std::string& loginHeader) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimerCoutner::JavaCallbackTimeCounter); -#endif - WTF::String header(loginHeader.c_str(), loginHeader.length()); - WTF::Vector<WTF::String> split; - header.split('&', split); - if (!split.isEmpty()) { - WTF::String realm; - WTF::String account; - WTF::String args; - int len = split.size(); - while (len--) { - WTF::String& str = split[len]; - size_t equals = str.find('='); - if (equals == WTF::notFound) - continue; - - WTF::String* result = 0; - if (str.startsWith("realm", false)) - result = &realm; - else if (str.startsWith("account", false)) - result = &account; - else if (str.startsWith("args", false)) - result = &args; - - if (result) - // Decode url escape sequences before sending to the app. - *result = WebCore::decodeURLEscapeSequences(str.substring(equals + 1)); - } - - // realm and args are required parameters. - if (realm.isEmpty() || args.isEmpty()) - return; - - JNIEnv* env = getJNIEnv(); - jstring jRealm = wtfStringToJstring(env, realm, true); - jstring jAccount = wtfStringToJstring(env, account); - jstring jArgs = wtfStringToJstring(env, args, true); - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mAutoLogin, jRealm, jAccount, jArgs); - } -} - -void WebFrame::maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request) -{ - if (request.httpMethod() != "POST") - return; - - WTF::String username; - WTF::String password; - if (!getUsernamePasswordFromDom(frame, username, password)) - return; - - JNIEnv* env = getJNIEnv(); - jstring jUsername = wtfStringToJstring(env, username); - jstring jPassword = wtfStringToJstring(env, password); - jbyteArray jPostData = getPostData(request); - if (jPostData) { - env->CallVoidMethod(mJavaFrame->frame(env).get(), - mJavaFrame->mMaybeSavePassword, jPostData, jUsername, jPassword); - } - - env->DeleteLocalRef(jPostData); - env->DeleteLocalRef(jUsername); - env->DeleteLocalRef(jPassword); - checkException(env); -} - -bool WebFrame::getUsernamePasswordFromDom(WebCore::Frame* frame, WTF::String& username, WTF::String& password) -{ - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = frame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found && !node->namespaceURI().isNull() && - !node->namespaceURI().isEmpty()) { - const WTF::Vector<WebCore::FormAssociatedElement*>& elements = - ((WebCore::HTMLFormElement*)node)->associatedElements(); - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLElement* e = toHTMLElement(elements[i]); - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->isPasswordField()) - password = input->value(); - else if (input->isTextField() || input->isEmailField()) - username = input->value(); - if (!username.isNull() && !password.isNull()) - found = true; - } - } - node = form->nextItem(); - } - return found; -} - -jbyteArray WebFrame::getPostData(const WebCore::ResourceRequest& request) -{ - jbyteArray jPostDataStr = NULL; - WebCore::FormData* formdata = request.httpBody(); - if (formdata) { - JNIEnv* env = getJNIEnv(); - AutoJObject obj = mJavaFrame->frame(env); - - // We can use the formdata->flatten() but it will result in two - // memcpys, first through loading up the vector with the form data - // then another to copy it out of the vector and into the java byte - // array. Instead, we copy the form data ourselves below saving a - // memcpy. - const WTF::Vector<WebCore::FormDataElement>& elements = - formdata->elements(); - - // Sizing pass - int size = 0; - size_t n = elements.size(); - FileInfo** fileinfos = new FileInfo*[n]; - for (size_t i = 0; i < n; ++i) { - fileinfos[i] = 0; - const WebCore::FormDataElement& e = elements[i]; - if (e.m_type == WebCore::FormDataElement::data) { - size += e.m_data.size(); - } else if (e.m_type == WebCore::FormDataElement::encodedFile) { - fileinfos[i] = new FileInfo(env, e.m_filename); - int delta = env->CallIntMethod(obj.get(), - mJavaFrame->mGetFileSize, fileinfos[i]->getUri()); - checkException(env); - fileinfos[i]->setSize(delta); - size += delta; - } - } - - // Only create the byte array if there is POST data to pass up. - // The Java code is expecting null if there is no data. - if (size > 0) { - // Copy the actual form data. - jPostDataStr = env->NewByteArray(size); - if (jPostDataStr) { - // Write the form data to the java array. - jbyte* bytes = env->GetByteArrayElements(jPostDataStr, NULL); - int offset = 0; - for (size_t i = 0; i < n; ++i) { - const WebCore::FormDataElement& e = elements[i]; - if (e.m_type == WebCore::FormDataElement::data) { - int delta = e.m_data.size(); - memcpy(bytes + offset, e.m_data.data(), delta); - offset += delta; - } else if (e.m_type - == WebCore::FormDataElement::encodedFile) { - int delta = env->CallIntMethod(obj.get(), - mJavaFrame->mGetFile, fileinfos[i]->getUri(), - jPostDataStr, offset, fileinfos[i]->getSize()); - checkException(env); - offset += delta; - } - } - env->ReleaseByteArrayElements(jPostDataStr, bytes, 0); - } - } - delete[] fileinfos; - } - return jPostDataStr; -} - -// ---------------------------------------------------------------------------- - -static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeCallPolicyFunction must take a valid frame pointer!"); - PolicyFunctionWrapper* pFunc = (PolicyFunctionWrapper*)func; - LOG_ASSERT(pFunc, "nativeCallPolicyFunction must take a valid function pointer!"); - - // If we are resending the form then we should reset the multiple submission protection. - if (decision == WebCore::PolicyUse) - pFrame->loader()->resetMultipleFormSubmissionProtection(); - - (pFrame->loader()->policyChecker()->*(pFunc->func))((WebCore::PolicyAction)decision); -} - -static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAssetManager, jobject historyList) -{ - ScriptController::initializeThreading(); - -#if USE(CHROME_NETWORK_STACK) - // needs to be called before any other chromium code - initChromium(); -#endif - -#ifdef ANDROID_INSTRUMENT -#if USE(V8) - V8Counters::initCounters(); -#endif - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - // Create a new page - ChromeClientAndroid* chromeC = new ChromeClientAndroid; - EditorClientAndroid* editorC = new EditorClientAndroid; - DeviceMotionClientAndroid* deviceMotionC = new DeviceMotionClientAndroid; - DeviceOrientationClientAndroid* deviceOrientationC = new DeviceOrientationClientAndroid; - - WebCore::Page::PageClients pageClients; - pageClients.chromeClient = chromeC; - pageClients.contextMenuClient = new ContextMenuClientAndroid; - pageClients.editorClient = editorC; - pageClients.dragClient = new DragClientAndroid; - pageClients.inspectorClient = new InspectorClientAndroid; - pageClients.deviceMotionClient = deviceMotionC; - pageClients.deviceOrientationClient = deviceOrientationC; - WebCore::Page* page = new WebCore::Page(pageClients); - - editorC->setPage(page); - page->setGroupName("android.webkit"); - - // Create a WebFrame to access the Java BrowserFrame associated with this page - WebFrame* webFrame = new WebFrame(env, obj, historyList, page); - // Attach webFrame to pageClients.chromeClient and release our ownership - chromeC->setWebFrame(webFrame); - Release(webFrame); - - FrameLoaderClientAndroid* loaderC = new FrameLoaderClientAndroid(webFrame); - // Create a Frame and the page holds its reference - WebCore::Frame* frame = WebCore::Frame::create(page, NULL, loaderC).get(); - loaderC->setFrame(frame); -#if ENABLE(WDS) - WDS::server()->addFrame(frame); -#endif - - // Create a WebViewCore to access the Java WebViewCore associated with this page - WebViewCore* webViewCore = new WebViewCore(env, javaview, frame); - -#if ENABLE(WEB_AUTOFILL) - editorC->getAutoFill()->setWebViewCore(webViewCore); -#endif - - // Create a FrameView - RefPtr<WebCore::FrameView> frameView = WebCore::FrameView::create(frame); - // Create a WebFrameView - WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore); - // As webFrameView Retains webViewCore, release our ownership - Release(webViewCore); - // As frameView Retains webFrameView, release our ownership - Release(webFrameView); - // Attach the frameView to the frame and release our ownership - frame->setView(frameView); - // Set the frame to active to turn on keyboard focus. - frame->init(); - frame->selection()->setFocused(true); - frame->page()->focusController()->setFocused(true); - deviceMotionC->setWebViewCore(webViewCore); - deviceOrientationC->setWebViewCore(webViewCore); - - // Allow local access to file:/// and substitute data - WebCore::SecurityOrigin::setLocalLoadPolicy( - WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); - - LOGV("::WebCore:: createFrame %p", frame); - - // Set the mNativeFrame field in Frame - SET_NATIVE_FRAME(env, obj, (int)frame); - - String directory = webFrame->getRawResourceFilename( - WebCore::PlatformBridge::DrawableDir); - if (directory.isEmpty()) - LOGE("Can't find the drawable directory"); - else { - // Setup the asset manager. - AssetManager* am = assetManagerForJavaObject(env, jAssetManager); - // Initialize our skinning classes - webFrame->setRenderSkins(new WebCore::RenderSkinAndroid(am, directory)); - } - for (int i = WebCore::PlatformBridge::FileUploadLabel; - i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++) - initGlobalLocalizedName( - static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame); -} - -static void DestroyFrame(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeDestroyFrame must take a valid frame pointer!"); - - LOGV("::WebCore:: deleting frame %p", pFrame); - - WebCore::FrameView* view = pFrame->view(); - view->ref(); - // detachFromParent will cause the page to be closed. - WebCore::FrameLoader* fl = pFrame->loader(); - // retain a pointer because detachFromParent will set the page to null. - WebCore::Page* page = pFrame->page(); - if (fl) - fl->detachFromParent(); - delete page; - view->deref(); - - SET_NATIVE_FRAME(env, obj, 0); -#if ENABLE(WDS) - WDS::server()->removeFrame(pFrame); -#endif -} - -static void LoadUrl(JNIEnv *env, jobject obj, jstring url, jobject headers) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadUrl must take a valid frame pointer!"); - - WTF::String webcoreUrl = jstringToWtfString(env, url); - WebCore::KURL kurl(WebCore::KURL(), webcoreUrl); - WebCore::ResourceRequest request(kurl); - if (headers) { - // dalvikvm will raise exception if any of these fail - jclass mapClass = env->FindClass("java/util/Map"); - jmethodID entrySet = env->GetMethodID(mapClass, "entrySet", - "()Ljava/util/Set;"); - jobject set = env->CallObjectMethod(headers, entrySet); - - jclass setClass = env->FindClass("java/util/Set"); - jmethodID iterator = env->GetMethodID(setClass, "iterator", - "()Ljava/util/Iterator;"); - jobject iter = env->CallObjectMethod(set, iterator); - - jclass iteratorClass = env->FindClass("java/util/Iterator"); - jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z"); - jmethodID next = env->GetMethodID(iteratorClass, "next", - "()Ljava/lang/Object;"); - jclass entryClass = env->FindClass("java/util/Map$Entry"); - jmethodID getKey = env->GetMethodID(entryClass, "getKey", - "()Ljava/lang/Object;"); - jmethodID getValue = env->GetMethodID(entryClass, "getValue", - "()Ljava/lang/Object;"); - - while (env->CallBooleanMethod(iter, hasNext)) { - jobject entry = env->CallObjectMethod(iter, next); - jstring key = (jstring) env->CallObjectMethod(entry, getKey); - jstring value = (jstring) env->CallObjectMethod(entry, getValue); - request.setHTTPHeaderField(jstringToWtfString(env, key), jstringToWtfString(env, value)); - env->DeleteLocalRef(entry); - env->DeleteLocalRef(key); - env->DeleteLocalRef(value); - } - - env->DeleteLocalRef(entryClass); - env->DeleteLocalRef(iteratorClass); - env->DeleteLocalRef(iter); - env->DeleteLocalRef(setClass); - env->DeleteLocalRef(set); - env->DeleteLocalRef(mapClass); - } - LOGV("LoadUrl %s", kurl.string().latin1().data()); - pFrame->loader()->load(request, false); -} - -static void PostUrl(JNIEnv *env, jobject obj, jstring url, jbyteArray postData) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativePostUrl must take a valid frame pointer!"); - - WebCore::KURL kurl(WebCore::KURL(), jstringToWtfString(env, url)); - WebCore::ResourceRequest request(kurl); - request.setHTTPMethod("POST"); - request.setHTTPContentType("application/x-www-form-urlencoded"); - - if (postData) { - jsize size = env->GetArrayLength(postData); - jbyte* bytes = env->GetByteArrayElements(postData, NULL); - RefPtr<FormData> formData = FormData::create((const void*)bytes, size); - // the identifier uses the same logic as generateFormDataIdentifier() in - // HTMLFormElement.cpp - formData->setIdentifier(static_cast<int64_t>(WTF::currentTime() * 1000000.0)); - request.setHTTPBody(formData); - env->ReleaseByteArrayElements(postData, bytes, 0); - } - - LOGV("PostUrl %s", kurl.string().latin1().data()); - WebCore::FrameLoadRequest frameRequest(pFrame->document()->securityOrigin(), request); - pFrame->loader()->loadFrameRequest(frameRequest, false, false, 0, 0, WebCore::SendReferrer); -} - -static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data, - jstring mimeType, jstring encoding, jstring failUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeLoadData must take a valid frame pointer!"); - - // Setup the resource request - WebCore::ResourceRequest request(jstringToWtfString(env, baseUrl)); - - // Setup the substituteData - const char* dataStr = env->GetStringUTFChars(data, NULL); - WTF::PassRefPtr<WebCore::SharedBuffer> sharedBuffer = - WebCore::SharedBuffer::create(); - LOG_ASSERT(dataStr, "nativeLoadData has a null data string."); - sharedBuffer->append(dataStr, strlen(dataStr)); - env->ReleaseStringUTFChars(data, dataStr); - - WebCore::SubstituteData substituteData(sharedBuffer, - jstringToWtfString(env, mimeType), jstringToWtfString(env, encoding), - WebCore::KURL(ParsedURLString, jstringToWtfString(env, failUrl))); - - // Perform the load - pFrame->loader()->load(request, substituteData, false); -} - -static void StopLoading(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeStopLoading must take a valid frame pointer!"); - LOGV("::WebCore:: stopLoading %p", pFrame); - - // Stop loading the page and do not send an unload event - pFrame->loader()->stopForUserCancel(); -} - -#if ENABLE(ARCHIVE) -static String saveArchiveAutoname(String basename, String name, String extension) { - if (name.isNull() || name.isEmpty()) { - name = String("index"); - } - - String testname = basename; - testname.append(name); - testname.append(extension); - - errno = 0; - struct stat permissions; - if (stat(testname.utf8().data(), &permissions) < 0) { - if (errno == ENOENT) - return testname; - return String(); - } - - const int maxAttempts = 100; - for (int i = 1; i < maxAttempts; i++) { - String testname = basename; - testname.append(name); - testname.append("-"); - testname.append(String::number(i)); - testname.append(extension); - - errno = 0; - if (stat(testname.utf8().data(), &permissions) < 0) { - if (errno == ENOENT) - return testname; - return String(); - } - } - - return String(); -} -#endif - -static jstring SaveWebArchive(JNIEnv *env, jobject obj, jstring basename, jboolean autoname) -{ -#if ENABLE(ARCHIVE) - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeSaveWebArchive must take a valid frame pointer!"); - String mimeType = pFrame->loader()->documentLoader()->mainResource()->mimeType(); - if ((mimeType != "text/html") && (mimeType != "application/xhtml+xml")) - return NULL; - - const char* basenameNative = getCharactersFromJStringInEnv(env, basename); - String basenameString = String::fromUTF8(basenameNative); - String filename; - - if (autoname) { - String name = pFrame->loader()->documentLoader()->originalURL().lastPathComponent(); - String extension = String(".webarchivexml"); - filename = saveArchiveAutoname(basenameString, name, extension); - } else { - filename = basenameString; - } - - if (filename.isNull() || filename.isEmpty()) { - LOGD("saveWebArchive: Failed to select a filename to save."); - releaseCharactersForJStringInEnv(env, basename, basenameNative); - return NULL; - } - - const int noCompression = 0; - xmlTextWriterPtr writer = xmlNewTextWriterFilename(filename.utf8().data(), noCompression); - if (writer == NULL) { - LOGD("saveWebArchive: Failed to initialize xml writer."); - releaseCharactersForJStringInEnv(env, basename, basenameNative); - return NULL; - } - - RefPtr<WebArchiveAndroid> archive = WebCore::WebArchiveAndroid::create(pFrame); - - bool result = archive->saveWebArchive(writer); - - releaseCharactersForJStringInEnv(env, basename, basenameNative); - xmlFreeTextWriter(writer); - - if (result) - return wtfStringToJstring(env, filename); - - return NULL; -#endif -} - -static jstring ExternalRepresentation(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!"); - - // Request external representation of the render tree - WTF::String renderDump = WebCore::externalRepresentation(pFrame); - return wtfStringToJstring(env, renderDump); -} - -static StringBuilder FrameAsText(WebCore::Frame *pFrame, jboolean dumpChildFrames) { - StringBuilder renderDump; - if (!pFrame) - return renderDump; - WebCore::Element *documentElement = pFrame->document()->documentElement(); - if (!documentElement) - return renderDump; - if (pFrame->tree()->parent()) { - renderDump.append("\n--------\nFrame: '"); - renderDump.append(pFrame->tree()->name()); - renderDump.append("'\n--------\n"); - } - renderDump.append(((WebCore::HTMLElement*)documentElement)->innerText()); - renderDump.append("\n"); - if (dumpChildFrames) { - for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) { - renderDump.append(FrameAsText(pFrame->tree()->child(i), dumpChildFrames).toString()); - } - } - return renderDump; -} - -static jstring DocumentAsText(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!"); - - WTF::String renderDump = FrameAsText(pFrame, false /* dumpChildFrames */).toString(); - return wtfStringToJstring(env, renderDump); -} - -static jstring ChildFramesAsText(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "android_webcore_nativeDocumentAsText must take a valid frame pointer!"); - - StringBuilder renderDumpBuilder; - for (unsigned i = 0; i < pFrame->tree()->childCount(); ++i) { - renderDumpBuilder.append(FrameAsText(pFrame->tree()->child(i), true /* dumpChildFrames */).toString()); - } - WTF::String renderDump = renderDumpBuilder.toString(); - return wtfStringToJstring(env, renderDump); -} - -static void Reload(JNIEnv *env, jobject obj, jboolean allowStale) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeReload must take a valid frame pointer!"); - - WebCore::FrameLoader* loader = pFrame->loader(); - if (allowStale) { - // load the current page with FrameLoadTypeIndexedBackForward so that it - // will use cache when it is possible - WebCore::Page* page = pFrame->page(); - WebCore::HistoryItem* item = page->backForwardList()->currentItem(); - if (item) - page->goToItem(item, FrameLoadTypeIndexedBackForward); - } else - loader->reload(true); -} - -static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "nativeGoBackOrForward must take a valid frame pointer!"); - - if (pos == 1) - pFrame->page()->goForward(); - else if (pos == -1) - pFrame->page()->goBack(); - else - pFrame->page()->goBackOrForward(pos); -} - -static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!"); - - WebCore::ScriptValue value = - pFrame->script()->executeScript(jstringToWtfString(env, script), true); - WTF::String result = WTF::String(); - ScriptState* scriptState = mainWorldScriptState(pFrame); - if (!value.getString(scriptState, result)) - return NULL; - return wtfStringToJstring(env, result); -} - -// Wrap the JavaInstance used when binding custom javascript interfaces. Use a -// weak reference so that the gc can collect the WebView. Override virtualBegin -// and virtualEnd and swap the weak reference for the real object. -class WeakJavaInstance : public JavaInstance { -public: -#if USE(JSC) - static PassRefPtr<WeakJavaInstance> create(jobject obj, PassRefPtr<RootObject> root) - { - return adoptRef(new WeakJavaInstance(obj, root)); - } -#elif USE(V8) - static PassRefPtr<WeakJavaInstance> create(jobject obj) - { - return adoptRef(new WeakJavaInstance(obj)); - } -#endif - -private: -#if USE(JSC) - WeakJavaInstance(jobject instance, PassRefPtr<RootObject> rootObject) - : JavaInstance(instance, rootObject) -#elif USE(V8) - WeakJavaInstance(jobject instance) - : JavaInstance(instance) -#endif - , m_beginEndDepth(0) - { - JNIEnv* env = getJNIEnv(); - // JavaInstance creates a global ref to instance in its constructor. - env->DeleteGlobalRef(m_instance->instance()); - // Set the object to a weak reference. - m_instance->setInstance(env->NewWeakGlobalRef(instance)); - } - ~WeakJavaInstance() - { - JNIEnv* env = getJNIEnv(); - // Store the weak reference so we can delete it later. - jweak weak = m_instance->instance(); - // The JavaInstance destructor attempts to delete the global ref stored - // in m_instance. Since we replaced it in our constructor with a weak - // reference, restore the global ref here so the vm will not complain. - m_instance->setInstance(env->NewGlobalRef( - getRealObject(env, m_instance->instance()).get())); - // Delete the weak reference. - env->DeleteWeakGlobalRef(weak); - } - - virtual void virtualBegin() - { - if (m_beginEndDepth++ > 0) - return; - m_weakRef = m_instance->instance(); - JNIEnv* env = getJNIEnv(); - // This is odd. getRealObject returns an AutoJObject which is used to - // cleanly create and delete a local reference. But, here we need to - // maintain the local reference across calls to virtualBegin() and - // virtualEnd(). So, release the local reference from the AutoJObject - // and delete the local reference in virtualEnd(). - m_realObject = getRealObject(env, m_weakRef).release(); - // Point to the real object - m_instance->setInstance(m_realObject); - // Call the base class method - INHERITED::virtualBegin(); - } - - virtual void virtualEnd() - { - if (--m_beginEndDepth > 0) - return; - // Call the base class method first to pop the local frame. - INHERITED::virtualEnd(); - // Get rid of the local reference to the real object. - getJNIEnv()->DeleteLocalRef(m_realObject); - // Point back to the WeakReference. - m_instance->setInstance(m_weakRef); - } - -private: - typedef JavaInstance INHERITED; - jobject m_realObject; - jweak m_weakRef; - // The current depth of nested calls to virtualBegin and virtualEnd. - int m_beginEndDepth; -}; - -static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer, - jobject javascriptObj, jstring interfaceName) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = 0; - if (nativeFramePointer == 0) - pFrame = GET_NATIVE_FRAME(env, obj); - else - pFrame = (WebCore::Frame*)nativeFramePointer; - LOG_ASSERT(pFrame, "nativeAddJavascriptInterface must take a valid frame pointer!"); - - JavaVM* vm; - env->GetJavaVM(&vm); - LOGV("::WebCore:: addJSInterface: %p", pFrame); - -#if USE(JSC) - // Copied from qwebframe.cpp - JSC::JSLock lock(JSC::SilenceAssertionsOnly); - WebCore::JSDOMWindow *window = WebCore::toJSDOMWindow(pFrame, mainThreadNormalWorld()); - if (window) { - RootObject *root = pFrame->script()->bindingRootObject(); - setJavaVM(vm); - // Add the binding to JS environment - JSC::ExecState* exec = window->globalExec(); - JSC::JSObject* addedObject = WeakJavaInstance::create(javascriptObj, - root)->createRuntimeObject(exec); - const jchar* s = env->GetStringChars(interfaceName, NULL); - if (s) { - // Add the binding name to the window's table of child objects. - JSC::PutPropertySlot slot; - window->put(exec, JSC::Identifier(exec, (const UChar *)s, - env->GetStringLength(interfaceName)), addedObject, slot); - env->ReleaseStringChars(interfaceName, s); - checkException(env); - } - } -#elif USE(V8) - if (pFrame) { - RefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj); - const char* name = getCharactersFromJStringInEnv(env, interfaceName); - // Pass ownership of the added object to bindToWindowObject. - NPObject* npObject = JavaInstanceToNPObject(addedObject.get()); - pFrame->script()->bindToWindowObject(pFrame, name, npObject); - // bindToWindowObject calls NPN_RetainObject on the - // returned one (see createV8ObjectForNPObject in V8NPObject.cpp). - // bindToWindowObject also increases obj's ref count and decreases - // the ref count when the object is not reachable from JavaScript - // side. Code here must release the reference count increased by - // bindToWindowObject. - - // Note that while this function is declared in WebCore/bridge/npruntime.h, for V8 builds - // we use WebCore/bindings/v8/npruntime.cpp (rather than - // WebCore/bridge/npruntime.cpp), so the function is implemented there. - // TODO: Combine the two versions of these NPAPI files. - NPN_ReleaseObject(npObject); - releaseCharactersForJString(interfaceName, name); - } -#endif - -} - -static void SetCacheDisabled(JNIEnv *env, jobject obj, jboolean disabled) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::cache()->setDisabled(disabled); -} - -static jboolean CacheDisabled(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - return WebCore::cache()->disabled(); -} - -static void ClearWebCoreCache() -{ - if (!WebCore::cache()->disabled()) { - // Disabling the cache will remove all resources from the cache. They may - // still live on if they are referenced by some Web page though. - WebCore::cache()->setDisabled(true); - WebCore::cache()->setDisabled(false); - } - - // clear page cache - int pageCapacity = WebCore::pageCache()->capacity(); - // Setting size to 0, makes all pages be released. - WebCore::pageCache()->setCapacity(0); - WebCore::pageCache()->releaseAutoreleasedPagesNow(); - WebCore::pageCache()->setCapacity(pageCapacity); -} - -static void ClearWebViewCache() -{ -#if USE(CHROME_NETWORK_STACK) - WebCache::get(false /*privateBrowsing*/)->clear(); -#else - // The Android network stack provides a WebView cache in CacheManager.java. - // Clearing this is handled entirely Java-side. -#endif -} - -static void ClearCache(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#if USE(JSC) - JSC::JSLock lock(false); - JSC::Heap::Statistics jsHeapStatistics = WebCore::JSDOMWindow::commonJSGlobalData()->heap.statistics(); - LOGD("About to gc and JavaScript heap size is %d and has %d bytes free", - jsHeapStatistics.size, jsHeapStatistics.free); -#endif // USE(JSC) - LOGD("About to clear cache and current cache has %d bytes live and %d bytes dead", - cache()->getLiveSize(), cache()->getDeadSize()); -#endif // ANDROID_INSTRUMENT - ClearWebCoreCache(); - ClearWebViewCache(); -#if USE(JSC) - // force JavaScript to GC when clear cache - WebCore::gcController().garbageCollectSoon(); -#elif USE(V8) - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - pFrame->script()->lowMemoryNotification(); -#endif // USE(JSC) -} - -static jboolean DocumentHasImages(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "DocumentHasImages must take a valid frame pointer!"); - - return pFrame->document()->images()->length() > 0; -} - -static jboolean HasPasswordField(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "HasPasswordField must take a valid frame pointer!"); - - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - // Null/Empty namespace means that node is not created in HTMLFormElement - // class, but just normal Element class. - while (node && !found && !node->namespaceURI().isNull() && - !node->namespaceURI().isEmpty()) { - const WTF::Vector<WebCore::FormAssociatedElement*>& elements = - ((WebCore::HTMLFormElement*)node)->associatedElements(); - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLElement* e = toHTMLElement(elements[i]); - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - if (static_cast<WebCore::HTMLInputElement*>(e)->isPasswordField()) - found = true; - } - } - node = form->nextItem(); - } - return found; -} - -static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!"); - jobjectArray strArray = NULL; - WTF::String username; - WTF::String password; - if (WebFrame::getWebFrame(pFrame)->getUsernamePasswordFromDom(pFrame, username, password)) { - jclass stringClass = env->FindClass("java/lang/String"); - strArray = env->NewObjectArray(2, stringClass, NULL); - env->DeleteLocalRef(stringClass); - env->SetObjectArrayElement(strArray, 0, wtfStringToJstring(env, username)); - env->SetObjectArrayElement(strArray, 1, wtfStringToJstring(env, password)); - } - return strArray; -} - -static void SetUsernamePassword(JNIEnv *env, jobject obj, - jstring username, jstring password) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOG_ASSERT(pFrame, "SetUsernamePassword must take a valid frame pointer!"); - - WebCore::HTMLInputElement* usernameEle = NULL; - WebCore::HTMLInputElement* passwordEle = NULL; - bool found = false; - WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms(); - WebCore::Node* node = form->firstItem(); - while (node && !found && !node->namespaceURI().isNull() && - !node->namespaceURI().isEmpty()) { - const WTF::Vector<WebCore::FormAssociatedElement*>& elements = - ((WebCore::HTMLFormElement*)node)->associatedElements(); - size_t size = elements.size(); - for (size_t i = 0; i< size && !found; i++) { - WebCore::HTMLElement* e = toHTMLElement(elements[i]); - if (e->hasLocalName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e; - if (input->autoComplete() == false) - continue; - if (input->isPasswordField()) - passwordEle = input; - else if (input->isTextField() || input->isEmailField()) - usernameEle = input; - if (usernameEle != NULL && passwordEle != NULL) - found = true; - } - } - node = form->nextItem(); - } - if (found) { - usernameEle->setValue(jstringToWtfString(env, username)); - passwordEle->setValue(jstringToWtfString(env, password)); - } -} - -void -WebFrame::saveFormData(HTMLFormElement* form) -{ - if (form->autoComplete()) { - JNIEnv* env = getJNIEnv(); - jclass mapClass = env->FindClass("java/util/HashMap"); - LOG_ASSERT(mapClass, "Could not find HashMap class!"); - jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for HashMap"); - jobject hashMap = env->NewObject(mapClass, init, 1); - LOG_ASSERT(hashMap, "Could not create a new HashMap"); - jmethodID put = env->GetMethodID(mapClass, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - LOG_ASSERT(put, "Could not find put method on HashMap"); - WTF::Vector<WebCore::FormAssociatedElement*> elements = form->associatedElements(); - size_t size = elements.size(); - for (size_t i = 0; i < size; i++) { - WebCore::HTMLElement* e = toHTMLElement(elements[i]); - if (e->hasTagName(WebCore::HTMLNames::inputTag)) { - WebCore::HTMLInputElement* input = static_cast<WebCore::HTMLInputElement*>(e); - if (input->isTextField() && !input->isPasswordField() - && input->autoComplete()) { - WTF::String value = input->value(); - int len = value.length(); - if (len) { - const WTF::AtomicString& name = input->name(); - jstring key = wtfStringToJstring(env, name); - jstring val = wtfStringToJstring(env, value); - LOG_ASSERT(key && val, "name or value not set"); - env->CallObjectMethod(hashMap, put, key, val); - env->DeleteLocalRef(key); - env->DeleteLocalRef(val); - } - } - } - } - env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSaveFormData, hashMap); - env->DeleteLocalRef(hashMap); - env->DeleteLocalRef(mapClass); - } -} - -static void OrientationChanged(JNIEnv *env, jobject obj, int orientation) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter); -#endif - WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj); - LOGV("Sending orientation: %d", orientation); - pFrame->sendOrientationChangeEvent(orientation); -} - -#if USE(CHROME_NETWORK_STACK) - -static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword) -{ - WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); - std::string username = jstringToStdString(env, jUsername); - std::string password = jstringToStdString(env, jPassword); - client->setAuth(username, password); -} - -static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle) -{ - WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); - client->cancelAuth(); -} - -static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle) -{ - WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); - client->proceedSslCertError(); -} - -static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error) -{ - WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); - client->cancelSslCertError(cert_error); -} - -#else - -static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword) -{ - LOGW("Chromium authentication API called, but libchromium is not available"); -} - -static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle) -{ - LOGW("Chromium authentication API called, but libchromium is not available"); -} - -static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle) -{ - LOGW("Chromium SSL API called, but libchromium is not available"); -} - -static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error) -{ - LOGW("Chromium SSL API called, but libchromium is not available"); -} - -#endif // USE(CHROME_NETWORK_STACK) - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gBrowserFrameNativeMethods[] = { - /* name, signature, funcPtr */ - { "nativeCallPolicyFunction", "(II)V", - (void*) CallPolicyFunction }, - { "nativeCreateFrame", "(Landroid/webkit/WebViewCore;Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V", - (void*) CreateFrame }, - { "nativeDestroyFrame", "()V", - (void*) DestroyFrame }, - { "nativeStopLoading", "()V", - (void*) StopLoading }, - { "nativeLoadUrl", "(Ljava/lang/String;Ljava/util/Map;)V", - (void*) LoadUrl }, - { "nativePostUrl", "(Ljava/lang/String;[B)V", - (void*) PostUrl }, - { "nativeLoadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - (void*) LoadData }, - { "nativeSaveWebArchive", "(Ljava/lang/String;Z)Ljava/lang/String;", - (void*) SaveWebArchive }, - { "externalRepresentation", "()Ljava/lang/String;", - (void*) ExternalRepresentation }, - { "documentAsText", "()Ljava/lang/String;", - (void*) DocumentAsText }, - { "childFramesAsText", "()Ljava/lang/String;", - (void*) ChildFramesAsText }, - { "reload", "(Z)V", - (void*) Reload }, - { "nativeGoBackOrForward", "(I)V", - (void*) GoBackOrForward }, - { "nativeAddJavascriptInterface", "(ILjava/lang/Object;Ljava/lang/String;)V", - (void*) AddJavascriptInterface }, - { "stringByEvaluatingJavaScriptFromString", - "(Ljava/lang/String;)Ljava/lang/String;", - (void*) StringByEvaluatingJavaScriptFromString }, - { "setCacheDisabled", "(Z)V", - (void*) SetCacheDisabled }, - { "cacheDisabled", "()Z", - (void*) CacheDisabled }, - { "clearCache", "()V", - (void*) ClearCache }, - { "documentHasImages", "()Z", - (void*) DocumentHasImages }, - { "hasPasswordField", "()Z", - (void*) HasPasswordField }, - { "getUsernamePassword", "()[Ljava/lang/String;", - (void*) GetUsernamePassword }, - { "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V", - (void*) SetUsernamePassword }, - { "nativeOrientationChanged", "(I)V", - (void*) OrientationChanged }, - { "nativeAuthenticationProceed", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) AuthenticationProceed }, - { "nativeAuthenticationCancel", "(I)V", - (void*) AuthenticationCancel }, - { "nativeSslCertErrorProceed", "(I)V", - (void*) SslCertErrorProceed }, - { "nativeSslCertErrorCancel", "(II)V", - (void*) SslCertErrorCancel }, -}; - -int registerWebFrame(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/BrowserFrame"); - LOG_ASSERT(clazz, "Cannot find BrowserFrame"); - gFrameField = env->GetFieldID(clazz, "mNativeFrame", "I"); - LOG_ASSERT(gFrameField, "Cannot find mNativeFrame on BrowserFrame"); - env->DeleteLocalRef(clazz); - - return jniRegisterNativeMethods(env, "android/webkit/BrowserFrame", - gBrowserFrameNativeMethods, NELEM(gBrowserFrameNativeMethods)); -} - -} /* namespace android */ diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h deleted file mode 100644 index 6522a5f..0000000 --- a/WebKit/android/jni/WebCoreFrameBridge.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2006, 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. - */ - -// TODO: change name to WebFrame.h - -#ifndef WEBFRAME_H -#define WEBFRAME_H - -#include "FrameLoaderClient.h" -#include "PlatformBridge.h" -#include "PlatformString.h" -#include "WebCoreRefObject.h" -#include <jni.h> -#include <string> -#include <wtf/RefCounted.h> - -namespace WebCore { - class HTMLFormElement; - class Frame; - class HistoryItem; - class Image; - class Page; - class RenderPart; - class RenderSkinAndroid; - class ResourceHandle; - class ResourceLoaderAndroid; - class ResourceRequest; -} - -namespace android { - -class WebViewCore; -class WebUrlLoaderClient; -class UrlInterceptResponse; - -// one instance of WebFrame per Page for calling into Java's BrowserFrame -class WebFrame : public WebCoreRefObject { - public: - WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* page); - ~WebFrame(); - - // helper function - static WebFrame* getWebFrame(const WebCore::Frame* frame); - - virtual PassRefPtr<WebCore::ResourceLoaderAndroid> startLoadingResource(WebCore::ResourceHandle*, - const WebCore::ResourceRequest& request, bool mainResource, - bool synchronous); - - UrlInterceptResponse* shouldInterceptRequest(const WTF::String& url); - - void reportError(int errorCode, const WTF::String& description, - const WTF::String& failingUrl); - - void loadStarted(WebCore::Frame* frame); - - void transitionToCommitted(WebCore::Frame* frame); - - void didFinishLoad(WebCore::Frame* frame); - - void addHistoryItem(WebCore::HistoryItem* item); - - void removeHistoryItem(int index); - - void updateHistoryIndex(int newIndex); - - void setTitle(const WTF::String& title); - - void windowObjectCleared(WebCore::Frame* frame); - - void setProgress(float newProgress); - - const WTF::String userAgentForURL(const WebCore::KURL* url); - - void didReceiveIcon(WebCore::Image* icon); - - void didReceiveTouchIconURL(const WTF::String& url, bool precomposed); - - void updateVisitedHistory(const WebCore::KURL& url, bool reload); - - virtual bool canHandleRequest(const WebCore::ResourceRequest& request); - - WebCore::Frame* createWindow(bool dialog, bool userGesture); - - void requestFocus() const; - - void closeWindow(WebViewCore* webViewCore); - - void decidePolicyForFormResubmission(WebCore::FramePolicyFunction func); - - void setUserAgent(WTF::String userAgent) { mUserAgent = userAgent; } - - WTF::String getRawResourceFilename(WebCore::PlatformBridge::rawResId) const; - - float density() const; - - void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials); - - void reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert); - - void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength); - - void didReceiveData(const char* data, int size); - - void didFinishLoading(); - - void maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request); - - void setCertificate(const std::string& cert); - - // Parse the x-auto-login header and propagate the parameters to the - // application. - void autoLogin(const std::string& loginHeader); - - /** - * When the user initiates a click, we set mUserInitiatedAction to true. - * If a load happens due to this click, then we ask the application if it wants - * to override the load. Otherwise, we attempt to load the resource internally. - */ - void setUserInitiatedAction(bool userInitiatedAction) { mUserInitiatedAction = userInitiatedAction; } - - WebCore::Page* page() const { return mPage; } - - // Currently used only by the chrome net stack. A similar field is used by - // FrameLoader.java to block java network loads. - void setBlockNetworkLoads(bool block) { mBlockNetworkLoads = block; } - bool blockNetworkLoads() const { return mBlockNetworkLoads; } - - /** - * Helper methods. These are typically chunks of code that are called in - * slightly different ways by the Apache and Chrome HTTP stacks. - */ - bool getUsernamePasswordFromDom(WebCore::Frame* frame, WTF::String& username, WTF::String& password); - jbyteArray getPostData(const WebCore::ResourceRequest& request); - - bool shouldSaveFormData(); - void saveFormData(WebCore::HTMLFormElement*); - const WebCore::RenderSkinAndroid* renderSkins() const { return m_renderSkins; } - void setRenderSkins(const WebCore::RenderSkinAndroid* skins) { m_renderSkins = skins; } -private: - struct JavaBrowserFrame; - JavaBrowserFrame* mJavaFrame; - WebCore::Page* mPage; - WTF::String mUserAgent; - bool mBlockNetworkLoads; - bool mUserInitiatedAction; - const WebCore::RenderSkinAndroid* m_renderSkins; -}; - -} // namespace android - -#endif // WEBFRAME_H diff --git a/WebKit/android/jni/WebCoreJni.cpp b/WebKit/android/jni/WebCoreJni.cpp deleted file mode 100644 index 2a07999..0000000 --- a/WebKit/android/jni/WebCoreJni.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007, 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 "webcoreglue" - -#include "config.h" -#include "WebCoreJni.h" - -#include "NotImplemented.h" -#include <JNIUtility.h> -#include <jni.h> -#include <utils/Log.h> - -namespace android { - -AutoJObject getRealObject(JNIEnv* env, jobject obj) -{ - jobject real = env->NewLocalRef(obj); - LOG_ASSERT(real, "The real object has been deleted!"); - return AutoJObject(env, real); -} - -/** - * Helper method for checking java exceptions - * @return true if an exception occurred. - */ -bool checkException(JNIEnv* env) -{ - if (env->ExceptionCheck() != 0) - { - LOGE("*** Uncaught exception returned from Java call!\n"); - env->ExceptionDescribe(); - return true; - } - return false; -} - -// This method is safe to call from the ui thread and the WebCore thread. -WTF::String jstringToWtfString(JNIEnv* env, jstring str) -{ - if (!str || !env) - return WTF::String(); - const jchar* s = env->GetStringChars(str, NULL); - if (!s) - return WTF::String(); - WTF::String ret(s, env->GetStringLength(str)); - env->ReleaseStringChars(str, s); - checkException(env); - return ret; -} - -jstring wtfStringToJstring(JNIEnv* env, const WTF::String& str, bool validOnZeroLength) -{ - int length = str.length(); - return length || validOnZeroLength ? env->NewString(str.characters(), length) : 0; -} - - -#if USE(CHROME_NETWORK_STACK) -string16 jstringToString16(JNIEnv* env, jstring jstr) -{ - if (!jstr || !env) - return string16(); - - const char* s = env->GetStringUTFChars(jstr, 0); - if (!s) - return string16(); - string16 str = UTF8ToUTF16(s); - env->ReleaseStringUTFChars(jstr, s); - checkException(env); - return str; -} - -std::string jstringToStdString(JNIEnv* env, jstring jstr) -{ - if (!jstr || !env) - return std::string(); - - const char* s = env->GetStringUTFChars(jstr, 0); - if (!s) - return std::string(); - std::string str(s); - env->ReleaseStringUTFChars(jstr, s); - checkException(env); - return str; -} - -jstring stdStringToJstring(JNIEnv* env, const std::string& str, bool validOnZeroLength) -{ - return !str.empty() || validOnZeroLength ? env->NewStringUTF(str.c_str()) : 0; -} - -#endif - -} diff --git a/WebKit/android/jni/WebCoreJni.h b/WebKit/android/jni/WebCoreJni.h deleted file mode 100644 index ec25c8f..0000000 --- a/WebKit/android/jni/WebCoreJni.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2008, 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 ANDROID_WEBKIT_WEBCOREJNI_H -#define ANDROID_WEBKIT_WEBCOREJNI_H - -#include "ChromiumIncludes.h" -#include "PlatformString.h" -#include <jni.h> - -namespace android { - -// A helper class that automatically deletes the local reference to the jobject -// returned from getRealObject. -class AutoJObject { -public: - AutoJObject(const AutoJObject& other) - : m_env(other.m_env) - , m_obj(other.m_obj ? other.m_env->NewLocalRef(other.m_obj) : NULL) {} - ~AutoJObject() { - if (m_obj) - m_env->DeleteLocalRef(m_obj); - } - jobject get() const { - return m_obj; - } - // Releases the local reference to the caller. The caller *must* delete the - // local reference when it is done with it. - jobject release() { - jobject obj = m_obj; - m_obj = 0; - return obj; - } - JNIEnv* env() const { - return m_env; - } -private: - AutoJObject(); // Not permitted. - AutoJObject(JNIEnv* env, jobject obj) - : m_env(env) - , m_obj(obj) {} - JNIEnv* m_env; - jobject m_obj; - friend AutoJObject getRealObject(JNIEnv*, jobject); -}; - -// Get the real object stored in the weak reference returned as an -// AutoJObject. -AutoJObject getRealObject(JNIEnv*, jobject); - -// Helper method for check java exceptions. Returns true if an exception -// occurred and logs the exception. -bool checkException(JNIEnv* env); - -// Create a WTF::String object from a jstring object. -WTF::String jstringToWtfString(JNIEnv*, jstring); -// Returns a local reference to a new jstring. If validOnZeroLength is true then -// passing in an empty WTF String will result in an empty jstring. Otherwise -// an empty WTF String returns 0. -jstring wtfStringToJstring(JNIEnv*, const WTF::String&, bool validOnZeroLength = false); - -#if USE(CHROME_NETWORK_STACK) -string16 jstringToString16(JNIEnv*, jstring); - -std::string jstringToStdString(JNIEnv*, jstring); -// Returns a local reference to a new jstring. If validOnZeroLength is true then -// passing in an empty std::string will result in an empty jstring. Otherwise -// an empty std::string returns 0. -jstring stdStringToJstring(JNIEnv*, const std::string&, bool validOnZeroLength = false); -#endif - -} - -#endif diff --git a/WebKit/android/jni/WebCoreJniOnLoad.cpp b/WebKit/android/jni/WebCoreJniOnLoad.cpp deleted file mode 100644 index 1f264a2..0000000 --- a/WebKit/android/jni/WebCoreJniOnLoad.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "webcoreglue" - -#include "config.h" - -#include "BackForwardList.h" -#include "ChromeClientAndroid.h" -#include "ContextMenuClientAndroid.h" -#include "CookieClient.h" -#include "DeviceMotionClientAndroid.h" -#include "DeviceOrientationClientAndroid.h" -#include "DragClientAndroid.h" -#include "EditorClientAndroid.h" -#include "FocusController.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HistoryItem.h" -#include "InspectorClientAndroid.h" -#include "IntRect.h" -#include "JavaSharedClient.h" -#include "Page.h" -#include "PlatformGraphicsContext.h" -#include "ResourceRequest.h" -#include "ScriptController.h" -#include "SecurityOrigin.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SharedBuffer.h" -#include "SkBitmap.h" -#include "SkCanvas.h" -#include "SkImageEncoder.h" -#include "SubstituteData.h" -#include "TimerClient.h" -#include "TextEncoding.h" -#include "WebCoreViewBridge.h" -#include "WebFrameView.h" -#include "WebViewCore.h" -#include "benchmark/Intercept.h" -#include "benchmark/MyJavaVM.h" - -#include <JNIUtility.h> -#include <jni.h> -#include <utils/Log.h> - -#define EXPORT __attribute__((visibility("default"))) - -namespace android { - -extern int registerWebFrame(JNIEnv*); -extern int registerJavaBridge(JNIEnv*); -extern int registerJniUtil(JNIEnv*); -extern int registerResourceLoader(JNIEnv*); -extern int registerWebViewCore(JNIEnv*); -extern int registerWebHistory(JNIEnv*); -extern int registerWebIconDatabase(JNIEnv*); -extern int registerWebSettings(JNIEnv*); -extern int registerWebView(JNIEnv*); -#if ENABLE(DATABASE) -extern int registerWebStorage(JNIEnv*); -#endif -extern int registerGeolocationPermissions(JNIEnv*); -extern int registerMockGeolocation(JNIEnv*); -#if ENABLE(VIDEO) -extern int registerMediaPlayerAudio(JNIEnv*); -extern int registerMediaPlayerVideo(JNIEnv*); -#endif -extern int registerDeviceMotionAndOrientationManager(JNIEnv*); -extern int registerCookieManager(JNIEnv*); -#if USE(CHROME_NETWORK_STACK) -extern int registerCacheManager(JNIEnv*); -#endif - -} - -struct RegistrationMethod { - const char* name; - int (*func)(JNIEnv*); -}; - -static RegistrationMethod gWebCoreRegMethods[] = { - { "JavaBridge", android::registerJavaBridge }, - { "JniUtil", android::registerJniUtil }, - { "WebFrame", android::registerWebFrame }, - { "WebCoreResourceLoader", android::registerResourceLoader }, - { "WebViewCore", android::registerWebViewCore }, - { "WebHistory", android::registerWebHistory }, - { "WebIconDatabase", android::registerWebIconDatabase }, - { "WebSettings", android::registerWebSettings }, -#if ENABLE(DATABASE) - { "WebStorage", android::registerWebStorage }, -#endif - { "WebView", android::registerWebView }, - { "GeolocationPermissions", android::registerGeolocationPermissions }, - { "MockGeolocation", android::registerMockGeolocation }, -#if ENABLE(VIDEO) - { "HTML5Audio", android::registerMediaPlayerAudio }, - { "HTML5VideoViewProxy", android::registerMediaPlayerVideo }, -#endif - { "DeviceMotionAndOrientationManager", android::registerDeviceMotionAndOrientationManager }, - { "CookieManager", android::registerCookieManager }, -#if USE(CHROME_NETWORK_STACK) - { "CacheManager", android::registerCacheManager }, -#endif -}; - -EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - // Save the JavaVM pointer for use globally. - JSC::Bindings::setJavaVM(vm); - - JNIEnv* env = NULL; - jint result = -1; - - if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { - LOGE("GetEnv failed!"); - return result; - } - LOG_ASSERT(env, "Could not retrieve the env!"); - - const RegistrationMethod* method = gWebCoreRegMethods; - const RegistrationMethod* end = method + sizeof(gWebCoreRegMethods)/sizeof(RegistrationMethod); - while (method != end) { - if (method->func(env) < 0) { - LOGE("%s registration failed!", method->name); - return result; - } - method++; - } - - // Initialize rand() function. The rand() function is used in - // FileSystemAndroid to create a random temporary filename. - srand(time(NULL)); - - return JNI_VERSION_1_4; -} - -class MyJavaSharedClient : public TimerClient, public CookieClient { -public: - MyJavaSharedClient() : m_hasTimer(false) {} - virtual void setSharedTimer(long long timemillis) { m_hasTimer = true; } - virtual void stopSharedTimer() { m_hasTimer = false; } - virtual void setSharedTimerCallback(void (*f)()) { m_func = f; } - virtual void signalServiceFuncPtrQueue() {} - - // Cookie methods that do nothing. - virtual void setCookies(const KURL&, const String&) {} - virtual String cookies(const KURL&) { return ""; } - virtual bool cookiesEnabled() { return false; } - - bool m_hasTimer; - void (*m_func)(); -}; - -static void historyItemChanged(HistoryItem* i) { - if (i->bridge()) - i->bridge()->updateHistoryItem(i); -} - -namespace android { - -EXPORT void benchmark(const char* url, int reloadCount, int width, int height) { - ScriptController::initializeThreading(); - - // Setting this allows data: urls to load from a local file. - SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll); - - // Create the fake JNIEnv and JavaVM - InitializeJavaVM(); - - // The real function is private to libwebcore but we know what it does. - notifyHistoryItemChanged = historyItemChanged; - - // Implement the shared timer callback - MyJavaSharedClient client; - JavaSharedClient::SetTimerClient(&client); - JavaSharedClient::SetCookieClient(&client); - - // Create the page with all the various clients - ChromeClientAndroid* chrome = new ChromeClientAndroid; - EditorClientAndroid* editor = new EditorClientAndroid; - DeviceMotionClientAndroid* deviceMotion = new DeviceMotionClientAndroid; - DeviceOrientationClientAndroid* deviceOrientation = new DeviceOrientationClientAndroid; - WebCore::Page::PageClients pageClients; - pageClients.chromeClient = chrome; - pageClients.contextMenuClient = new ContextMenuClientAndroid; - pageClients.editorClient = editor; - pageClients.dragClient = new DragClientAndroid; - pageClients.inspectorClient = new InspectorClientAndroid; - pageClients.deviceMotionClient = deviceMotion; - pageClients.deviceOrientationClient = deviceOrientation; - WebCore::Page* page = new WebCore::Page(pageClients); - editor->setPage(page); - - // Create MyWebFrame that intercepts network requests - MyWebFrame* webFrame = new MyWebFrame(page); - webFrame->setUserAgent("Performance testing"); // needs to be non-empty - chrome->setWebFrame(webFrame); - // ChromeClientAndroid maintains the reference. - Release(webFrame); - - // Create the Frame and the FrameLoaderClient - FrameLoaderClientAndroid* loader = new FrameLoaderClientAndroid(webFrame); - RefPtr<Frame> frame = Frame::create(page, NULL, loader); - loader->setFrame(frame.get()); - - // Build our View system, resize it to the given dimensions and release our - // references. Note: We keep a referenec to frameView so we can layout and - // draw later without risk of it being deleted. - WebViewCore* webViewCore = new WebViewCore(JSC::Bindings::getJNIEnv(), - MY_JOBJECT, frame.get()); - RefPtr<FrameView> frameView = FrameView::create(frame.get()); - WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore); - frame->setView(frameView); - frameView->resize(width, height); - Release(webViewCore); - Release(webFrameView); - - // Initialize the frame and turn of low-bandwidth display (it fails an - // assertion in the Cache code) - frame->init(); - frame->selection()->setFocused(true); - frame->page()->focusController()->setFocused(true); - - deviceMotion->setWebViewCore(webViewCore); - deviceOrientation->setWebViewCore(webViewCore); - - // Set all the default settings the Browser normally uses. - Settings* s = frame->settings(); -#ifdef ANDROID_LAYOUT - s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now -#endif - s->setStandardFontFamily("sans-serif"); - s->setFixedFontFamily("monospace"); - s->setSansSerifFontFamily("sans-serif"); - s->setSerifFontFamily("serif"); - s->setCursiveFontFamily("cursive"); - s->setFantasyFontFamily("fantasy"); - s->setMinimumFontSize(8); - s->setMinimumLogicalFontSize(8); - s->setDefaultFontSize(16); - s->setDefaultFixedFontSize(13); - s->setLoadsImagesAutomatically(true); - s->setJavaScriptEnabled(true); - s->setDefaultTextEncodingName("latin1"); - s->setPluginsEnabled(false); - s->setShrinksStandaloneImagesToFit(false); -#ifdef ANDROID_LAYOUT - s->setUseWideViewport(false); -#endif - - // Finally, load the actual data - ResourceRequest req(url); - frame->loader()->load(req, false); - - do { - // Layout the page and service the timer - frame->view()->layout(); - while (client.m_hasTimer) { - client.m_func(); - JavaSharedClient::ServiceFunctionPtrQueue(); - } - JavaSharedClient::ServiceFunctionPtrQueue(); - - // Layout more if needed. - while (frame->view()->needsLayout()) - frame->view()->layout(); - JavaSharedClient::ServiceFunctionPtrQueue(); - - if (reloadCount) - frame->loader()->reload(true); - } while (reloadCount--); - - // Draw into an offscreen bitmap - SkBitmap bmp; - bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height); - bmp.allocPixels(); - SkCanvas canvas(bmp); - PlatformGraphicsContext ctx(&canvas, NULL); - GraphicsContext gc(&ctx); - frame->view()->paintContents(&gc, IntRect(0, 0, width, height)); - - // Write the bitmap to the sdcard - SkImageEncoder* enc = SkImageEncoder::Create(SkImageEncoder::kPNG_Type); - enc->encodeFile("/sdcard/webcore_test.png", bmp, 100); - delete enc; - - // Tear down the world. - frame->loader()->detachFromParent(); - delete page; -} - -} // namespace android diff --git a/WebKit/android/jni/WebCoreRefObject.h b/WebKit/android/jni/WebCoreRefObject.h deleted file mode 100644 index 4228db6..0000000 --- a/WebKit/android/jni/WebCoreRefObject.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2007, 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 WEBCORE_FOUNDATION_h -#define WEBCORE_FOUNDATION_h - -#include "SkRefCnt.h" - -typedef SkRefCnt WebCoreRefObject; - -static inline WebCoreRefObject* Retain(WebCoreRefObject* obj) -{ - if (obj) - obj->ref(); - return obj; -} - -static inline void Release(WebCoreRefObject* obj) -{ - if (obj) - obj->unref(); -} - -#endif // WEBCORE_FOUNDATION_h diff --git a/WebKit/android/jni/WebCoreResourceLoader.cpp b/WebKit/android/jni/WebCoreResourceLoader.cpp deleted file mode 100644 index f9acc97..0000000 --- a/WebKit/android/jni/WebCoreResourceLoader.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2006, 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 "webcoreglue" - -#include "config.h" -#include "WebCoreResourceLoader.h" - -#include "ResourceError.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceHandleInternal.h" -#include "ResourceResponse.h" -#include "SkUtils.h" -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif -#include "WebCoreJni.h" - -#include <JNIHelp.h> -#include <JNIUtility.h> -#include <SkTypes.h> -#include <stdlib.h> -#include <utils/misc.h> -#include <wtf/Platform.h> -#include <wtf/text/CString.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -static struct resourceloader_t { - jfieldID mObject; - jmethodID mCancelMethodID; - jmethodID mDownloadFileMethodID; - jmethodID mWillLoadFromCacheMethodID; - jmethodID mPauseLoadMethodID; -} gResourceLoader; - -// ---------------------------------------------------------------------------- - -#define GET_NATIVE_HANDLE(env, obj) ((WebCore::ResourceHandle*)env->GetIntField(obj, gResourceLoader.mObject)) -#define SET_NATIVE_HANDLE(env, obj, handle) (env->SetIntField(obj, gResourceLoader.mObject, handle)) - -//----------------------------------------------------------------------------- -// ResourceLoadHandler - -PassRefPtr<WebCore::ResourceLoaderAndroid> WebCoreResourceLoader::create(JNIEnv *env, jobject jLoadListener) -{ - return adoptRef<WebCore::ResourceLoaderAndroid>(new WebCoreResourceLoader(env, jLoadListener)); -} - -WebCoreResourceLoader::WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener) - : mPausedLoad(false) -{ - mJLoader = env->NewGlobalRef(jLoadListener); -} - -WebCoreResourceLoader::~WebCoreResourceLoader() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - SET_NATIVE_HANDLE(env, mJLoader, 0); - env->DeleteGlobalRef(mJLoader); - mJLoader = 0; -} - -void WebCoreResourceLoader::cancel() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(mJLoader, gResourceLoader.mCancelMethodID); - checkException(env); -} - -void WebCoreResourceLoader::downloadFile() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(mJLoader, gResourceLoader.mDownloadFileMethodID); - checkException(env); -} - -void WebCoreResourceLoader::pauseLoad(bool pause) -{ - if (mPausedLoad == pause) - return; - - mPausedLoad = pause; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(mJLoader, gResourceLoader.mPauseLoadMethodID, pause); - checkException(env); -} - -/* -* This static method is called to check to see if a POST response is in -* the cache. This may be slow, but is only used during a navigation to -* a POST response. -*/ -bool WebCoreResourceLoader::willLoadFromCache(const WebCore::KURL& url, int64_t identifier) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - WTF::String urlStr = url.string(); - jstring jUrlStr = wtfStringToJstring(env, urlStr); - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - bool val = env->CallStaticBooleanMethod(resourceLoader, gResourceLoader.mWillLoadFromCacheMethodID, jUrlStr, identifier); - checkException(env); - env->DeleteLocalRef(resourceLoader); - env->DeleteLocalRef(jUrlStr); - - return val; -} - -// ---------------------------------------------------------------------------- -void WebCoreResourceLoader::SetResponseHeader(JNIEnv* env, jobject obj, jint nativeResponse, jstring key, jstring val) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeSetResponseHeader must take a valid response pointer!"); - - LOG_ASSERT(key, "How did a null value become a key?"); - if (val) - response->setHTTPHeaderField(jstringToWtfString(env, key), jstringToWtfString(env, val)); -} - -jint WebCoreResourceLoader::CreateResponse(JNIEnv* env, jobject obj, jstring url, jint statusCode, - jstring statusText, jstring mimeType, jlong expectedLength, - jstring encoding) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - LOG_ASSERT(url, "Must have a url in the response!"); - WebCore::KURL kurl(WebCore::ParsedURLString, jstringToWtfString(env, url)); - WTF::String encodingStr; - WTF::String mimeTypeStr; - if (mimeType) { - mimeTypeStr = jstringToWtfString(env, mimeType); - LOGV("Response setMIMEType: %s", mimeTypeStr.latin1().data()); - } - if (encoding) { - encodingStr = jstringToWtfString(env, encoding); - LOGV("Response setTextEncodingName: %s", encodingStr.latin1().data()); - } - WebCore::ResourceResponse* response = new WebCore::ResourceResponse( - kurl, mimeTypeStr, (long long)expectedLength, - encodingStr, WTF::String()); - response->setHTTPStatusCode(statusCode); - if (statusText) { - WTF::String status = jstringToWtfString(env, statusText); - response->setHTTPStatusText(status); - LOGV("Response setStatusText: %s", status.latin1().data()); - } - return (int)response; -} - -void WebCoreResourceLoader::ReceivedResponse(JNIEnv* env, jobject obj, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeReceivedResponse must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - LOG_ASSERT(response, "nativeReceivedResponse must take a valid resource pointer!"); - handle->client()->didReceiveResponse(handle, *response); - // As the client makes a copy of the response, delete it here. - delete response; -} - -void WebCoreResourceLoader::AddData(JNIEnv* env, jobject obj, jbyteArray dataArray, jint length) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - LOGV("webcore_resourceloader data(%d)", length); - - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeAddData must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - SkAutoMemoryUsageProbe mup("android_webcore_resourceloader_nativeAddData"); - - bool result = false; - jbyte * data = env->GetByteArrayElements(dataArray, NULL); - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didReceiveData(handle, (const char *)data, length, length); - env->ReleaseByteArrayElements(dataArray, data, JNI_ABORT); -} - -void WebCoreResourceLoader::Finished(JNIEnv* env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - LOGV("webcore_resourceloader finished"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeFinished must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - handle->client()->didFinishLoading(handle, 0); -} - -jstring WebCoreResourceLoader::RedirectedToUrl(JNIEnv* env, jobject obj, - jstring baseUrl, jstring redirectTo, jint nativeResponse) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - LOGV("webcore_resourceloader redirectedToUrl"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeRedirectedToUrl must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return NULL; - - LOG_ASSERT(handle->client(), "Why do we not have a client?"); - WebCore::ResourceRequest r = handle->firstRequest(); - WebCore::KURL url(WebCore::KURL(WebCore::ParsedURLString, jstringToWtfString(env, baseUrl)), - jstringToWtfString(env, redirectTo)); - WebCore::ResourceResponse* response = (WebCore::ResourceResponse*)nativeResponse; - // If the url fails to resolve the relative path, return null. - if (url.protocol().isEmpty()) { - delete response; - return NULL; - } else { - // Ensure the protocol is lowercase. - url.setProtocol(url.protocol().lower()); - } - // Set the url after updating the protocol. - r.setURL(url); - if (r.httpMethod() == "POST") { - r.setHTTPMethod("GET"); - r.clearHTTPReferrer(); - r.setHTTPBody(0); - r.setHTTPContentType(""); - } - handle->client()->willSendRequest(handle, r, *response); - delete response; - return wtfStringToJstring(env, url.string()); -} - -void WebCoreResourceLoader::Error(JNIEnv* env, jobject obj, jint id, jstring description, - jstring failingUrl) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::ResourceTimeCounter); -#endif - LOGV("webcore_resourceloader error"); - WebCore::ResourceHandle* handle = GET_NATIVE_HANDLE(env, obj); - LOG_ASSERT(handle, "nativeError must take a valid handle!"); - // ResourceLoader::didFail() can set handle to be NULL, we need to check - if (!handle) - return; - - handle->client()->didFail(handle, WebCore::ResourceError("", id, - jstringToWtfString(env, failingUrl), jstringToWtfString(env, description))); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gResourceloaderMethods[] = { - /* name, signature, funcPtr */ - { "nativeSetResponseHeader", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::SetResponseHeader }, - { "nativeCreateResponse", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;JLjava/lang/String;)I", - (void*) WebCoreResourceLoader::CreateResponse }, - { "nativeReceivedResponse", "(I)V", - (void*) WebCoreResourceLoader::ReceivedResponse }, - { "nativeAddData", "([BI)V", - (void*) WebCoreResourceLoader::AddData }, - { "nativeFinished", "()V", - (void*) WebCoreResourceLoader::Finished }, - { "nativeRedirectedToUrl", "(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;", - (void*) WebCoreResourceLoader::RedirectedToUrl }, - { "nativeError", "(ILjava/lang/String;Ljava/lang/String;)V", - (void*) WebCoreResourceLoader::Error } -}; - -int registerResourceLoader(JNIEnv* env) -{ - jclass resourceLoader = env->FindClass("android/webkit/LoadListener"); - LOG_FATAL_IF(resourceLoader == NULL, - "Unable to find class android/webkit/LoadListener"); - - gResourceLoader.mObject = - env->GetFieldID(resourceLoader, "mNativeLoader", "I"); - LOG_FATAL_IF(gResourceLoader.mObject == NULL, - "Unable to find android/webkit/LoadListener.mNativeLoader"); - - gResourceLoader.mCancelMethodID = - env->GetMethodID(resourceLoader, "cancel", "()V"); - LOG_FATAL_IF(gResourceLoader.mCancelMethodID == NULL, - "Could not find method cancel on LoadListener"); - - gResourceLoader.mDownloadFileMethodID = - env->GetMethodID(resourceLoader, "downloadFile", "()V"); - LOG_FATAL_IF(gResourceLoader.mDownloadFileMethodID == NULL, - "Could not find method downloadFile on LoadListener"); - - gResourceLoader.mPauseLoadMethodID = - env->GetMethodID(resourceLoader, "pauseLoad", "(Z)V"); - LOG_FATAL_IF(gResourceLoader.mPauseLoadMethodID == NULL, - "Could not find method pauseLoad on LoadListener"); - - gResourceLoader.mWillLoadFromCacheMethodID = - env->GetStaticMethodID(resourceLoader, "willLoadFromCache", "(Ljava/lang/String;J)Z"); - LOG_FATAL_IF(gResourceLoader.mWillLoadFromCacheMethodID == NULL, - "Could not find static method willLoadFromCache on LoadListener"); - - env->DeleteLocalRef(resourceLoader); - - return jniRegisterNativeMethods(env, "android/webkit/LoadListener", - gResourceloaderMethods, NELEM(gResourceloaderMethods)); -} - -} /* namespace android */ diff --git a/WebKit/android/jni/WebCoreResourceLoader.h b/WebKit/android/jni/WebCoreResourceLoader.h deleted file mode 100644 index c60b3f5..0000000 --- a/WebKit/android/jni/WebCoreResourceLoader.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2006, 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 ANDROID_WEBKIT_RESOURCELOADLISTENER_H -#define ANDROID_WEBKIT_RESOURCELOADLISTENER_H - -#include <KURL.h> -#include <ResourceLoaderAndroid.h> -#include <jni.h> - -namespace android { - -class WebCoreResourceLoader : public WebCore::ResourceLoaderAndroid -{ -public: - static PassRefPtr<WebCore::ResourceLoaderAndroid> create(JNIEnv *env, jobject jLoadListener); - virtual ~WebCoreResourceLoader(); - - /** - * Call to java to cancel the current load. - */ - virtual void cancel(); - - /** - * Call to java to download the current load rather than feed it - * back to WebCore - */ - virtual void downloadFile(); - - virtual void pauseLoad(bool); - - /** - * Call to java to find out if this URL is in the cache - */ - static bool willLoadFromCache(const WebCore::KURL& url, int64_t identifier); - - // Native jni functions - static void SetResponseHeader(JNIEnv*, jobject, jint, jstring, jstring); - static jint CreateResponse(JNIEnv*, jobject, jstring, jint, jstring, - jstring, jlong, jstring); - static void ReceivedResponse(JNIEnv*, jobject, jint); - static void AddData(JNIEnv*, jobject, jbyteArray, jint); - static void Finished(JNIEnv*, jobject); - static jstring RedirectedToUrl(JNIEnv*, jobject, jstring, jstring, jint); - static void Error(JNIEnv*, jobject, jint, jstring, jstring); - -protected: - WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener); -private: - jobject mJLoader; - bool mPausedLoad; -}; - -} // end namespace android - -#endif diff --git a/WebKit/android/jni/WebCoreViewBridge.h b/WebKit/android/jni/WebCoreViewBridge.h deleted file mode 100644 index 59e1c9a..0000000 --- a/WebKit/android/jni/WebCoreViewBridge.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2007, 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 WEBCORE_VIEW_BRIDGE_H -#define WEBCORE_VIEW_BRIDGE_H - -// TODO: move this outside of jni directory - -#include "IntRect.h" -#include "WebCoreRefObject.h" - -namespace WebCore -{ - class GraphicsContext; -} - -class WebCoreViewBridge : public WebCoreRefObject { -public: - WebCoreViewBridge() { } - virtual ~WebCoreViewBridge() { } - - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect) = 0; - - const WebCore::IntRect& getBounds() const - { - return m_bounds; - } - - const WebCore::IntRect& getVisibleBounds() const - { - return m_visibleBounds; - } - - const WebCore::IntRect& getWindowBounds() const - { - return m_windowBounds; - } - - void setSize(int w, int h) - { - m_bounds.setWidth(w); - m_bounds.setHeight(h); - } - - void setVisibleSize(int w, int h) - { - m_visibleBounds.setWidth(w); - m_visibleBounds.setHeight(h); - } - - void setLocation(int x, int y) - { - m_bounds.setX(x); - m_bounds.setY(y); - m_visibleBounds.setX(x); - m_visibleBounds.setY(y); - } - - void setWindowBounds(int x, int y, int h, int v) - { - m_windowBounds = WebCore::IntRect(x, y, h, v); - } - - int width() const { return m_bounds.width(); } - int height() const { return m_bounds.height(); } - int locX() const { return m_bounds.x(); } - int locY() const { return m_bounds.y(); } - - int visibleWidth() const { return m_visibleBounds.width(); } - int visibleHeight() const { return m_visibleBounds.height(); } - int visibleX() const { return m_visibleBounds.x(); } - int visibleY() const { return m_visibleBounds.y(); } - - virtual bool forFrameView() const { return false; } - virtual bool forPluginView() const { return false; } - -private: - WebCore::IntRect m_bounds; - WebCore::IntRect m_windowBounds; - WebCore::IntRect m_visibleBounds; -}; - -#endif // WEBCORE_VIEW_BRIDGE_H diff --git a/WebKit/android/jni/WebFrameView.cpp b/WebKit/android/jni/WebFrameView.cpp deleted file mode 100644 index 8e5eac4..0000000 --- a/WebKit/android/jni/WebFrameView.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2008, 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 "webcoreglue" - -#include <config.h> -#include "WebFrameView.h" - -#include "android_graphics.h" -#include "GraphicsContext.h" -#include "Frame.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "HostWindow.h" -#include "PlatformGraphicsContext.h" -#include "WebViewCore.h" - -#include <SkCanvas.h> - -namespace android { - -WebFrameView::WebFrameView(WebCore::FrameView* frameView, WebViewCore* webViewCore) - : WebCoreViewBridge() - , mFrameView(frameView) - , mWebViewCore(webViewCore) { - // attach itself to mFrameView - mFrameView->setPlatformWidget(this); - Retain(mWebViewCore); -} - -WebFrameView::~WebFrameView() { - Release(mWebViewCore); -} - -void WebFrameView::draw(WebCore::GraphicsContext* ctx, const WebCore::IntRect& rect) { - WebCore::Frame* frame = mFrameView->frame(); - - if (NULL == frame->contentRenderer()) { - // We only do this if there is nothing else to draw. - // If there is a renderer, it will fill the bg itself, so we don't want to - // double-draw (slow) - SkCanvas* canvas = ctx->platformContext()->mCanvas; - canvas->drawColor(SK_ColorWHITE); - } else if (frame->tree()->parent()) { - // Note: this code was moved from FrameLoaderClientAndroid - // - // For subframe, create a new translated rect from the given rectangle. - WebCore::IntRect transRect(rect); - // In Frame::markAllMatchesForText(), it does a fake paint. So we need - // to handle the case where platformContext() is null. However, we still - // want to call paint, since WebKit must have called the paint for a reason. - SkCanvas* canvas = ctx->platformContext() ? ctx->platformContext()->mCanvas : NULL; - if (canvas) { - const WebCore::IntRect& bounds = getBounds(); - - // Grab the intersection of transRect and the frame's bounds. - transRect.intersect(bounds); - if (transRect.isEmpty()) - return; - - // Move the transRect into the frame's local coordinates. - transRect.move(-bounds.x(), -bounds.y()); - - // Translate the canvas, add a clip. - canvas->save(); - canvas->translate(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y())); - canvas->clipRect(transRect); - } - mFrameView->paintContents(ctx, transRect); - if (canvas) - canvas->restore(); - } else { - mFrameView->paintContents(ctx, rect); - } -} - -void WebFrameView::setView(WebCore::FrameView* frameView) { - mFrameView = frameView; - mFrameView->setPlatformWidget(this); -} - -} // namespace android diff --git a/WebKit/android/jni/WebFrameView.h b/WebKit/android/jni/WebFrameView.h deleted file mode 100644 index 823f2b4..0000000 --- a/WebKit/android/jni/WebFrameView.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2008, 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 WEB_FRAMEVIEW_H -#define WEB_FRAMEVIEW_H - -#include "WebCoreViewBridge.h" - -namespace WebCore { - class FrameView; -} - -namespace android { - class WebViewCore; - - class WebFrameView: public WebCoreViewBridge { - public: - WebFrameView(WebCore::FrameView* frameView, WebViewCore* webViewCore); - virtual ~WebFrameView(); - - virtual void draw(WebCore::GraphicsContext* ctx, - const WebCore::IntRect& rect); - - WebViewCore* webViewCore() const { - return mWebViewCore; - } - - void setView(WebCore::FrameView* frameView); - - WebCore::FrameView* view() const { - return mFrameView; - } - - virtual bool forFrameView() const { return true; } - - private: - WebCore::FrameView* mFrameView; - WebViewCore* mWebViewCore; - }; - -} // namespace android - -#endif // WEB_FRAMEVIEW_H diff --git a/WebKit/android/jni/WebHistory.cpp b/WebKit/android/jni/WebHistory.cpp deleted file mode 100644 index 97ce23b..0000000 --- a/WebKit/android/jni/WebHistory.cpp +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Copyright 2007, 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 "webhistory" - -#include "config.h" -#include "WebHistory.h" - -#include "BackForwardList.h" -#include "BackForwardListImpl.h" -#include "DocumentLoader.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "HistoryItem.h" -#include "IconDatabase.h" -#include "Page.h" -#include "TextEncoding.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreJni.h" -#include "WebIconDatabase.h" - -#include <JNIHelp.h> -#include "JNIUtility.h" -#include <SkUtils.h> -#include <utils/misc.h> -#include <wtf/OwnPtr.h> -#include <wtf/Platform.h> -#include <wtf/text/CString.h> - -namespace android { - -// Forward declarations -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item); -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent); -static bool read_item_recursive(WebCore::HistoryItem* child, const char** pData, int length); - -// Field ids for WebHistoryItems -struct WebHistoryItemFields { - jmethodID mInit; - jmethodID mUpdate; - jfieldID mTitle; - jfieldID mUrl; -} gWebHistoryItem; - -struct WebBackForwardListFields { - jmethodID mAddHistoryItem; - jmethodID mRemoveHistoryItem; - jmethodID mSetCurrentIndex; -} gWebBackForwardList; - -//-------------------------------------------------------------------------- -// WebBackForwardList native methods. -//-------------------------------------------------------------------------- - -static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) -{ - LOG_ASSERT(frame, "Close needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - - WebCore::BackForwardListImpl* list = static_cast<WebCore::BackForwardListImpl*>(pFrame->page()->backForwardList()); - RefPtr<WebCore::HistoryItem> current = list->currentItem(); - // Remove each item instead of using close(). close() is intended to be used - // right before the list is deleted. - WebCore::HistoryItemVector& entries = list->entries(); - int size = entries.size(); - for (int i = size - 1; i >= 0; --i) - list->removeItem(entries[i].get()); - // Add the current item back to the list. - if (current) { - current->setBridge(0); - // addItem will update the children to match the newly created bridge - list->addItem(current); - - /* - * The Grand Prix site uses anchor navigations to change the display. - * WebKit tries to be smart and not load child frames that have the - * same history urls during an anchor navigation. This means that the - * current history item stored in the child frame's loader does not - * match the item found in the history tree. If we remove all the - * entries in the back/foward list, we have to restore the entire tree - * or else a HistoryItem might have a deleted parent. - * - * In order to restore the history tree correctly, we have to look up - * all the frames first and then look up the history item. We do this - * because the history item in the tree may be null at this point. - * Unfortunately, a HistoryItem can only search its immediately - * children so we do a breadth-first rebuild of the tree. - */ - - // Keep a small list of child frames to traverse. - WTF::Vector<WebCore::Frame*> frameQueue; - // Fix the top-level item. - pFrame->loader()->history()->setCurrentItem(current.get()); - WebCore::Frame* child = pFrame->tree()->firstChild(); - // Remember the parent history item so we can search for a child item. - RefPtr<WebCore::HistoryItem> parent = current; - while (child) { - // Use the old history item since the current one may have a - // deleted parent. - WebCore::HistoryItem* item = parent->childItemWithTarget(child->tree()->name()); - child->loader()->history()->setCurrentItem(item); - // Append the first child to the queue if it exists. If there is no - // item, then we do not need to traverse the children since there - // will be no parent history item. - WebCore::Frame* firstChild; - if (item && (firstChild = child->tree()->firstChild())) - frameQueue.append(firstChild); - child = child->tree()->nextSibling(); - // If we don't have a sibling for this frame and the queue isn't - // empty, use the next entry in the queue. - if (!child && !frameQueue.isEmpty()) { - child = frameQueue.at(0); - frameQueue.remove(0); - // Figure out the parent history item used when searching for - // the history item to use. - parent = child->tree()->parent()->loader()->history()->currentItem(); - } - } - } -} - -static void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint index) -{ - LOG_ASSERT(frame, "RestoreState needs a valid Frame pointer!"); - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - WebCore::Page* page = pFrame->page(); - WebCore::HistoryItem* currentItem = - static_cast<WebCore::BackForwardListImpl*>(page->backForwardList())->entries()[index].get(); - - // load the current page with FrameLoadTypeIndexedBackForward so that it - // will use cache when it is possible - page->goToItem(currentItem, FrameLoadTypeIndexedBackForward); -} - -static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray data) -{ - LOG_ASSERT(frame, "Inflate needs a valid frame pointer!"); - LOG_ASSERT(data, "Inflate needs a valid data pointer!"); - - // Get the actual bytes and the length from the java array. - const jbyte* bytes = env->GetByteArrayElements(data, NULL); - jsize size = env->GetArrayLength(data); - - // Inflate the history tree into one HistoryItem or null if the inflation - // failed. - RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create(); - WebHistoryItem* bridge = new WebHistoryItem(env, obj, newItem.get()); - newItem->setBridge(bridge); - - // Inflate the item recursively. If it fails, that is ok. We'll have an - // incomplete HistoryItem but that is better than crashing due to a null - // item. - // We have a 2nd local variable since read_item_recursive may change the - // ptr's value. We can't pass &bytes since we have to send bytes to - // ReleaseByteArrayElements unchanged. - const char* ptr = reinterpret_cast<const char*>(bytes); - read_item_recursive(newItem.get(), &ptr, (int)size); - env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT); - bridge->setActive(); - - // Add the new item to the back/forward list. - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - pFrame->page()->backForwardList()->addItem(newItem); - - // Update the item. - bridge->updateHistoryItem(newItem.get()); -} - -// 6 empty strings + no document state + children count + 2 scales = 10 unsigned values -// 1 char for isTargetItem. -#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 10 + sizeof(char))) - -jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - if (!item) - return NULL; - - // Reserve a vector of chars with an initial size of HISTORY_MIN_SIZE. - v.reserveCapacity(HISTORY_MIN_SIZE); - - // Write the top-level history item and then write all the children - // recursively. - LOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?"); - write_item(v, item); - write_children_recursive(v, item); - - // Try to create a new java byte array. - jbyteArray b = env->NewByteArray(v.size()); - if (!b) - return NULL; - - // Write our flattened data to the java array. - env->SetByteArrayRegion(b, 0, v.size(), (const jbyte*)v.data()); - return b; -} - -WebHistoryItem::WebHistoryItem(JNIEnv* env, jobject obj, - WebCore::HistoryItem* item) : WebCore::AndroidWebHistoryBridge(item) { - m_object = env->NewWeakGlobalRef(obj); - m_parent = 0; -} - -WebHistoryItem::~WebHistoryItem() { - if (m_object) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - env->DeleteWeakGlobalRef(m_object); - } -} - -void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { - // Do not want to update during inflation. - if (!m_active) - return; - WebHistoryItem* webItem = this; - // Now we need to update the top-most WebHistoryItem based on the top-most - // HistoryItem. - if (m_parent) { - webItem = m_parent.get(); - if (webItem->hasOneRef()) { - // if the parent only has one ref, it is from this WebHistoryItem. - // This means that the matching WebCore::HistoryItem has been freed. - // This can happen during clear(). - LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); - return; - } - while (webItem->parent()) - webItem = webItem->parent(); - item = webItem->historyItem(); - if (!item) { - // If a HistoryItem only exists for page cache, it is possible that - // the parent HistoryItem destroyed before the child HistoryItem. If - // it happens, skip updating. - LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); - return; - } - } - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - - // Don't do anything if the item has been gc'd already - AutoJObject realItem = getRealObject(env, webItem->m_object); - if (!realItem.get()) - return; - - const WTF::String& urlString = item->urlString(); - jstring urlStr = NULL; - if (!urlString.isNull()) - urlStr = wtfStringToJstring(env, urlString); - const WTF::String& originalUrlString = item->originalURLString(); - jstring originalUrlStr = NULL; - if (!originalUrlString.isNull()) - originalUrlStr = wtfStringToJstring(env, originalUrlString); - const WTF::String& titleString = item->title(); - jstring titleStr = NULL; - if (!titleString.isNull()) - titleStr = wtfStringToJstring(env, titleString); - - // Try to get the favicon from the history item. For some pages like Grand - // Prix, there are history items with anchors. If the icon fails for the - // item, try to get the icon using the url without the ref. - jobject favicon = NULL; - WTF::String url = item->urlString(); - if (item->url().hasFragmentIdentifier()) { - int refIndex = url.reverseFind('#'); - url = url.substring(0, refIndex); - } - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, - WebCore::IntSize(16, 16)); - - if (icon) - favicon = webcoreImageToJavaBitmap(env, icon); - - WTF::Vector<char> data; - jbyteArray array = WebHistory::Flatten(env, data, item); - env->CallVoidMethod(realItem.get(), gWebHistoryItem.mUpdate, urlStr, - originalUrlStr, titleStr, favicon, array); - env->DeleteLocalRef(urlStr); - env->DeleteLocalRef(originalUrlStr); - env->DeleteLocalRef(titleStr); - if (favicon) - env->DeleteLocalRef(favicon); - env->DeleteLocalRef(array); -} - -static void historyItemChanged(WebCore::HistoryItem* item) { - LOG_ASSERT(item, "historyItemChanged called with a null item"); - - if (item->bridge()) - item->bridge()->updateHistoryItem(item); -} - -void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) -{ - LOG_ASSERT(item, "newItem must take a valid HistoryItem!"); - // Item already added. Should only happen when we are inflating the list. - if (item->bridge() || !list.get()) - return; - - JNIEnv* env = list.env(); - // Allocate a blank WebHistoryItem - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit); - env->DeleteLocalRef(clazz); - - // Create the bridge, make it active, and attach it to the item. - WebHistoryItem* bridge = new WebHistoryItem(env, newItem, item); - bridge->setActive(); - item->setBridge(bridge); - - // Update the history item which will flatten the data and call update on - // the java item. - bridge->updateHistoryItem(item); - - // Add it to the list. - env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem); - - // Delete our local reference. - env->DeleteLocalRef(newItem); -} - -void WebHistory::RemoveItem(const AutoJObject& list, int index) -{ - if (list.get()) - list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mRemoveHistoryItem, index); -} - -void WebHistory::UpdateHistoryIndex(const AutoJObject& list, int newIndex) -{ - if (list.get()) - list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mSetCurrentIndex, newIndex); -} - -static void write_string(WTF::Vector<char>& v, const WTF::String& str) -{ - unsigned strLen = str.length(); - // Only do work if the string has data. - if (strLen) { - // Determine how much to grow the vector. Use the worst case for utf8 to - // avoid reading the string twice. Add sizeof(unsigned) to hold the - // string length in utf8. - unsigned vectorLen = v.size() + sizeof(unsigned); - unsigned length = (strLen << 2) + vectorLen; - // Grow the vector. This will change the value of v.size() but we - // remember the original size above. - v.grow(length); - // Grab the position to write to. - char* data = v.begin() + vectorLen; - // Write the actual string - int l = SkUTF16_ToUTF8(str.characters(), strLen, data); - LOGV("Writing string %d %.*s", l, l, data); - // Go back and write the utf8 length. Subtract sizeof(unsigned) from - // data to get the position to write the length. - memcpy(data - sizeof(unsigned), (char*)&l, sizeof(unsigned)); - // Shrink the internal state of the vector so we match what was - // actually written. - v.shrink(vectorLen + l); - } else - v.append((char*)&strLen, sizeof(unsigned)); -} - -static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item) -{ - // Original url - write_string(v, item->originalURLString()); - - // Url - write_string(v, item->urlString()); - - // Title - write_string(v, item->title()); - - // Form content type - write_string(v, item->formContentType()); - - // Form data - const WebCore::FormData* formData = item->formData(); - if (formData) { - write_string(v, formData->flattenToString()); - // save the identifier as it is not included in the flatten data - int64_t id = formData->identifier(); - v.append((char*)&id, sizeof(int64_t)); - } else - write_string(v, WTF::String()); // Empty constructor does not allocate a buffer. - - // Target - write_string(v, item->target()); - - AndroidWebHistoryBridge* bridge = item->bridge(); - LOG_ASSERT(bridge, "We should have a bridge here!"); - // Screen scale - const float scale = bridge->scale(); - LOGV("Writing scale %f", scale); - v.append((char*)&scale, sizeof(float)); - const float textWrapScale = bridge->textWrapScale(); - LOGV("Writing text wrap scale %f", textWrapScale); - v.append((char*)&textWrapScale, sizeof(float)); - - // Scroll position. - const int scrollX = item->scrollPoint().x(); - v.append((char*)&scrollX, sizeof(int)); - const int scrollY = item->scrollPoint().y(); - v.append((char*)&scrollY, sizeof(int)); - - // Document state - const WTF::Vector<WTF::String>& docState = item->documentState(); - WTF::Vector<WTF::String>::const_iterator end = docState.end(); - unsigned stateSize = docState.size(); - LOGV("Writing docState %d", stateSize); - v.append((char*)&stateSize, sizeof(unsigned)); - for (WTF::Vector<WTF::String>::const_iterator i = docState.begin(); i != end; ++i) { - write_string(v, *i); - } - - // Is target item - LOGV("Writing isTargetItem %d", item->isTargetItem()); - v.append((char)item->isTargetItem()); - - // Children count - unsigned childCount = item->children().size(); - LOGV("Writing childCount %d", childCount); - v.append((char*)&childCount, sizeof(unsigned)); -} - -static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent) -{ - const WebCore::HistoryItemVector& children = parent->children(); - WebCore::HistoryItemVector::const_iterator end = children.end(); - for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { - WebCore::HistoryItem* item = (*i).get(); - LOG_ASSERT(parent->bridge(), - "The parent item should have a bridge object!"); - if (!item->bridge()) { - WebHistoryItem* bridge = new WebHistoryItem(static_cast<WebHistoryItem*>(parent->bridge())); - item->setBridge(bridge); - bridge->setActive(); - } else { - // The only time this item's parent may not be the same as the - // parent's bridge is during history close. In that case, the - // parent must not have a parent bridge. - WebHistoryItem* bridge = static_cast<WebHistoryItem*>(item->bridge()); - WebHistoryItem* parentBridge = static_cast<WebHistoryItem*>(parent->bridge()); - LOG_ASSERT(parentBridge->parent() == 0 || - bridge->parent() == parentBridge, - "Somehow this item has an incorrect parent"); - bridge->setParent(parentBridge); - } - write_item(v, item); - write_children_recursive(v, item); - } -} - -static bool read_item_recursive(WebCore::HistoryItem* newItem, - const char** pData, int length) -{ - if (!pData || length < HISTORY_MIN_SIZE) - return false; - - const WebCore::TextEncoding& e = WebCore::UTF8Encoding(); - const char* data = *pData; - const char* end = data + length; - int sizeofUnsigned = (int)sizeof(unsigned); - - // Read the original url - // Read the expected length of the string. - int l; - memcpy(&l, data, sizeofUnsigned); - // Increment data pointer by the size of an unsigned int. - data += sizeofUnsigned; - if (l) { - LOGV("Original url %d %.*s", l, l, data); - // If we have a length, check if that length exceeds the data length - // and return null if there is not enough data. - if (data + l < end) - newItem->setOriginalURLString(e.decode(data, l)); - else - return false; - // Increment the data pointer by the length of the string. - data += l; - } - // Check if we have enough data left to continue. - if (end - data < sizeofUnsigned) - return false; - - // Read the url - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Url %d %.*s", l, l, data); - if (data + l < end) - newItem->setURLString(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the title - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Title %d %.*s", l, l, data); - if (data + l < end) - newItem->setTitle(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Generate a new ResourceRequest object for populating form information. - WTF::String formContentType; - WTF::PassRefPtr<WebCore::FormData> formData = NULL; - - // Read the form content type - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Content type %d %.*s", l, l, data); - if (data + l < end) - formContentType = e.decode(data, l); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - // Read the form data - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Form data %d %.*s", l, l, data); - if (data + l < end) - formData = WebCore::FormData::create(data, l); - else - return false; - data += l; - // Read the identifier - { - int64_t id; - int size = (int)sizeof(int64_t); - memcpy(&id, data, size); - data += size; - if (id) - formData->setIdentifier(id); - } - } - if (end - data < sizeofUnsigned) - return false; - - // Set up the form info - if (formData != NULL) { - WebCore::ResourceRequest r; - r.setHTTPMethod("POST"); - r.setHTTPContentType(formContentType); - r.setHTTPBody(formData); - newItem->setFormInfoFromRequest(r); - } - - // Read the target - memcpy(&l, data, sizeofUnsigned); - data += sizeofUnsigned; - if (l) { - LOGV("Target %d %.*s", l, l, data); - if (data + l < end) - newItem->setTarget(e.decode(data, l)); - else - return false; - data += l; - } - if (end - data < sizeofUnsigned) - return false; - - AndroidWebHistoryBridge* bridge = newItem->bridge(); - LOG_ASSERT(bridge, "There should be a bridge object during inflate"); - float fValue; - // Read the screen scale - memcpy(&fValue, data, sizeof(float)); - LOGV("Screen scale %f", fValue); - bridge->setScale(fValue); - data += sizeof(float); - memcpy(&fValue, data, sizeofUnsigned); - LOGV("Text wrap scale %f", fValue); - bridge->setTextWrapScale(fValue); - data += sizeof(float); - - if (end - data < sizeofUnsigned) - return false; - - // Read scroll position. - int scrollX = 0; - memcpy(&scrollX, data, sizeofUnsigned); - data += sizeofUnsigned; - int scrollY = 0; - memcpy(&scrollY, data, sizeofUnsigned); - data += sizeofUnsigned; - newItem->setScrollPoint(IntPoint(scrollX, scrollY)); - - if (end - data < sizeofUnsigned) - return false; - - // Read the document state - memcpy(&l, data, sizeofUnsigned); - LOGV("Document state %d", l); - data += sizeofUnsigned; - if (l) { - // Check if we have enough data to at least parse the sizes of each - // document state string. - if (data + l * sizeofUnsigned >= end) - return false; - // Create a new vector and reserve enough space for the document state. - WTF::Vector<WTF::String> docState; - docState.reserveCapacity(l); - while (l--) { - // Check each time if we have enough to parse the length of the next - // string. - if (end - data < sizeofUnsigned) - return false; - int strLen; - memcpy(&strLen, data, sizeofUnsigned); - data += sizeofUnsigned; - if (data + strLen < end) - docState.append(e.decode(data, strLen)); - else - return false; - LOGV("\t\t%d %.*s", strLen, strLen, data); - data += strLen; - } - newItem->setDocumentState(docState); - } - // Check if we have enough to read the next byte - if (data >= end) - return false; - - // Read is target item - // Cast the value to unsigned char in order to make a negative value larger - // than 1. A value that is not 0 or 1 is a failure. - unsigned char c = (unsigned char)data[0]; - if (c > 1) - return false; - LOGV("Target item %d", c); - newItem->setIsTargetItem((bool)c); - data++; - if (end - data < sizeofUnsigned) - return false; - - // Read the child count - memcpy(&l, data, sizeofUnsigned); - LOGV("Child count %d", l); - data += sizeofUnsigned; - *pData = data; - if (l) { - // Check if we have the minimum amount need to parse l children. - if (data + l * HISTORY_MIN_SIZE >= end) - return false; - while (l--) { - // No need to check the length each time because read_item_recursive - // will return null if there isn't enough data left to parse. - WTF::PassRefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create(); - // Set a bridge that will not call into java. - child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge))); - // Read the child item. - if (!read_item_recursive(child.get(), pData, end - data)) { - child.clear(); - return false; - } - child->bridge()->setActive(); - newItem->addChildItem(child); - } - } - return true; -} - -// On arm, this test will cause memory corruption since converting char* will -// byte align the result and this test does not use memset (it probably -// should). -// On the simulator, using HistoryItem will invoke the IconDatabase which will -// initialize the main thread. Since this is invoked by the Zygote process, the -// main thread will be incorrect and an assert will fire later. -// In conclusion, define UNIT_TEST only if you know what you are doing. -#ifdef UNIT_TEST -static void unit_test() -{ - LOGD("Entering history unit test!"); - const char* test1 = new char[0]; - WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); - WebCore::HistoryItem* testItem = item.get(); - testItem->setBridge(new WebHistoryItem(0)); - LOG_ASSERT(!read_item_recursive(testItem, &test1, 0), "0 length array should fail!"); - delete[] test1; - const char* test2 = new char[2]; - LOG_ASSERT(!read_item_recursive(testItem, &test2, 2), "Small array should fail!"); - delete[] test2; - LOG_ASSERT(!read_item_recursive(testItem, NULL, HISTORY_MIN_SIZE), "Null data should fail!"); - // Original Url - char* test3 = new char[HISTORY_MIN_SIZE]; - const char* ptr = (const char*)test3; - memset(test3, 0, HISTORY_MIN_SIZE); - *(int*)test3 = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length originalUrl should fail!"); - // Url - int offset = 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length url should fail!"); - // Title - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length title should fail!"); - // Form content type - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length contentType should fail!"); - // Form data - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length form data should fail!"); - // Target - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!"); - offset += 4; // Scale - // Document state - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length document state should fail!"); - // Is target item - offset += 1; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(char*)(test3 + offset) = '!'; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "IsTargetItem should fail with ! as the value!"); - // Child count - offset += 4; - memset(test3, 0, HISTORY_MIN_SIZE); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 4000; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!"); - offset = 36; - // Test document state - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 1; - *(int*)(test3 + offset + 4) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + sizeof(unsigned)), "1 20 length document state string should fail!"); - delete[] test3; - test3 = new char[HISTORY_MIN_SIZE + 2 * sizeof(unsigned)]; - memset(test3, 0, HISTORY_MIN_SIZE + 2 * sizeof(unsigned)); - ptr = (const char*)test3; - *(int*)(test3 + offset) = 2; - *(int*)(test3 + offset + 4) = 0; - *(int*)(test3 + offset + 8) = 20; - LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE + 2 * sizeof(unsigned) ), "2 20 length document state string should fail!"); - delete[] test3; -} -#endif - -//--------------------------------------------------------- -// JNI registration -//--------------------------------------------------------- -static JNINativeMethod gWebBackForwardListMethods[] = { - { "nativeClose", "(I)V", - (void*) WebHistoryClose }, - { "restoreIndex", "(II)V", - (void*) WebHistoryRestoreIndex } -}; - -static JNINativeMethod gWebHistoryItemMethods[] = { - { "inflate", "(I[B)V", - (void*) WebHistoryInflate } -}; - -int registerWebHistory(JNIEnv* env) -{ - // Get notified of all changes to history items. - WebCore::notifyHistoryItemChanged = historyItemChanged; -#ifdef UNIT_TEST - unit_test(); -#endif - // Find WebHistoryItem, its constructor, and the update method. - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); - gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "()V"); - LOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); - gWebHistoryItem.mUpdate = env->GetMethodID(clazz, "update", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Bitmap;[B)V"); - LOG_ASSERT(gWebHistoryItem.mUpdate, "Could not find method update in WebHistoryItem"); - - // Find the field ids for mTitle and mUrl. - gWebHistoryItem.mTitle = env->GetFieldID(clazz, "mTitle", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mTitle, "Could not find field mTitle in WebHistoryItem"); - gWebHistoryItem.mUrl = env->GetFieldID(clazz, "mUrl", "Ljava/lang/String;"); - LOG_ASSERT(gWebHistoryItem.mUrl, "Could not find field mUrl in WebHistoryItem"); - env->DeleteLocalRef(clazz); - - // Find the WebBackForwardList object and method. - clazz = env->FindClass("android/webkit/WebBackForwardList"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); - gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", - "(Landroid/webkit/WebHistoryItem;)V"); - LOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); - gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", - "(I)V"); - LOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); - gWebBackForwardList.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V"); - LOG_ASSERT(gWebBackForwardList.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)); -} - -} /* namespace android */ diff --git a/WebKit/android/jni/WebHistory.h b/WebKit/android/jni/WebHistory.h deleted file mode 100644 index 2d86aa4..0000000 --- a/WebKit/android/jni/WebHistory.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2006, 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 ANDROID_WEBKIT_WEBHISTORY_H -#define ANDROID_WEBKIT_WEBHISTORY_H - -#include "AndroidWebHistoryBridge.h" - -#include <jni.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> - -namespace android { - -class AutoJObject; - -class WebHistory { -public: - static jbyteArray Flatten(JNIEnv*, WTF::Vector<char>&, WebCore::HistoryItem*); - static void AddItem(const AutoJObject&, WebCore::HistoryItem*); - static void RemoveItem(const AutoJObject&, int); - static void UpdateHistoryIndex(const AutoJObject&, int); -}; - -// there are two scale factors saved with each history item. m_scale reflects the -// viewport scale factor, default to 100 means 100%. m_textWrapScale records -// the scale factor for wrapping the text paragraph. -class WebHistoryItem : public WebCore::AndroidWebHistoryBridge { -public: - WebHistoryItem(WebHistoryItem* parent) - : WebCore::AndroidWebHistoryBridge(0) - , m_parent(parent) - , m_object(NULL) { } - WebHistoryItem(JNIEnv*, jobject, WebCore::HistoryItem*); - ~WebHistoryItem(); - void updateHistoryItem(WebCore::HistoryItem* item); - void setParent(WebHistoryItem* parent) { m_parent = parent; } - WebHistoryItem* parent() const { return m_parent.get(); } -private: - RefPtr<WebHistoryItem> m_parent; - jweak m_object; -}; - -}; - -#endif diff --git a/WebKit/android/jni/WebIconDatabase.cpp b/WebKit/android/jni/WebIconDatabase.cpp deleted file mode 100644 index 2a660d1..0000000 --- a/WebKit/android/jni/WebIconDatabase.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2006, 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 "favicons" - -#include "config.h" -#include "WebIconDatabase.h" - -#include "FileSystem.h" -#include "GraphicsJNI.h" -#include "IconDatabase.h" -#include "Image.h" -#include "IntRect.h" -#include "JavaSharedClient.h" -#include "KURL.h" -#include "WebCoreJni.h" - -#include <JNIHelp.h> -#include <JNIUtility.h> -#include <SharedBuffer.h> -#include <SkBitmap.h> -#include <SkImageDecoder.h> -#include <SkTemplates.h> -#include <pthread.h> -#include <utils/misc.h> -#include <wtf/Platform.h> -#include <wtf/text/CString.h> - -namespace android { - -jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon) -{ - if (!icon) - return NULL; - SkBitmap bm; - WebCore::SharedBuffer* buffer = icon->data(); - if (!buffer || !SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(), - &bm, SkBitmap::kNo_Config, - SkImageDecoder::kDecodePixels_Mode)) - return NULL; - - return GraphicsJNI::createBitmap(env, new SkBitmap(bm), false, NULL); -} - -static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase(); - -// XXX: Called by the IconDatabase thread -void WebIconDatabase::dispatchDidAddIconForPageURL(const WTF::String& pageURL) -{ - mNotificationsMutex.lock(); - mNotifications.append(pageURL); - if (!mDeliveryRequested) { - mDeliveryRequested = true; - JavaSharedClient::EnqueueFunctionPtr(DeliverNotifications, this); - } - mNotificationsMutex.unlock(); -} - -// Called in the WebCore thread -void WebIconDatabase::RegisterForIconNotification(WebIconDatabaseClient* client) -{ - WebIconDatabase* db = gIconDatabaseClient; - for (unsigned i = 0; i < db->mClients.size(); ++i) { - // Do not add the same client twice. - if (db->mClients[i] == client) - return; - } - gIconDatabaseClient->mClients.append(client); -} - -// Called in the WebCore thread -void WebIconDatabase::UnregisterForIconNotification(WebIconDatabaseClient* client) -{ - WebIconDatabase* db = gIconDatabaseClient; - for (unsigned i = 0; i < db->mClients.size(); ++i) { - if (db->mClients[i] == client) { - db->mClients.remove(i); - break; - } - } -} - -// Called in the WebCore thread -void WebIconDatabase::DeliverNotifications(void* v) -{ - ASSERT(v); - ((WebIconDatabase*)v)->deliverNotifications(); -} - -// Called in the WebCore thread -void WebIconDatabase::deliverNotifications() -{ - ASSERT(mDeliveryRequested); - - // Swap the notifications queue - Vector<WTF::String> queue; - mNotificationsMutex.lock(); - queue.swap(mNotifications); - mDeliveryRequested = false; - mNotificationsMutex.unlock(); - - // Swap the clients queue - Vector<WebIconDatabaseClient*> clients; - clients.swap(mClients); - - for (unsigned i = 0; i < queue.size(); ++i) { - for (unsigned j = 0; j < clients.size(); ++j) { - clients[j]->didAddIconForPageUrl(queue[i]); - } - } -} - -static void Open(JNIEnv* env, jobject obj, jstring path) -{ - WebCore::IconDatabase* iconDb = WebCore::iconDatabase(); - if (iconDb->isOpen()) - return; - iconDb->setEnabled(true); - iconDb->setClient(gIconDatabaseClient); - LOG_ASSERT(path, "No path given to nativeOpen"); - WTF::String pathStr = jstringToWtfString(env, path); - WTF::CString fullPath = WebCore::pathByAppendingComponent(pathStr, - WebCore::IconDatabase::defaultDatabaseFilename()).utf8(); - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; - bool didSetPermissions = false; - if (access(fullPath.data(), F_OK) == 0) { - if (chmod(fullPath.data(), mode) == 0) - didSetPermissions = true; - } else { - int fd = open(fullPath.data(), O_CREAT, mode); - if (fd >= 0) { - close(fd); - didSetPermissions = true; - } - } - if (didSetPermissions) { - LOGV("Opening WebIconDatabase file '%s'", pathStr.latin1().data()); - bool res = iconDb->open(pathStr); - if (!res) - LOGE("Open failed!"); - } else - LOGE("Failed to set permissions on '%s'", fullPath.data()); -} - -static void Close(JNIEnv* env, jobject obj) -{ - WebCore::iconDatabase()->close(); -} - -static void RemoveAllIcons(JNIEnv* env, jobject obj) -{ - LOGV("Removing all icons"); - WebCore::iconDatabase()->removeAllIcons(); -} - -static jobject IconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to iconForPageUrl"); - WTF::String urlStr = jstringToWtfString(env, url); - - WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(urlStr, - WebCore::IntSize(16, 16)); - LOGV("Retrieving icon for '%s' %p", urlStr.latin1().data(), icon); - return webcoreImageToJavaBitmap(env, icon); -} - -static void RetainIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to retainIconForPageUrl"); - WTF::String urlStr = jstringToWtfString(env, url); - - LOGV("Retaining icon for '%s'", urlStr.latin1().data()); - WebCore::iconDatabase()->retainIconForPageURL(urlStr); -} - -static void ReleaseIconForPageUrl(JNIEnv* env, jobject obj, jstring url) -{ - LOG_ASSERT(url, "No url given to releaseIconForPageUrl"); - WTF::String urlStr = jstringToWtfString(env, url); - - LOGV("Releasing icon for '%s'", urlStr.latin1().data()); - WebCore::iconDatabase()->releaseIconForPageURL(urlStr); -} - -/* - * JNI registration - */ -static JNINativeMethod gWebIconDatabaseMethods[] = { - { "nativeOpen", "(Ljava/lang/String;)V", - (void*) Open }, - { "nativeClose", "()V", - (void*) Close }, - { "nativeRemoveAllIcons", "()V", - (void*) RemoveAllIcons }, - { "nativeIconForPageUrl", "(Ljava/lang/String;)Landroid/graphics/Bitmap;", - (void*) IconForPageUrl }, - { "nativeRetainIconForPageUrl", "(Ljava/lang/String;)V", - (void*) RetainIconForPageUrl }, - { "nativeReleaseIconForPageUrl", "(Ljava/lang/String;)V", - (void*) ReleaseIconForPageUrl } -}; - -int registerWebIconDatabase(JNIEnv* env) -{ -#ifndef NDEBUG - jclass webIconDatabase = env->FindClass("android/webkit/WebIconDatabase"); - LOG_ASSERT(webIconDatabase, "Unable to find class android.webkit.WebIconDatabase"); - env->DeleteLocalRef(webIconDatabase); -#endif - - return jniRegisterNativeMethods(env, "android/webkit/WebIconDatabase", - gWebIconDatabaseMethods, NELEM(gWebIconDatabaseMethods)); -} - -} diff --git a/WebKit/android/jni/WebIconDatabase.h b/WebKit/android/jni/WebIconDatabase.h deleted file mode 100644 index b2169aa..0000000 --- a/WebKit/android/jni/WebIconDatabase.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2006, 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 ANDROID_WEBKIT_WEBICONDATABASE_H -#define ANDROID_WEBKIT_WEBICONDATABASE_H - -#include "IconDatabaseClient.h" -#include "PlatformString.h" -#include "utils/threads.h" -#include <jni.h> -#include <wtf/Vector.h> - -namespace WebCore { - class Image; -} - -namespace android { - - class WebIconDatabaseClient { - public: - virtual ~WebIconDatabaseClient() {} - virtual void didAddIconForPageUrl(const WTF::String& pageUrl) = 0; - }; - - class WebIconDatabase : public WebCore::IconDatabaseClient { - public: - WebIconDatabase() : mDeliveryRequested(false) {} - // IconDatabaseClient method - virtual void dispatchDidAddIconForPageURL(const WTF::String& pageURL); - - static void RegisterForIconNotification(WebIconDatabaseClient* client); - static void UnregisterForIconNotification(WebIconDatabaseClient* client); - static void DeliverNotifications(void*); - - private: - // Deliver all the icon notifications - void deliverNotifications(); - - // List of clients. - Vector<WebIconDatabaseClient*> mClients; - - // Queue of page urls that have received an icon. - Vector<WTF::String> mNotifications; - android::Mutex mNotificationsMutex; - // Flag to indicate that we have requested a delivery of notifications. - bool mDeliveryRequested; - }; - - jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon); - -}; - -#endif diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp deleted file mode 100644 index 468e7b0..0000000 --- a/WebKit/android/jni/WebSettings.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright 2007, 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 "websettings" - -#include <config.h> -#include <wtf/Platform.h> - -#include "ApplicationCacheStorage.h" -#include "BitmapAllocatorAndroid.h" -#include "CachedResourceLoader.h" -#include "ChromiumIncludes.h" -#include "DatabaseTracker.h" -#include "Database.h" -#include "Document.h" -#include "EditorClientAndroid.h" -#include "FileSystem.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "GeolocationPermissions.h" -#include "GeolocationPositionCache.h" -#include "Page.h" -#include "PageCache.h" -#include "RenderTable.h" -#include "SQLiteFileSystem.h" -#include "Settings.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreJni.h" -#if USE(V8) -#include "WorkerContextExecutionProxy.h" -#endif -#include "WebRequestContext.h" -#include "WebViewCore.h" - -#include <JNIHelp.h> -#include <utils/misc.h> -#include <wtf/text/CString.h> - -namespace android { - -static const int permissionFlags660 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; - -struct FieldIds { - FieldIds(JNIEnv* env, jclass clazz) { - mLayoutAlgorithm = env->GetFieldID(clazz, "mLayoutAlgorithm", - "Landroid/webkit/WebSettings$LayoutAlgorithm;"); - mTextSize = env->GetFieldID(clazz, "mTextSize", - "Landroid/webkit/WebSettings$TextSize;"); - mStandardFontFamily = env->GetFieldID(clazz, "mStandardFontFamily", - "Ljava/lang/String;"); - mFixedFontFamily = env->GetFieldID(clazz, "mFixedFontFamily", - "Ljava/lang/String;"); - mSansSerifFontFamily = env->GetFieldID(clazz, "mSansSerifFontFamily", - "Ljava/lang/String;"); - mSerifFontFamily = env->GetFieldID(clazz, "mSerifFontFamily", - "Ljava/lang/String;"); - mCursiveFontFamily = env->GetFieldID(clazz, "mCursiveFontFamily", - "Ljava/lang/String;"); - mFantasyFontFamily = env->GetFieldID(clazz, "mFantasyFontFamily", - "Ljava/lang/String;"); - mDefaultTextEncoding = env->GetFieldID(clazz, "mDefaultTextEncoding", - "Ljava/lang/String;"); - mUserAgent = env->GetFieldID(clazz, "mUserAgent", - "Ljava/lang/String;"); - mAcceptLanguage = env->GetFieldID(clazz, "mAcceptLanguage", "Ljava/lang/String;"); - mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I"); - mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I"); - mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I"); - mDefaultFixedFontSize = env->GetFieldID(clazz, "mDefaultFixedFontSize", "I"); - mLoadsImagesAutomatically = env->GetFieldID(clazz, "mLoadsImagesAutomatically", "Z"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - mBlockNetworkImage = env->GetFieldID(clazz, "mBlockNetworkImage", "Z"); -#endif - mBlockNetworkLoads = env->GetFieldID(clazz, "mBlockNetworkLoads", "Z"); - mJavaScriptEnabled = env->GetFieldID(clazz, "mJavaScriptEnabled", "Z"); - mPluginState = env->GetFieldID(clazz, "mPluginState", - "Landroid/webkit/WebSettings$PluginState;"); -#if ENABLE(DATABASE) - mDatabaseEnabled = env->GetFieldID(clazz, "mDatabaseEnabled", "Z"); -#endif -#if ENABLE(DOM_STORAGE) - mDomStorageEnabled = env->GetFieldID(clazz, "mDomStorageEnabled", "Z"); -#endif -#if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) - // The databases saved to disk for both the SQL and DOM Storage APIs are stored - // in the same base directory. - mDatabasePath = env->GetFieldID(clazz, "mDatabasePath", "Ljava/lang/String;"); - mDatabasePathHasBeenSet = env->GetFieldID(clazz, "mDatabasePathHasBeenSet", "Z"); -#endif -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - mAppCacheEnabled = env->GetFieldID(clazz, "mAppCacheEnabled", "Z"); - mAppCachePath = env->GetFieldID(clazz, "mAppCachePath", "Ljava/lang/String;"); - mAppCacheMaxSize = env->GetFieldID(clazz, "mAppCacheMaxSize", "J"); -#endif -#if ENABLE(WORKERS) - mWorkersEnabled = env->GetFieldID(clazz, "mWorkersEnabled", "Z"); -#endif - mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z"); - mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;"); - mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z"); - mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, - "mJavaScriptCanOpenWindowsAutomatically", "Z"); - mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); - mSupportMultipleWindows = env->GetFieldID(clazz, "mSupportMultipleWindows", "Z"); - mShrinksStandaloneImagesToFit = env->GetFieldID(clazz, "mShrinksStandaloneImagesToFit", "Z"); - mMaximumDecodedImageSize = env->GetFieldID(clazz, "mMaximumDecodedImageSize", "J"); - mPrivateBrowsingEnabled = env->GetFieldID(clazz, "mPrivateBrowsingEnabled", "Z"); - mSyntheticLinksEnabled = env->GetFieldID(clazz, "mSyntheticLinksEnabled", "Z"); - mUseDoubleTree = env->GetFieldID(clazz, "mUseDoubleTree", "Z"); - mPageCacheCapacity = env->GetFieldID(clazz, "mPageCacheCapacity", "I"); -#if ENABLE(WEB_AUTOFILL) - mAutoFillEnabled = env->GetFieldID(clazz, "mAutoFillEnabled", "Z"); - mAutoFillProfile = env->GetFieldID(clazz, "mAutoFillProfile", "Landroid/webkit/WebSettings$AutoFillProfile;"); - jclass autoFillProfileClass = env->FindClass("android/webkit/WebSettings$AutoFillProfile"); - mAutoFillProfileFullName = env->GetFieldID(autoFillProfileClass, "mFullName", "Ljava/lang/String;"); - mAutoFillProfileEmailAddress = env->GetFieldID(autoFillProfileClass, "mEmailAddress", "Ljava/lang/String;"); - mAutoFillProfileCompanyName = env->GetFieldID(autoFillProfileClass, "mCompanyName", "Ljava/lang/String;"); - mAutoFillProfileAddressLine1 = env->GetFieldID(autoFillProfileClass, "mAddressLine1", "Ljava/lang/String;"); - mAutoFillProfileAddressLine2 = env->GetFieldID(autoFillProfileClass, "mAddressLine2", "Ljava/lang/String;"); - mAutoFillProfileCity = env->GetFieldID(autoFillProfileClass, "mCity", "Ljava/lang/String;"); - mAutoFillProfileState = env->GetFieldID(autoFillProfileClass, "mState", "Ljava/lang/String;"); - mAutoFillProfileZipCode = env->GetFieldID(autoFillProfileClass, "mZipCode", "Ljava/lang/String;"); - mAutoFillProfileCountry = env->GetFieldID(autoFillProfileClass, "mCountry", "Ljava/lang/String;"); - mAutoFillProfilePhoneNumber = env->GetFieldID(autoFillProfileClass, "mPhoneNumber", "Ljava/lang/String;"); - env->DeleteLocalRef(autoFillProfileClass); -#endif -#if USE(CHROME_NETWORK_STACK) - mOverrideCacheMode = env->GetFieldID(clazz, "mOverrideCacheMode", "I"); -#endif - - LOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); - LOG_ASSERT(mTextSize, "Could not find field mTextSize"); - LOG_ASSERT(mStandardFontFamily, "Could not find field mStandardFontFamily"); - LOG_ASSERT(mFixedFontFamily, "Could not find field mFixedFontFamily"); - LOG_ASSERT(mSansSerifFontFamily, "Could not find field mSansSerifFontFamily"); - LOG_ASSERT(mSerifFontFamily, "Could not find field mSerifFontFamily"); - LOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); - LOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); - LOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); - LOG_ASSERT(mUserAgent, "Could not find field mUserAgent"); - LOG_ASSERT(mAcceptLanguage, "Could not find field mAcceptLanguage"); - LOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); - LOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); - LOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); - LOG_ASSERT(mDefaultFixedFontSize, "Could not find field mDefaultFixedFontSize"); - LOG_ASSERT(mLoadsImagesAutomatically, "Could not find field mLoadsImagesAutomatically"); -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - LOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage"); -#endif - LOG_ASSERT(mBlockNetworkLoads, "Could not find field mBlockNetworkLoads"); - LOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled"); - LOG_ASSERT(mPluginState, "Could not find field mPluginState"); -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - LOG_ASSERT(mAppCacheEnabled, "Could not find field mAppCacheEnabled"); - LOG_ASSERT(mAppCachePath, "Could not find field mAppCachePath"); - LOG_ASSERT(mAppCacheMaxSize, "Could not find field mAppCacheMaxSize"); -#endif -#if ENABLE(WORKERS) - LOG_ASSERT(mWorkersEnabled, "Could not find field mWorkersEnabled"); -#endif - LOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically, - "Could not find field mJavaScriptCanOpenWindowsAutomatically"); - LOG_ASSERT(mUseWideViewport, "Could not find field mUseWideViewport"); - LOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows"); - LOG_ASSERT(mShrinksStandaloneImagesToFit, "Could not find field mShrinksStandaloneImagesToFit"); - LOG_ASSERT(mMaximumDecodedImageSize, "Could not find field mMaximumDecodedImageSize"); - LOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); - LOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity"); - - jclass enumClass = env->FindClass("java/lang/Enum"); - LOG_ASSERT(enumClass, "Could not find Enum class!"); - mOrdinal = env->GetMethodID(enumClass, "ordinal", "()I"); - LOG_ASSERT(mOrdinal, "Could not find method ordinal"); - env->DeleteLocalRef(enumClass); - - jclass textSizeClass = env->FindClass("android/webkit/WebSettings$TextSize"); - LOG_ASSERT(textSizeClass, "Could not find TextSize enum"); - mTextSizeValue = env->GetFieldID(textSizeClass, "value", "I"); - env->DeleteLocalRef(textSizeClass); - } - - // Field ids - jfieldID mLayoutAlgorithm; - jfieldID mTextSize; - jfieldID mStandardFontFamily; - jfieldID mFixedFontFamily; - jfieldID mSansSerifFontFamily; - jfieldID mSerifFontFamily; - jfieldID mCursiveFontFamily; - jfieldID mFantasyFontFamily; - jfieldID mDefaultTextEncoding; - jfieldID mUserAgent; - jfieldID mAcceptLanguage; - jfieldID mMinimumFontSize; - jfieldID mMinimumLogicalFontSize; - jfieldID mDefaultFontSize; - jfieldID mDefaultFixedFontSize; - jfieldID mLoadsImagesAutomatically; -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - jfieldID mBlockNetworkImage; -#endif - jfieldID mBlockNetworkLoads; - jfieldID mJavaScriptEnabled; - jfieldID mPluginState; -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - jfieldID mAppCacheEnabled; - jfieldID mAppCachePath; - jfieldID mAppCacheMaxSize; -#endif -#if ENABLE(WORKERS) - jfieldID mWorkersEnabled; -#endif - jfieldID mJavaScriptCanOpenWindowsAutomatically; - jfieldID mUseWideViewport; - jfieldID mSupportMultipleWindows; - jfieldID mShrinksStandaloneImagesToFit; - jfieldID mMaximumDecodedImageSize; - jfieldID mPrivateBrowsingEnabled; - jfieldID mSyntheticLinksEnabled; - jfieldID mUseDoubleTree; - jfieldID mPageCacheCapacity; - // Ordinal() method and value field for enums - jmethodID mOrdinal; - jfieldID mTextSizeValue; - -#if ENABLE(DATABASE) - jfieldID mDatabaseEnabled; -#endif -#if ENABLE(DOM_STORAGE) - jfieldID mDomStorageEnabled; -#endif - jfieldID mGeolocationEnabled; - jfieldID mGeolocationDatabasePath; - jfieldID mXSSAuditorEnabled; -#if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) - jfieldID mDatabasePath; - jfieldID mDatabasePathHasBeenSet; -#endif -#if ENABLE(WEB_AUTOFILL) - jfieldID mAutoFillEnabled; - jfieldID mAutoFillProfile; - jfieldID mAutoFillProfileFullName; - jfieldID mAutoFillProfileEmailAddress; - jfieldID mAutoFillProfileCompanyName; - jfieldID mAutoFillProfileAddressLine1; - jfieldID mAutoFillProfileAddressLine2; - jfieldID mAutoFillProfileCity; - jfieldID mAutoFillProfileState; - jfieldID mAutoFillProfileZipCode; - jfieldID mAutoFillProfileCountry; - jfieldID mAutoFillProfilePhoneNumber; -#endif -#if USE(CHROME_NETWORK_STACK) - jfieldID mOverrideCacheMode; -#endif -}; - -static struct FieldIds* gFieldIds; - -// Note: This is moved from the old FrameAndroid.cpp -static void recursiveCleanupForFullLayout(WebCore::RenderObject* obj) -{ - obj->setNeedsLayout(true, false); -#ifdef ANDROID_LAYOUT - if (obj->isTable()) - (static_cast<WebCore::RenderTable *>(obj))->clearSingleColumn(); -#endif - for (WebCore::RenderObject* n = obj->firstChild(); n; n = n->nextSibling()) - recursiveCleanupForFullLayout(n); -} - -#if ENABLE(WEB_AUTOFILL) -inline string16 getStringFieldAsString16(JNIEnv* env, jobject autoFillProfile, jfieldID fieldId) -{ - jstring str = static_cast<jstring>(env->GetObjectField(autoFillProfile, fieldId)); - return str ? jstringToString16(env, str) : string16(); -} - -void syncAutoFillProfile(JNIEnv* env, jobject autoFillProfile, WebAutoFill* webAutoFill) -{ - string16 fullName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileFullName); - string16 emailAddress = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileEmailAddress); - string16 companyName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCompanyName); - string16 addressLine1 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine1); - string16 addressLine2 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine2); - string16 city = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCity); - string16 state = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileState); - string16 zipCode = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileZipCode); - string16 country = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCountry); - string16 phoneNumber = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfilePhoneNumber); - - webAutoFill->setProfile(fullName, emailAddress, companyName, addressLine1, addressLine2, city, state, zipCode, country, phoneNumber); -} -#endif - -class WebSettings { -public: - static void Sync(JNIEnv* env, jobject obj, jint frame) - { - WebCore::Frame* pFrame = (WebCore::Frame*)frame; - LOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__); - WebCore::Settings* s = pFrame->settings(); - if (!s) - return; - WebCore::CachedResourceLoader* cachedResourceLoader = pFrame->document()->cachedResourceLoader(); - -#ifdef ANDROID_LAYOUT - jobject layout = env->GetObjectField(obj, gFieldIds->mLayoutAlgorithm); - WebCore::Settings::LayoutAlgorithm l = (WebCore::Settings::LayoutAlgorithm) - env->CallIntMethod(layout, gFieldIds->mOrdinal); - if (s->layoutAlgorithm() != l) { - s->setLayoutAlgorithm(l); - if (pFrame->document()) { - pFrame->document()->styleSelectorChanged(WebCore::RecalcStyleImmediately); - if (pFrame->document()->renderer()) { - recursiveCleanupForFullLayout(pFrame->document()->renderer()); - LOG_ASSERT(pFrame->view(), "No view for this frame when trying to relayout"); - pFrame->view()->layout(); - // FIXME: This call used to scroll the page to put the focus into view. - // It worked on the WebViewCore, but now scrolling is done outside of the - // WebViewCore, on the UI side, so there needs to be a new way to do this. - //pFrame->makeFocusVisible(); - } - } - } -#endif - jobject textSize = env->GetObjectField(obj, gFieldIds->mTextSize); - float zoomFactor = env->GetIntField(textSize, gFieldIds->mTextSizeValue) / 100.0f; - if (pFrame->textZoomFactor() != zoomFactor) - pFrame->setTextZoomFactor(zoomFactor); - - jstring str = (jstring)env->GetObjectField(obj, gFieldIds->mStandardFontFamily); - s->setStandardFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFixedFontFamily); - s->setFixedFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSansSerifFontFamily); - s->setSansSerifFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mSerifFontFamily); - s->setSerifFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mCursiveFontFamily); - s->setCursiveFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mFantasyFontFamily); - s->setFantasyFontFamily(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); - s->setDefaultTextEncodingName(jstringToWtfString(env, str)); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent); - WebFrame::getWebFrame(pFrame)->setUserAgent(jstringToWtfString(env, str)); -#if USE(CHROME_NETWORK_STACK) - WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextUserAgent(); - - jint cacheMode = env->GetIntField(obj, gFieldIds->mOverrideCacheMode); - WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextCacheMode(cacheMode); - - str = (jstring)env->GetObjectField(obj, gFieldIds->mAcceptLanguage); - WebRequestContext::setAcceptLanguage(jstringToWtfString(env, str)); -#endif - - jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); - s->setMinimumFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mMinimumLogicalFontSize); - s->setMinimumLogicalFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFontSize); - s->setDefaultFontSize(size); - - size = env->GetIntField(obj, gFieldIds->mDefaultFixedFontSize); - s->setDefaultFixedFontSize(size); - - jboolean flag = env->GetBooleanField(obj, gFieldIds->mLoadsImagesAutomatically); - s->setLoadsImagesAutomatically(flag); - if (flag) - cachedResourceLoader->setAutoLoadImages(true); - -#ifdef ANDROID_BLOCK_NETWORK_IMAGE - flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage); - s->setBlockNetworkImage(flag); - if(!flag) - cachedResourceLoader->setBlockNetworkImage(false); -#endif - flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkLoads); - WebFrame* webFrame = WebFrame::getWebFrame(pFrame); - webFrame->setBlockNetworkLoads(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled); - s->setJavaScriptEnabled(flag); - - // ON = 0 - // ON_DEMAND = 1 - // OFF = 2 - jobject pluginState = env->GetObjectField(obj, gFieldIds->mPluginState); - int state = env->CallIntMethod(pluginState, gFieldIds->mOrdinal); - s->setPluginsEnabled(state < 2); -#ifdef ANDROID_PLUGINS - s->setPluginsOnDemand(state == 1); -#endif - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - flag = env->GetBooleanField(obj, gFieldIds->mAppCacheEnabled); - s->setOfflineWebApplicationCacheEnabled(flag); - str = (jstring)env->GetObjectField(obj, gFieldIds->mAppCachePath); - if (str) { - String path = jstringToWtfString(env, str); - if (path.length() && cacheStorage().cacheDirectory().isNull()) { - cacheStorage().setCacheDirectory(path); - // This database is created on the first load. If the file - // doesn't exist, we create it and set its permissions. The - // filename must match that in ApplicationCacheStorage.cpp. - String filename = pathByAppendingComponent(path, "ApplicationCache.db"); - int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); - if (fd >= 0) - close(fd); - } - } - jlong maxsize = env->GetLongField(obj, gFieldIds->mAppCacheMaxSize); - cacheStorage().setMaximumSize(maxsize); -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically); - s->setJavaScriptCanOpenWindowsAutomatically(flag); - -#ifdef ANDROID_LAYOUT - flag = env->GetBooleanField(obj, gFieldIds->mUseWideViewport); - s->setUseWideViewport(flag); -#endif - -#ifdef ANDROID_MULTIPLE_WINDOWS - flag = env->GetBooleanField(obj, gFieldIds->mSupportMultipleWindows); - s->setSupportMultipleWindows(flag); -#endif - flag = env->GetBooleanField(obj, gFieldIds->mShrinksStandaloneImagesToFit); - s->setShrinksStandaloneImagesToFit(flag); - jlong maxImage = env->GetLongField(obj, gFieldIds->mMaximumDecodedImageSize); - // Since in ImageSourceAndroid.cpp, the image will always not exceed - // MAX_SIZE_BEFORE_SUBSAMPLE, there's no need to pass the max value to - // WebCore, which checks (image_width * image_height * 4) as an - // estimation against the max value, which is done in CachedImage.cpp. - // And there're cases where the decoded image size will not - // exceed the max, but the WebCore estimation will. So the following - // code is commented out to fix those cases. - // if (maxImage == 0) - // maxImage = computeMaxBitmapSizeForCache(); - s->setMaximumDecodedImageSize(maxImage); - - flag = env->GetBooleanField(obj, gFieldIds->mPrivateBrowsingEnabled); - s->setPrivateBrowsingEnabled(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mSyntheticLinksEnabled); - s->setDefaultFormatDetection(flag); - s->setFormatDetectionAddress(flag); - s->setFormatDetectionEmail(flag); - s->setFormatDetectionTelephone(flag); -#if ENABLE(DATABASE) - flag = env->GetBooleanField(obj, gFieldIds->mDatabaseEnabled); - WebCore::Database::setIsAvailable(flag); - - flag = env->GetBooleanField(obj, gFieldIds->mDatabasePathHasBeenSet); - if (flag) { - // If the user has set the database path, sync it to the DatabaseTracker. - str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); - if (str) { - String path = jstringToWtfString(env, str); - DatabaseTracker::tracker().setDatabaseDirectoryPath(path); - // This database is created when the first HTML5 Database object is - // instantiated. If the file doesn't exist, we create it and set its - // permissions. The filename must match that in - // DatabaseTracker.cpp. - String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "Databases.db"); - int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); - if (fd >= 0) - close(fd); - } - } -#endif -#if ENABLE(DOM_STORAGE) - flag = env->GetBooleanField(obj, gFieldIds->mDomStorageEnabled); - s->setLocalStorageEnabled(flag); - str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); - if (str) { - WTF::String localStorageDatabasePath = jstringToWtfString(env,str); - if (localStorageDatabasePath.length()) { - localStorageDatabasePath = WebCore::pathByAppendingComponent( - localStorageDatabasePath, "localstorage"); - // We need 770 for folders - mkdir(localStorageDatabasePath.utf8().data(), - permissionFlags660 | S_IXUSR | S_IXGRP); - s->setLocalStorageDatabasePath(localStorageDatabasePath); - } - } -#endif - - flag = env->GetBooleanField(obj, gFieldIds->mGeolocationEnabled); - GeolocationPermissions::setAlwaysDeny(!flag); - str = (jstring)env->GetObjectField(obj, gFieldIds->mGeolocationDatabasePath); - if (str) { - String path = jstringToWtfString(env, str); - GeolocationPermissions::setDatabasePath(path); - GeolocationPositionCache::instance()->setDatabasePath(path); - // This database is created when the first Geolocation object is - // instantiated. If the file doesn't exist, we create it and set its - // permissions. The filename must match that in - // GeolocationPositionCache.cpp. - String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "CachedGeoposition.db"); - int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); - if (fd >= 0) - close(fd); - } - - flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); - s->setXSSAuditorEnabled(flag); - - size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); - if (size > 0) { - s->setUsesPageCache(true); - WebCore::pageCache()->setCapacity(size); - } else - s->setUsesPageCache(false); - -#if ENABLE(WEB_AUTOFILL) - flag = env->GetBooleanField(obj, gFieldIds->mAutoFillEnabled); - // TODO: This updates the Settings WebCore side with the user's - // preference for autofill and will stop WebCore making requests - // into the chromium autofill code. That code in Chromium also has - // a notion of being enabled/disabled that gets read from the users - // preferences. At the moment, it's hardcoded to true on Android - // (see chrome/browser/autofill/autofill_manager.cc:405). This - // setting should probably be synced into Chromium also. - - s->setAutoFillEnabled(flag); - - if (flag) { - EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(pFrame->page()->editorClient()); - WebAutoFill* webAutoFill = editorC->getAutoFill(); - // Set the active AutoFillProfile data. - jobject autoFillProfile = env->GetObjectField(obj, gFieldIds->mAutoFillProfile); - if (autoFillProfile) - syncAutoFillProfile(env, autoFillProfile, webAutoFill); - else { - // The autofill profile is null. We need to tell Chromium about this because - // this may be because the user just deleted their profile but left the - // autofill feature setting enabled. - webAutoFill->clearProfiles(); - } - } -#endif - } -}; - - -//------------------------------------------------------------- -// JNI registration -//------------------------------------------------------------- - -static JNINativeMethod gWebSettingsMethods[] = { - { "nativeSync", "(I)V", - (void*) WebSettings::Sync } -}; - -int registerWebSettings(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/WebSettings"); - LOG_ASSERT(clazz, "Unable to find class WebSettings!"); - gFieldIds = new FieldIds(env, clazz); - env->DeleteLocalRef(clazz); - return jniRegisterNativeMethods(env, "android/webkit/WebSettings", - gWebSettingsMethods, NELEM(gWebSettingsMethods)); -} - -} diff --git a/WebKit/android/jni/WebStorage.cpp b/WebKit/android/jni/WebStorage.cpp deleted file mode 100644 index 9ce207d..0000000 --- a/WebKit/android/jni/WebStorage.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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" - -#if ENABLE(DATABASE) - -#include "ApplicationCacheStorage.h" -#include "DatabaseTracker.h" -#include "JNIUtility.h" -#include "JavaSharedClient.h" -#include "KURL.h" -#include "PageGroup.h" -#include "SecurityOrigin.h" -#include "WebCoreJni.h" - -#include <JNIHelp.h> - -namespace android { - -static jobject GetOrigins(JNIEnv* env, jobject obj) -{ - Vector<RefPtr<WebCore::SecurityOrigin> > coreOrigins; - WebCore::DatabaseTracker::tracker().origins(coreOrigins); - Vector<WebCore::KURL> manifestUrls; - if (WebCore::cacheStorage().manifestURLs(&manifestUrls)) { - int size = manifestUrls.size(); - for (int i = 0; i < size; ++i) { - RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]); - if (manifestOrigin.get() == 0) - continue; - coreOrigins.append(manifestOrigin); - } - } - - jclass setClass = env->FindClass("java/util/HashSet"); - jmethodID cid = env->GetMethodID(setClass, "<init>", "()V"); - jmethodID mid = env->GetMethodID(setClass, "add", "(Ljava/lang/Object;)Z"); - jobject set = env->NewObject(setClass, cid); - env->DeleteLocalRef(setClass); - - for (unsigned i = 0; i < coreOrigins.size(); ++i) { - WebCore::SecurityOrigin* origin = coreOrigins[i].get(); - WTF::String url = origin->toString(); - jstring jUrl = wtfStringToJstring(env, url); - env->CallBooleanMethod(set, mid, jUrl); - env->DeleteLocalRef(jUrl); - } - - return set; -} - -static unsigned long long GetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originStr = jstringToWtfString(env, origin); - RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr); - unsigned long long quota = WebCore::DatabaseTracker::tracker().quotaForOrigin(securityOrigin.get()); - return quota; -} - -static unsigned long long GetUsageForOrigin(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originStr = jstringToWtfString(env, origin); - RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr); - unsigned long long usage = WebCore::DatabaseTracker::tracker().usageForOrigin(securityOrigin.get()); - Vector<WebCore::KURL> manifestUrls; - if (!WebCore::cacheStorage().manifestURLs(&manifestUrls)) - return usage; - int size = manifestUrls.size(); - for (int i = 0; i < size; ++i) { - RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]); - if (manifestOrigin.get() == 0) - continue; - if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get())) { - int64_t cacheSize = 0; - WebCore::cacheStorage().cacheGroupSize(manifestUrls[i].string(), &cacheSize); - usage += cacheSize; - } - } - return usage; -} - -static void SetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin, unsigned long long quota) -{ - WTF::String originStr = jstringToWtfString(env, origin); - RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr); - WebCore::DatabaseTracker::tracker().setQuota(securityOrigin.get(), quota); -} - -static void DeleteOrigin(JNIEnv* env, jobject obj, jstring origin) -{ - WTF::String originStr = jstringToWtfString(env, origin); - RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr); - WebCore::DatabaseTracker::tracker().deleteOrigin(securityOrigin.get()); - - Vector<WebCore::KURL> manifestUrls; - if (!WebCore::cacheStorage().manifestURLs(&manifestUrls)) - return; - int size = manifestUrls.size(); - for (int i = 0; i < size; ++i) { - RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]); - if (manifestOrigin.get() == 0) - continue; - if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get())) - WebCore::cacheStorage().deleteCacheGroup(manifestUrls[i]); - } -} - -static void DeleteAllData(JNIEnv* env, jobject obj) -{ - 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]); - - // 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 - // moment to do it. That functionality is a WIP in https://bugs.webkit.org/show_bug.cgi?id=51878 - // and when that patch lands and we merge it, we should move towards that approach instead. - WebCore::PageGroup::clearDomStorage(); -} - -static void SetAppCacheMaximumSize(JNIEnv* env, jobject obj, unsigned long long size) -{ - WebCore::cacheStorage().setMaximumSize(size); -} - -/* - * JNI registration - */ -static JNINativeMethod gWebStorageMethods[] = { - { "nativeGetOrigins", "()Ljava/util/Set;", - (void*) GetOrigins }, - { "nativeGetUsageForOrigin", "(Ljava/lang/String;)J", - (void*) GetUsageForOrigin }, - { "nativeGetQuotaForOrigin", "(Ljava/lang/String;)J", - (void*) GetQuotaForOrigin }, - { "nativeSetQuotaForOrigin", "(Ljava/lang/String;J)V", - (void*) SetQuotaForOrigin }, - { "nativeDeleteOrigin", "(Ljava/lang/String;)V", - (void*) DeleteOrigin }, - { "nativeDeleteAllData", "()V", - (void*) DeleteAllData }, - { "nativeSetAppCacheMaximumSize", "(J)V", - (void*) SetAppCacheMaximumSize } -}; - -int registerWebStorage(JNIEnv* env) -{ -#ifndef NDEBUG - jclass webStorage = env->FindClass("android/webkit/WebStorage"); - LOG_ASSERT(webStorage, "Unable to find class android.webkit.WebStorage"); - env->DeleteLocalRef(webStorage); -#endif - - return jniRegisterNativeMethods(env, "android/webkit/WebStorage", - gWebStorageMethods, NELEM(gWebStorageMethods)); -} - -} - -#endif //ENABLE(DATABASE) diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp deleted file mode 100644 index f2680b5..0000000 --- a/WebKit/android/jni/WebViewCore.cpp +++ /dev/null @@ -1,4598 +0,0 @@ -/* - * Copyright 2006, 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 "webcoreglue" - -#include "config.h" -#include "WebViewCore.h" - -#include "AccessibilityObject.h" -#include "Attribute.h" -#include "BaseLayerAndroid.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "Chrome.h" -#include "ChromeClientAndroid.h" -#include "ChromiumIncludes.h" -#include "ClientRect.h" -#include "ClientRectList.h" -#include "Color.h" -#include "CSSPropertyNames.h" -#include "CSSValueKeywords.h" -#include "DatabaseTracker.h" -#include "Document.h" -#include "DOMWindow.h" -#include "DOMSelection.h" -#include "Element.h" -#include "Editor.h" -#include "EditorClientAndroid.h" -#include "EventHandler.h" -#include "EventNames.h" -#include "ExceptionCode.h" -#include "FocusController.h" -#include "Font.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "Geolocation.h" -#include "GraphicsContext.h" -#include "GraphicsJNI.h" -#include "HTMLAnchorElement.h" -#include "HTMLAreaElement.h" -#include "HTMLElement.h" -#include "HTMLFormControlElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLLabelElement.h" -#include "HTMLMapElement.h" -#include "HTMLNames.h" -#include "HTMLOptGroupElement.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "HTMLTextAreaElement.h" -#include "HistoryItem.h" -#include "HitTestRequest.h" -#include "HitTestResult.h" -#include "InlineTextBox.h" -#include "MemoryUsage.h" -#include "NamedNodeMap.h" -#include "Navigator.h" -#include "Node.h" -#include "NodeList.h" -#include "Page.h" -#include "PageGroup.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformString.h" -#include "PluginWidgetAndroid.h" -#include "PluginView.h" -#include "Position.h" -#include "ProgressTracker.h" -#include "Range.h" -#include "RenderBox.h" -#include "RenderInline.h" -#include "RenderLayer.h" -#include "RenderPart.h" -#include "RenderText.h" -#include "RenderTextControl.h" -#include "RenderThemeAndroid.h" -#include "RenderView.h" -#include "ResourceRequest.h" -#include "SchemeRegistry.h" -#include "SelectionController.h" -#include "Settings.h" -#include "SkANP.h" -#include "SkTemplates.h" -#include "SkTDArray.h" -#include "SkTypes.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "SkUtils.h" -#include "Text.h" -#include "TypingCommand.h" -#include "WebCoreFrameBridge.h" -#include "WebFrameView.h" -#include "WindowsKeyboardCodes.h" -#include "android_graphics.h" -#include "autofill/WebAutoFill.h" -#include "htmlediting.h" -#include "markup.h" - -#include <JNIHelp.h> -#include <JNIUtility.h> -#include <ui/KeycodeLabels.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/AtomicString.h> -#include <wtf/text/StringImpl.h> - -#if USE(V8) -#include "ScriptController.h" -#include "V8Counters.h" -#include <wtf/text/CString.h> -#endif - -#if DEBUG_NAV_UI -#include "SkTime.h" -#endif - -#if ENABLE(TOUCH_EVENTS) // Android -#include "PlatformTouchEvent.h" -#endif - -#ifdef ANDROID_DOM_LOGGING -#include "AndroidLog.h" -#include "RenderTreeAsText.h" -#include <wtf/text/CString.h> - -FILE* gDomTreeFile = 0; -FILE* gRenderTreeFile = 0; -#endif - -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif - -#if USE(ACCELERATED_COMPOSITING) -#include "GraphicsLayerAndroid.h" -#include "RenderLayerCompositor.h" -#endif - -/* We pass this flag when recording the actual content, so that we don't spend - time actually regionizing complex path clips, when all we really want to do - is record them. - */ -#define PICT_RECORD_FLAGS SkPicture::kUsePathBoundsForClip_RecordingFlag - -//////////////////////////////////////////////////////////////////////////////////////////////// - -namespace android { - -static SkTDArray<WebViewCore*> gInstanceList; - -void WebViewCore::addInstance(WebViewCore* inst) { - *gInstanceList.append() = inst; -} - -void WebViewCore::removeInstance(WebViewCore* inst) { - int index = gInstanceList.find(inst); - LOG_ASSERT(index >= 0, "RemoveInstance inst not found"); - if (index >= 0) { - gInstanceList.removeShuffle(index); - } -} - -bool WebViewCore::isInstance(WebViewCore* inst) { - return gInstanceList.find(inst) >= 0; -} - -jobject WebViewCore::getApplicationContext() { - - // check to see if there is a valid webviewcore object - if (gInstanceList.isEmpty()) - return 0; - - // get the context from the webview - jobject context = gInstanceList[0]->getContext(); - - if (!context) - return 0; - - // get the application context using JNI - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass contextClass = env->GetObjectClass(context); - jmethodID appContextMethod = env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;"); - env->DeleteLocalRef(contextClass); - jobject result = env->CallObjectMethod(context, appContextMethod); - checkException(env); - return result; -} - - -struct WebViewCoreStaticMethods { - jmethodID m_isSupportedMediaMimeType; -} gWebViewCoreStaticMethods; - -// Check whether a media mimeType is supported in Android media framework. -bool WebViewCore::isSupportedMediaMimeType(const WTF::String& mimeType) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jMimeType = wtfStringToJstring(env, mimeType); - jclass webViewCore = env->FindClass("android/webkit/WebViewCore"); - bool val = env->CallStaticBooleanMethod(webViewCore, - gWebViewCoreStaticMethods.m_isSupportedMediaMimeType, jMimeType); - checkException(env); - env->DeleteLocalRef(webViewCore); - env->DeleteLocalRef(jMimeType); - - return val; -} - -// ---------------------------------------------------------------------------- - -#define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.m_nativeClass)) - -// Field ids for WebViewCore -struct WebViewCoreFields { - jfieldID m_nativeClass; - jfieldID m_viewportWidth; - jfieldID m_viewportHeight; - jfieldID m_viewportInitialScale; - jfieldID m_viewportMinimumScale; - jfieldID m_viewportMaximumScale; - jfieldID m_viewportUserScalable; - jfieldID m_viewportDensityDpi; - jfieldID m_webView; - jfieldID m_drawIsPaused; - jfieldID m_lowMemoryUsageMb; - jfieldID m_highMemoryUsageMb; - jfieldID m_highUsageDeltaMb; -} gWebViewCoreFields; - -// ---------------------------------------------------------------------------- - -struct WebViewCore::JavaGlue { - jweak m_obj; - jmethodID m_scrollTo; - jmethodID m_contentDraw; - jmethodID m_layersDraw; - jmethodID m_requestListBox; - jmethodID m_openFileChooser; - jmethodID m_requestSingleListBox; - jmethodID m_jsAlert; - jmethodID m_jsConfirm; - jmethodID m_jsPrompt; - jmethodID m_jsUnload; - jmethodID m_jsInterrupt; - jmethodID m_didFirstLayout; - jmethodID m_updateViewport; - jmethodID m_sendNotifyProgressFinished; - jmethodID m_sendViewInvalidate; - jmethodID m_updateTextfield; - jmethodID m_updateTextSelection; - jmethodID m_clearTextEntry; - jmethodID m_restoreScale; - jmethodID m_needTouchEvents; - jmethodID m_requestKeyboard; - jmethodID m_requestKeyboardWithSelection; - jmethodID m_exceededDatabaseQuota; - jmethodID m_reachedMaxAppCacheSize; - jmethodID m_populateVisitedLinks; - jmethodID m_geolocationPermissionsShowPrompt; - jmethodID m_geolocationPermissionsHidePrompt; - jmethodID m_getDeviceMotionService; - jmethodID m_getDeviceOrientationService; - jmethodID m_addMessageToConsole; - jmethodID m_formDidBlur; - jmethodID m_getPluginClass; - jmethodID m_showFullScreenPlugin; - jmethodID m_hideFullScreenPlugin; - jmethodID m_createSurface; - jmethodID m_addSurface; - jmethodID m_updateSurface; - jmethodID m_destroySurface; - jmethodID m_getContext; - jmethodID m_keepScreenOn; - jmethodID m_sendFindAgain; - jmethodID m_showRect; - jmethodID m_centerFitRect; - jmethodID m_setScrollbarModes; - jmethodID m_setInstallableWebApp; - jmethodID m_enterFullscreenForVideoLayer; - jmethodID m_setWebTextViewAutoFillable; - jmethodID m_selectAt; - AutoJObject object(JNIEnv* env) { - return getRealObject(env, m_obj); - } -}; - -/* - * WebViewCore Implementation - */ - -static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) -{ - jmethodID m = env->GetMethodID(clazz, name, signature); - LOG_ASSERT(m, "Could not find method %s", name); - return m; -} - -Mutex WebViewCore::gFrameCacheMutex; -Mutex WebViewCore::gButtonMutex; -Mutex WebViewCore::gCursorBoundsMutex; - -WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* mainframe) - : m_pluginInvalTimer(this, &WebViewCore::pluginInvalTimerFired) - , m_deviceMotionAndOrientationManager(this) -{ - m_mainFrame = mainframe; - - m_popupReply = 0; - m_moveGeneration = 0; - m_lastGeneration = 0; - m_touchGeneration = 0; - m_blockTextfieldUpdates = false; - // just initial values. These should be set by client - m_maxXScroll = 320/4; - m_maxYScroll = 240/4; - m_textGeneration = 0; - m_screenWidth = 320; - m_textWrapWidth = 320; - m_scale = 1; -#if ENABLE(TOUCH_EVENTS) - m_forwardingTouchEvents = false; -#endif - m_isPaused = false; - m_screenOnCounter = 0; - m_shouldPaintCaret = true; - - LOG_ASSERT(m_mainFrame, "Uh oh, somehow a frameview was made without an initial frame!"); - - jclass clazz = env->GetObjectClass(javaWebViewCore); - m_javaGlue = new JavaGlue; - m_javaGlue->m_obj = env->NewWeakGlobalRef(javaWebViewCore); - m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(IIZZ)V"); - m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V"); - m_javaGlue->m_layersDraw = GetJMethod(env, clazz, "layersDraw", "()V"); - m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[I[I)V"); - m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "(Ljava/lang/String;)Ljava/lang/String;"); - m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[II)V"); - m_javaGlue->m_jsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); - m_javaGlue->m_jsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z"); - m_javaGlue->m_jsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - m_javaGlue->m_jsUnload = GetJMethod(env, clazz, "jsUnload", "(Ljava/lang/String;Ljava/lang/String;)Z"); - m_javaGlue->m_jsInterrupt = GetJMethod(env, clazz, "jsInterrupt", "()Z"); - m_javaGlue->m_didFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Z)V"); - 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_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V"); - m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); - m_javaGlue->m_restoreScale = GetJMethod(env, clazz, "restoreScale", "(FF)V"); - m_javaGlue->m_needTouchEvents = GetJMethod(env, clazz, "needTouchEvents", "(Z)V"); - m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V"); - m_javaGlue->m_requestKeyboardWithSelection = GetJMethod(env, clazz, "requestKeyboardWithSelection", "(IIII)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_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"); - m_javaGlue->m_getDeviceMotionService = GetJMethod(env, clazz, "getDeviceMotionService", "()Landroid/webkit/DeviceMotionService;"); - m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;"); - m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V"); - m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V"); - m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"); - m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;I)V"); - m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V"); - m_javaGlue->m_createSurface = GetJMethod(env, clazz, "createSurface", "(Landroid/view/View;)Landroid/webkit/ViewManager$ChildView;"); - m_javaGlue->m_addSurface = GetJMethod(env, clazz, "addSurface", "(Landroid/view/View;IIII)Landroid/webkit/ViewManager$ChildView;"); - m_javaGlue->m_updateSurface = GetJMethod(env, clazz, "updateSurface", "(Landroid/webkit/ViewManager$ChildView;IIII)V"); - m_javaGlue->m_destroySurface = GetJMethod(env, clazz, "destroySurface", "(Landroid/webkit/ViewManager$ChildView;)V"); - m_javaGlue->m_getContext = GetJMethod(env, clazz, "getContext", "()Landroid/content/Context;"); - m_javaGlue->m_keepScreenOn = GetJMethod(env, clazz, "keepScreenOn", "(Z)V"); - m_javaGlue->m_sendFindAgain = GetJMethod(env, clazz, "sendFindAgain", "()V"); - 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"); -#endif - m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); - m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V"); - env->DeleteLocalRef(clazz); - - env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this); - - m_scrollOffsetX = m_scrollOffsetY = 0; - - PageGroup::setShouldTrackVisitedLinks(true); - - reset(true); - - MemoryUsage::setLowMemoryUsageMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_lowMemoryUsageMb)); - MemoryUsage::setHighMemoryUsageMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_highMemoryUsageMb)); - MemoryUsage::setHighUsageDeltaMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_highUsageDeltaMb)); - - WebViewCore::addInstance(this); - -#if USE(CHROME_NETWORK_STACK) - AndroidNetworkLibraryImpl::InitWithApplicationContext(env, 0); -#endif -} - -WebViewCore::~WebViewCore() -{ - WebViewCore::removeInstance(this); - - // Release the focused view - Release(m_popupReply); - - if (m_javaGlue->m_obj) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->DeleteWeakGlobalRef(m_javaGlue->m_obj); - m_javaGlue->m_obj = 0; - } - delete m_javaGlue; - delete m_frameCacheKit; - delete m_navPictureKit; -} - -WebViewCore* WebViewCore::getWebViewCore(const WebCore::FrameView* view) -{ - return getWebViewCore(static_cast<const WebCore::ScrollView*>(view)); -} - -WebViewCore* WebViewCore::getWebViewCore(const WebCore::ScrollView* view) -{ - if (!view) - return 0; - - WebFrameView* webFrameView = static_cast<WebFrameView*>(view->platformWidget()); - if (!webFrameView) - return 0; - return webFrameView->webViewCore(); -} - -void WebViewCore::reset(bool fromConstructor) -{ - DBG_SET_LOG(""); - if (fromConstructor) { - m_frameCacheKit = 0; - m_navPictureKit = 0; - } else { - gFrameCacheMutex.lock(); - delete m_frameCacheKit; - delete m_navPictureKit; - m_frameCacheKit = 0; - m_navPictureKit = 0; - gFrameCacheMutex.unlock(); - } - - m_lastFocused = 0; - m_blurringNodePointer = 0; - m_lastFocusedBounds = WebCore::IntRect(0,0,0,0); - m_focusBoundsChanged = false; - m_lastFocusedSelStart = 0; - m_lastFocusedSelEnd = 0; - clearContent(); - m_updatedFrameCache = true; - m_frameCacheOutOfDate = true; - m_skipContentDraw = false; - m_findIsUp = false; - m_domtree_version = 0; - m_check_domtree_version = true; - m_progressDone = false; - m_hasCursorBounds = false; - - m_scrollOffsetX = 0; - m_scrollOffsetY = 0; - m_screenWidth = 0; - m_screenHeight = 0; - m_groupForVisitedLinks = 0; - m_currentNodeDomNavigationAxis = 0; -} - -static bool layoutIfNeededRecursive(WebCore::Frame* f) -{ - if (!f) - return true; - - WebCore::FrameView* v = f->view(); - if (!v) - return true; - - if (v->needsLayout()) - v->layout(f->tree()->parent()); - - WebCore::Frame* child = f->tree()->firstChild(); - bool success = true; - while (child) { - success &= layoutIfNeededRecursive(child); - child = child->tree()->nextSibling(); - } - - return success && !v->needsLayout(); -} - -CacheBuilder& WebViewCore::cacheBuilder() -{ - return FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder(); -} - -WebCore::Node* WebViewCore::currentFocus() -{ - return cacheBuilder().currentFocus(); -} - -void WebViewCore::recordPicture(SkPicture* picture) -{ - // if there is no document yet, just return - if (!m_mainFrame->document()) { - DBG_NAV_LOG("no document"); - return; - } - // Call layout to ensure that the contentWidth and contentHeight are correct - if (!layoutIfNeededRecursive(m_mainFrame)) { - DBG_NAV_LOG("layout failed"); - return; - } - // draw into the picture's recording canvas - WebCore::FrameView* view = m_mainFrame->view(); - DBG_NAV_LOGD("view=(w=%d,h=%d)", view->contentsWidth(), - view->contentsHeight()); - SkAutoPictureRecord arp(picture, view->contentsWidth(), - view->contentsHeight(), PICT_RECORD_FLAGS); - SkAutoMemoryUsageProbe mup(__FUNCTION__); - - // Copy m_buttons so we can pass it to our graphics context. - gButtonMutex.lock(); - WTF::Vector<Container> buttons(m_buttons); - gButtonMutex.unlock(); - - WebCore::PlatformGraphicsContext pgc(arp.getRecordingCanvas(), &buttons); - WebCore::GraphicsContext gc(&pgc); - view->platformWidget()->draw(&gc, WebCore::IntRect(0, 0, - view->contentsWidth(), view->contentsHeight())); - - gButtonMutex.lock(); - updateButtonList(&buttons); - gButtonMutex.unlock(); -} - -void WebViewCore::recordPictureSet(PictureSet* content) -{ - // if there is no document yet, just return - if (!m_mainFrame->document()) { - DBG_SET_LOG("!m_mainFrame->document()"); - return; - } - // If there is a pending style recalculation, just return. - if (m_mainFrame->document()->isPendingStyleRecalc()) { - LOGW("recordPictureSet: pending style recalc, ignoring."); - return; - } - if (m_addInval.isEmpty()) { - DBG_SET_LOG("m_addInval.isEmpty()"); - return; - } - // Call layout to ensure that the contentWidth and contentHeight are correct - // it's fine for layout to gather invalidates, but defeat sending a message - // back to java to call webkitDraw, since we're already in the middle of - // doing that - m_skipContentDraw = true; - bool success = layoutIfNeededRecursive(m_mainFrame); - m_skipContentDraw = false; - - // We may be mid-layout and thus cannot draw. - if (!success) - return; - - { // collect WebViewCoreRecordTimeCounter after layoutIfNeededRecursive -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreRecordTimeCounter); -#endif - - // if the webkit page dimensions changed, discard the pictureset and redraw. - WebCore::FrameView* view = m_mainFrame->view(); - int width = view->contentsWidth(); - int height = view->contentsHeight(); - - // Use the contents width and height as a starting point. - SkIRect contentRect; - contentRect.set(0, 0, width, height); - SkIRect total(contentRect); - - // Traverse all the frames and add their sizes if they are in the visible - // rectangle. - for (WebCore::Frame* frame = m_mainFrame->tree()->traverseNext(); frame; - frame = frame->tree()->traverseNext()) { - // If the frame doesn't have an owner then it is the top frame and the - // view size is the frame size. - WebCore::RenderPart* owner = frame->ownerRenderer(); - if (owner && owner->style()->visibility() == VISIBLE) { - int x = owner->x(); - int y = owner->y(); - - // Traverse the tree up to the parent to find the absolute position - // of this frame. - WebCore::Frame* parent = frame->tree()->parent(); - while (parent) { - WebCore::RenderPart* parentOwner = parent->ownerRenderer(); - if (parentOwner) { - x += parentOwner->x(); - y += parentOwner->y(); - } - parent = parent->tree()->parent(); - } - // Use the owner dimensions so that padding and border are - // included. - int right = x + owner->width(); - int bottom = y + owner->height(); - SkIRect frameRect = {x, y, right, bottom}; - // Ignore a width or height that is smaller than 1. Some iframes - // have small dimensions in order to be hidden. The iframe - // expansion code does not expand in that case so we should ignore - // them here. - if (frameRect.width() > 1 && frameRect.height() > 1 - && SkIRect::Intersects(total, frameRect)) - total.join(x, y, right, bottom); - } - } - - // If the new total is larger than the content, resize the view to include - // all the content. - if (!contentRect.contains(total)) { - // Resize the view to change the overflow clip. - view->resize(total.fRight, total.fBottom); - - // We have to force a layout in order for the clip to change. - m_mainFrame->contentRenderer()->setNeedsLayoutAndPrefWidthsRecalc(); - view->forceLayout(); - - // Relayout similar to above - m_skipContentDraw = true; - bool success = layoutIfNeededRecursive(m_mainFrame); - m_skipContentDraw = false; - if (!success) - return; - - // Set the computed content width - width = view->contentsWidth(); - height = view->contentsHeight(); - } - - if (cacheBuilder().pictureSetDisabled()) - content->clear(); - - content->checkDimensions(width, height, &m_addInval); - - // The inval region may replace existing pictures. The existing pictures - // may have already been split into pieces. If reuseSubdivided() returns - // true, the split pieces are the last entries in the picture already. They - // are marked as invalid, and are rebuilt by rebuildPictureSet(). - - // If the new region doesn't match a set of split pieces, add it to the end. - if (!content->reuseSubdivided(m_addInval)) { - const SkIRect& inval = m_addInval.getBounds(); - SkPicture* picture = rebuildPicture(inval); - DBG_SET_LOGD("{%d,%d,w=%d,h=%d}", inval.fLeft, - inval.fTop, inval.width(), inval.height()); - content->add(m_addInval, picture, 0, false); - SkSafeUnref(picture); - } - // Remove any pictures already in the set that are obscured by the new one, - // and check to see if any already split pieces need to be redrawn. - if (content->build()) - rebuildPictureSet(content); - } // WebViewCoreRecordTimeCounter - WebCore::Node* oldFocusNode = currentFocus(); - m_frameCacheOutOfDate = true; - WebCore::IntRect oldBounds; - int oldSelStart = 0; - int oldSelEnd = 0; - if (oldFocusNode) { - oldBounds = oldFocusNode->getRect(); - RenderObject* renderer = oldFocusNode->renderer(); - if (renderer && (renderer->isTextArea() || renderer->isTextField())) { - WebCore::RenderTextControl* rtc = - static_cast<WebCore::RenderTextControl*>(renderer); - oldSelStart = rtc->selectionStart(); - oldSelEnd = rtc->selectionEnd(); - } - } else - oldBounds = WebCore::IntRect(0,0,0,0); - unsigned latestVersion = 0; - if (m_check_domtree_version) { - // as domTreeVersion only increment, we can just check the sum to see - // whether we need to update the frame cache - for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) { - const Document* doc = frame->document(); - latestVersion += doc->domTreeVersion() + doc->styleVersion(); - } - } - DBG_NAV_LOGD("m_lastFocused=%p oldFocusNode=%p" - " m_lastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}" - " m_lastFocusedSelection={%d,%d} oldSelection={%d,%d}" - " m_check_domtree_version=%s latestVersion=%d m_domtree_version=%d", - m_lastFocused, oldFocusNode, - m_lastFocusedBounds.x(), m_lastFocusedBounds.y(), - m_lastFocusedBounds.width(), m_lastFocusedBounds.height(), - oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height(), - m_lastFocusedSelStart, m_lastFocusedSelEnd, oldSelStart, oldSelEnd, - m_check_domtree_version ? "true" : "false", - latestVersion, m_domtree_version); - if (m_lastFocused == oldFocusNode && m_lastFocusedBounds == oldBounds - && m_lastFocusedSelStart == oldSelStart - && m_lastFocusedSelEnd == oldSelEnd - && !m_findIsUp - && (!m_check_domtree_version || latestVersion == m_domtree_version)) - { - return; - } - m_focusBoundsChanged |= m_lastFocused == oldFocusNode - && m_lastFocusedBounds != oldBounds; - m_lastFocused = oldFocusNode; - m_lastFocusedBounds = oldBounds; - m_lastFocusedSelStart = oldSelStart; - m_lastFocusedSelEnd = oldSelEnd; - m_domtree_version = latestVersion; - DBG_NAV_LOG("call updateFrameCache"); - updateFrameCache(); - if (m_findIsUp) { - LOG_ASSERT(m_javaGlue->m_obj, - "A Java widget was not associated with this view bridge!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_sendFindAgain); - checkException(env); - } -} - -void WebViewCore::updateButtonList(WTF::Vector<Container>* buttons) -{ - // All the entries in buttons are either updates of previous entries in - // m_buttons or they need to be added to it. - Container* end = buttons->end(); - for (Container* updatedContainer = buttons->begin(); - updatedContainer != end; updatedContainer++) { - bool updated = false; - // Search for a previous entry that references the same node as our new - // data - Container* lastPossibleMatch = m_buttons.end(); - for (Container* possibleMatch = m_buttons.begin(); - possibleMatch != lastPossibleMatch; possibleMatch++) { - if (updatedContainer->matches(possibleMatch->node())) { - // Update our record, and skip to the next one. - possibleMatch->setRect(updatedContainer->rect()); - updated = true; - break; - } - } - if (!updated) { - // This is a brand new button, so append it to m_buttons - m_buttons.append(*updatedContainer); - } - } - size_t i = 0; - // count will decrease each time one is removed, so check count each time. - while (i < m_buttons.size()) { - if (m_buttons[i].canBeRemoved()) { - m_buttons[i] = m_buttons.last(); - m_buttons.removeLast(); - } else { - i++; - } - } -} - -// note: updateCursorBounds is called directly by the WebView thread -// This needs to be called each time we call CachedRoot::setCursor() with -// non-null CachedNode/CachedFrame, since otherwise the WebViewCore's data -// about the cursor is incorrect. When we call setCursor(0,0), we need -// to set hasCursorBounds to false. -void WebViewCore::updateCursorBounds(const CachedRoot* root, - const CachedFrame* cachedFrame, const CachedNode* cachedNode) -{ - LOG_ASSERT(root, "updateCursorBounds: root cannot be null"); - LOG_ASSERT(cachedNode, "updateCursorBounds: cachedNode cannot be null"); - LOG_ASSERT(cachedFrame, "updateCursorBounds: cachedFrame cannot be null"); - gCursorBoundsMutex.lock(); - m_hasCursorBounds = !cachedNode->isHidden(); - // If m_hasCursorBounds is false, we never look at the other - // values, so do not bother setting them. - if (m_hasCursorBounds) { - WebCore::IntRect bounds = cachedNode->bounds(cachedFrame); - if (m_cursorBounds != bounds) - DBG_NAV_LOGD("new cursor bounds=(%d,%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); - m_cursorBounds = bounds; - m_cursorHitBounds = cachedNode->hitBounds(cachedFrame); - m_cursorFrame = cachedFrame->framePointer(); - root->getSimulatedMousePosition(&m_cursorLocation); - m_cursorNode = cachedNode->nodePointer(); - } - gCursorBoundsMutex.unlock(); -} - -void WebViewCore::clearContent() -{ - DBG_SET_LOG(""); - m_content.clear(); - m_addInval.setEmpty(); - m_rebuildInval.setEmpty(); -} - -bool WebViewCore::focusBoundsChanged() -{ - bool result = m_focusBoundsChanged; - m_focusBoundsChanged = false; - return result; -} - -SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) -{ - WebCore::FrameView* view = m_mainFrame->view(); - int width = view->contentsWidth(); - int height = view->contentsHeight(); - SkPicture* picture = new SkPicture(); - SkAutoPictureRecord arp(picture, width, height, PICT_RECORD_FLAGS); - SkAutoMemoryUsageProbe mup(__FUNCTION__); - SkCanvas* recordingCanvas = arp.getRecordingCanvas(); - - gButtonMutex.lock(); - WTF::Vector<Container> buttons(m_buttons); - gButtonMutex.unlock(); - - WebCore::PlatformGraphicsContext pgc(recordingCanvas, &buttons); - WebCore::GraphicsContext gc(&pgc); - recordingCanvas->translate(-inval.fLeft, -inval.fTop); - recordingCanvas->save(); - view->platformWidget()->draw(&gc, WebCore::IntRect(inval.fLeft, - inval.fTop, inval.width(), inval.height())); - m_rebuildInval.op(inval, SkRegion::kUnion_Op); - DBG_SET_LOGD("m_rebuildInval={%d,%d,r=%d,b=%d}", - m_rebuildInval.getBounds().fLeft, m_rebuildInval.getBounds().fTop, - m_rebuildInval.getBounds().fRight, m_rebuildInval.getBounds().fBottom); - - gButtonMutex.lock(); - updateButtonList(&buttons); - gButtonMutex.unlock(); - - return picture; -} - -void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) -{ - WebCore::FrameView* view = m_mainFrame->view(); - size_t size = pictureSet->size(); - for (size_t index = 0; index < size; index++) { - if (pictureSet->upToDate(index)) - continue; - const SkIRect& inval = pictureSet->bounds(index); - DBG_SET_LOGD("pictSet=%p [%d] {%d,%d,w=%d,h=%d}", pictureSet, index, - inval.fLeft, inval.fTop, inval.width(), inval.height()); - pictureSet->setPicture(index, rebuildPicture(inval)); - } - pictureSet->validate(__FUNCTION__); -} - -BaseLayerAndroid* WebViewCore::createBaseLayer() -{ - BaseLayerAndroid* base = new BaseLayerAndroid(); - base->setContent(m_content); - - bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame); - // Layout only fails if called during a layout. - LOG_ASSERT(layoutSucceeded, "Can never be called recursively"); - -#if USE(ACCELERATED_COMPOSITING) - // We set the background color - if (m_mainFrame && m_mainFrame->document() - && m_mainFrame->document()->body()) { - Document* document = m_mainFrame->document(); - RefPtr<RenderStyle> style = document->styleForElementIgnoringPendingStylesheets(document->body()); - if (style->hasBackground()) { - Color color = style->visitedDependentColor(CSSPropertyBackgroundColor); - if (color.isValid() && color.alpha() > 0) - base->setBackgroundColor(color); - } - } - - // We update the layers - ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); - GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync()); - if (root) { - root->notifyClientAnimationStarted(); - LayerAndroid* copyLayer = new LayerAndroid(*root->contentLayer()); - base->addChild(copyLayer); - copyLayer->unref(); - } -#endif - - return base; -} - -BaseLayerAndroid* WebViewCore::recordContent(SkRegion* region, SkIPoint* point) -{ - DBG_SET_LOG("start"); - float progress = (float) m_mainFrame->page()->progress()->estimatedProgress(); - m_progressDone = progress <= 0.0f || progress >= 1.0f; - recordPictureSet(&m_content); - if (!m_progressDone && m_content.isEmpty()) { - DBG_SET_LOGD("empty (progress=%g)", progress); - return 0; - } - region->set(m_addInval); - m_addInval.setEmpty(); - region->op(m_rebuildInval, SkRegion::kUnion_Op); - m_rebuildInval.setEmpty(); - point->fX = m_content.width(); - point->fY = m_content.height(); - DBG_SET_LOGD("region={%d,%d,r=%d,b=%d}", region->getBounds().fLeft, - region->getBounds().fTop, region->getBounds().fRight, - region->getBounds().fBottom); - DBG_SET_LOG("end"); - - return createBaseLayer(); -} - -void WebViewCore::splitContent(PictureSet* content) -{ - bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame); - LOG_ASSERT(layoutSucceeded, "Can never be called recursively"); - content->split(&m_content); - rebuildPictureSet(&m_content); - content->set(m_content); -} - -void WebViewCore::scrollTo(int x, int y, bool animate) -{ - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - -// LOGD("WebViewCore::scrollTo(%d %d)\n", x, y); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollTo, - x, y, animate, false); - checkException(env); -} - -void WebViewCore::sendNotifyProgressFinished() -{ - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendNotifyProgressFinished); - checkException(env); -} - -void WebViewCore::viewInvalidate(const WebCore::IntRect& rect) -{ - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_sendViewInvalidate, - rect.x(), rect.y(), rect.right(), rect.bottom()); - checkException(env); -} - -void WebViewCore::contentDraw() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_contentDraw); - checkException(env); -} - -void WebViewCore::layersDraw() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_layersDraw); - checkException(env); -} - -void WebViewCore::contentInvalidate(const WebCore::IntRect &r) -{ - DBG_SET_LOGD("rect={%d,%d,w=%d,h=%d}", r.x(), r.y(), r.width(), r.height()); - SkIRect rect(r); - if (!rect.intersect(0, 0, INT_MAX, INT_MAX)) - return; - m_addInval.op(rect, SkRegion::kUnion_Op); - DBG_SET_LOGD("m_addInval={%d,%d,r=%d,b=%d}", - m_addInval.getBounds().fLeft, m_addInval.getBounds().fTop, - m_addInval.getBounds().fRight, m_addInval.getBounds().fBottom); - if (!m_skipContentDraw) - contentDraw(); -} - -void WebViewCore::contentInvalidateAll() -{ - WebCore::FrameView* view = m_mainFrame->view(); - contentInvalidate(WebCore::IntRect(0, 0, - view->contentsWidth(), view->contentsHeight())); -} - -void WebViewCore::offInvalidate(const WebCore::IntRect &r) -{ - // FIXME: these invalidates are offscreen, and can be throttled or - // deferred until the area is visible. For now, treat them as - // regular invals so that drawing happens (inefficiently) for now. - contentInvalidate(r); -} - -static int pin_pos(int x, int width, int targetWidth) -{ - if (x + width > targetWidth) - x = targetWidth - width; - if (x < 0) - x = 0; - return x; -} - -void WebViewCore::didFirstLayout() -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - - WebCore::FrameLoader* loader = m_mainFrame->loader(); - const WebCore::KURL& url = loader->url(); - if (url.isEmpty()) - return; - LOGV("::WebCore:: didFirstLayout %s", url.string().ascii().data()); - - WebCore::FrameLoadType loadType = loader->loadType(); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_didFirstLayout, - loadType == WebCore::FrameLoadTypeStandard - // When redirect with locked history, we would like to reset the - // scale factor. This is important for www.yahoo.com as it is - // redirected to www.yahoo.com/?rs=1 on load. - || loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList); - checkException(env); - - DBG_NAV_LOG("call updateFrameCache"); - m_check_domtree_version = false; - updateFrameCache(); - m_history.setDidFirstLayout(true); -} - -void WebViewCore::updateViewport() -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateViewport); - checkException(env); -} - -void WebViewCore::restoreScale(float scale, float textWrapScale) -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_restoreScale, scale, textWrapScale); - checkException(env); -} - -void WebViewCore::needTouchEvents(bool need) -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - -#if ENABLE(TOUCH_EVENTS) - if (m_forwardingTouchEvents == need) - return; - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_needTouchEvents, need); - checkException(env); - - m_forwardingTouchEvents = need; -#endif -} - -void WebViewCore::requestKeyboardWithSelection(const WebCore::Node* node, - int selStart, int selEnd) -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_requestKeyboardWithSelection, - reinterpret_cast<int>(node), selStart, selEnd, m_textGeneration); - checkException(env); -} - -void WebViewCore::requestKeyboard(bool showKeyboard) -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_requestKeyboard, showKeyboard); - checkException(env); -} - -void WebViewCore::notifyProgressFinished() -{ - m_check_domtree_version = true; - sendNotifyProgressFinished(); -} - -void WebViewCore::doMaxScroll(CacheBuilder::Direction dir) -{ - int dx = 0, dy = 0; - - switch (dir) { - case CacheBuilder::LEFT: - dx = -m_maxXScroll; - break; - case CacheBuilder::UP: - dy = -m_maxYScroll; - break; - case CacheBuilder::RIGHT: - dx = m_maxXScroll; - break; - case CacheBuilder::DOWN: - dy = m_maxYScroll; - break; - case CacheBuilder::UNINITIALIZED: - default: - LOG_ASSERT(0, "unexpected focus selector"); - } - WebCore::FrameView* view = m_mainFrame->view(); - this->scrollTo(view->scrollX() + dx, view->scrollY() + dy, true); -} - -void WebViewCore::setScrollOffset(int moveGeneration, bool sendScrollEvent, int dx, int dy) -{ - DBG_NAV_LOGD("{%d,%d} m_scrollOffset=(%d,%d), sendScrollEvent=%d", dx, dy, - m_scrollOffsetX, m_scrollOffsetY, sendScrollEvent); - if (m_scrollOffsetX != dx || m_scrollOffsetY != dy) { - m_scrollOffsetX = dx; - m_scrollOffsetY = dy; - // The visible rect is located within our coordinate space so it - // contains the actual scroll position. Setting the location makes hit - // testing work correctly. - m_mainFrame->view()->platformWidget()->setLocation(m_scrollOffsetX, - m_scrollOffsetY); - if (sendScrollEvent) { - m_mainFrame->eventHandler()->sendScrollEvent(); - - // Only update history position if it's user scrolled. - // Update history item to reflect the new scroll position. - // This also helps save the history information when the browser goes to - // background, so scroll position will be restored if browser gets - // killed while in background. - WebCore::HistoryController* history = m_mainFrame->loader()->history(); - // Because the history item saving could be heavy for large sites and - // scrolling can generate lots of small scroll offset, the following code - // reduces the saving frequency. - static const int MIN_SCROLL_DIFF = 32; - if (history->currentItem()) { - WebCore::IntPoint currentPoint = history->currentItem()->scrollPoint(); - if (std::abs(currentPoint.x() - dx) >= MIN_SCROLL_DIFF || - std::abs(currentPoint.y() - dy) >= MIN_SCROLL_DIFF) { - history->saveScrollPositionAndViewStateToItem(history->currentItem()); - } - } - } - - // update the currently visible screen - sendPluginVisibleScreen(); - } - gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_hasCursorBounds; - Frame* frame = (Frame*) m_cursorFrame; - IntPoint location = m_cursorLocation; - gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return; - moveMouseIfLatest(moveGeneration, frame, location.x(), location.y()); -} - -void WebViewCore::setGlobalBounds(int x, int y, int h, int v) -{ - DBG_NAV_LOGD("{%d,%d}", x, y); - m_mainFrame->view()->platformWidget()->setWindowBounds(x, y, h, v); -} - -void WebViewCore::setSizeScreenWidthAndScale(int width, int height, - int textWrapWidth, float scale, int screenWidth, int screenHeight, - int anchorX, int anchorY, bool ignoreHeight) -{ - WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); - int ow = window->width(); - int oh = window->height(); - int osw = m_screenWidth; - int osh = m_screenHeight; - int otw = m_textWrapWidth; - float oldScale = m_scale; - DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%g) new:(w=%d,h=%d,sw=%d,scale=%g)", - ow, oh, osw, m_scale, width, height, screenWidth, scale); - m_screenWidth = screenWidth; - m_screenHeight = screenHeight; - m_textWrapWidth = textWrapWidth; - if (scale >= 0) // negative means keep the current scale - m_scale = scale; - m_maxXScroll = screenWidth >> 2; - m_maxYScroll = m_maxXScroll * height / width; - // Don't reflow if the diff is small. - const bool reflow = otw && textWrapWidth && - ((float) abs(otw - textWrapWidth) / textWrapWidth) >= 0.01f; - - // When the screen size change, fixed positioned element should be updated. - // This is supposed to be light weighted operation without a full layout. - if (osh != screenHeight || osw != screenWidth) - m_mainFrame->view()->updatePositionedObjects(); - - if (ow != width || (!ignoreHeight && oh != height) || reflow) { - WebCore::RenderObject *r = m_mainFrame->contentRenderer(); - DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r, - screenWidth, screenHeight); - if (r) { - WebCore::IntPoint anchorPoint = WebCore::IntPoint(anchorX, anchorY); - DBG_NAV_LOGD("anchorX=%d anchorY=%d", anchorX, anchorY); - RefPtr<WebCore::Node> node; - WebCore::IntRect bounds; - WebCore::IntPoint offset; - // If the text wrap changed, it is probably zoom change or - // orientation change. Try to keep the anchor at the same place. - if (otw && textWrapWidth && otw != textWrapWidth && - (anchorX != 0 || anchorY != 0)) { - WebCore::HitTestResult hitTestResult = - m_mainFrame->eventHandler()->hitTestResultAtPoint( - anchorPoint, false); - node = hitTestResult.innerNode(); - } - if (node) { - bounds = node->getRect(); - DBG_NAV_LOGD("ob:(x=%d,y=%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); - // sites like nytimes.com insert a non-standard tag <nyt_text> - // in the html. If it is the HitTestResult, it may have zero - // width and height. In this case, use its parent node. - if (bounds.width() == 0) { - node = node->parentOrHostNode(); - if (node) { - bounds = node->getRect(); - DBG_NAV_LOGD("found a zero width node and use its parent, whose ob:(x=%d,y=%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); - } - } - } - - // Set the size after finding the old anchor point as - // hitTestResultAtPoint causes a layout. - window->setSize(width, height); - window->setVisibleSize(screenWidth, screenHeight); - if (width != screenWidth) { - m_mainFrame->view()->setUseFixedLayout(true); - m_mainFrame->view()->setFixedLayoutSize(IntSize(width, height)); - } else { - m_mainFrame->view()->setUseFixedLayout(false); - } - r->setNeedsLayoutAndPrefWidthsRecalc(); - m_mainFrame->view()->forceLayout(); - - // scroll to restore current screen center - if (node) { - const WebCore::IntRect& newBounds = node->getRect(); - DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d," - "h=%d)", newBounds.x(), newBounds.y(), - newBounds.width(), newBounds.height()); - if ((osw && osh && bounds.width() && bounds.height()) - && (bounds != newBounds)) { - WebCore::FrameView* view = m_mainFrame->view(); - // force left align if width is not changed while height changed. - // the anchorPoint is probably at some white space in the node - // which is affected by text wrap around the screen width. - const bool leftAlign = (otw != textWrapWidth) - && (bounds.width() == newBounds.width()) - && (bounds.height() != newBounds.height()); - const float xPercentInDoc = - leftAlign ? 0.0 : (float) (anchorX - bounds.x()) / bounds.width(); - const float xPercentInView = - leftAlign ? 0.0 : (float) (anchorX - m_scrollOffsetX) / osw; - const float yPercentInDoc = (float) (anchorY - bounds.y()) / bounds.height(); - const float yPercentInView = (float) (anchorY - m_scrollOffsetY) / osh; - showRect(newBounds.x(), newBounds.y(), newBounds.width(), - newBounds.height(), view->contentsWidth(), - view->contentsHeight(), - xPercentInDoc, xPercentInView, - yPercentInDoc, yPercentInView); - } - } - } - } else { - window->setSize(width, height); - window->setVisibleSize(screenWidth, screenHeight); - m_mainFrame->view()->resize(width, height); - if (width != screenWidth) { - m_mainFrame->view()->setUseFixedLayout(true); - m_mainFrame->view()->setFixedLayoutSize(IntSize(width, height)); - } else { - m_mainFrame->view()->setUseFixedLayout(false); - } - } - - // update the currently visible screen as perceived by the plugin - sendPluginVisibleScreen(); -} - -void WebViewCore::dumpDomTree(bool useFile) -{ -#ifdef ANDROID_DOM_LOGGING - if (useFile) - gDomTreeFile = fopen(DOM_TREE_LOG_FILE, "w"); - m_mainFrame->document()->showTreeForThis(); - if (gDomTreeFile) { - fclose(gDomTreeFile); - gDomTreeFile = 0; - } -#endif -} - -void WebViewCore::dumpRenderTree(bool useFile) -{ -#ifdef ANDROID_DOM_LOGGING - WTF::CString renderDump = WebCore::externalRepresentation(m_mainFrame).utf8(); - const char* data = renderDump.data(); - if (useFile) { - gRenderTreeFile = fopen(RENDER_TREE_LOG_FILE, "w"); - DUMP_RENDER_LOGD("%s", data); - fclose(gRenderTreeFile); - gRenderTreeFile = 0; - } else { - // adb log can only output 1024 characters, so write out line by line. - // exclude '\n' as adb log adds it for each output. - int length = renderDump.length(); - for (int i = 0, last = 0; i < length; i++) { - if (data[i] == '\n') { - if (i != last) - DUMP_RENDER_LOGD("%.*s", (i - last), &(data[last])); - last = i + 1; - } - } - } -#endif -} - -void WebViewCore::dumpNavTree() -{ -#if DUMP_NAV_CACHE - cacheBuilder().mDebug.print(); -#endif -} - -HTMLElement* WebViewCore::retrieveElement(int x, int y, - const QualifiedName& tagName) -{ - HitTestResult hitTestResult = m_mainFrame->eventHandler() - ->hitTestResultAtPoint(IntPoint(x, y), false, false, - DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, - IntSize(1, 1)); - if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) { - LOGE("Should not happen: no in document Node found"); - return 0; - } - const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult(); - if (list.isEmpty()) { - LOGE("Should not happen: no rect-based-test nodes found"); - return 0; - } - Node* node = hitTestResult.innerNode(); - Node* element = node; - while (element && (!element->isElementNode() - || !element->hasTagName(tagName))) { - element = element->parentNode(); - } - DBG_NAV_LOGD("node=%p element=%p x=%d y=%d nodeName=%s tagName=%s", node, - element, x, y, node->nodeName().utf8().data(), - element ? ((Element*) element)->tagName().utf8().data() : "<none>"); - return static_cast<WebCore::HTMLElement*>(element); -} - -HTMLAnchorElement* WebViewCore::retrieveAnchorElement(int x, int y) -{ - return static_cast<HTMLAnchorElement*> - (retrieveElement(x, y, HTMLNames::aTag)); -} - -HTMLImageElement* WebViewCore::retrieveImageElement(int x, int y) -{ - return static_cast<HTMLImageElement*> - (retrieveElement(x, y, HTMLNames::imgTag)); -} - -WTF::String WebViewCore::retrieveHref(int x, int y) -{ - WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(x, y); - return anchor ? anchor->href() : WTF::String(); -} - -WTF::String WebViewCore::retrieveAnchorText(int x, int y) -{ - WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(x, y); - return anchor ? anchor->text() : WTF::String(); -} - -WTF::String WebViewCore::retrieveImageSource(int x, int y) -{ - HTMLImageElement* image = retrieveImageElement(x, y); - return image ? image->src().string() : WTF::String(); -} - -WTF::String WebViewCore::requestLabel(WebCore::Frame* frame, - WebCore::Node* node) -{ - if (node && CacheBuilder::validNode(m_mainFrame, frame, node)) { - RefPtr<WebCore::NodeList> list = node->document()->getElementsByTagName("label"); - unsigned length = list->length(); - for (unsigned i = 0; i < length; i++) { - WebCore::HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>( - list->item(i)); - if (label->control() == node) { - Node* node = label; - String result; - while ((node = node->traverseNextNode(label))) { - if (node->isTextNode()) { - Text* textNode = static_cast<Text*>(node); - result += textNode->dataImpl(); - } - } - return result; - } - } - } - return WTF::String(); -} - -static bool isContentEditable(const WebCore::Node* node) -{ - if (!node) return false; - return node->document()->frame()->selection()->isContentEditable(); -} - -// Returns true if the node is a textfield, textarea, or contentEditable -static bool isTextInput(const WebCore::Node* node) -{ - if (isContentEditable(node)) - return true; - if (!node) - return false; - WebCore::RenderObject* renderer = node->renderer(); - return renderer && (renderer->isTextField() || renderer->isTextArea()); -} - -void WebViewCore::revealSelection() -{ - WebCore::Node* focus = currentFocus(); - if (!focus) - return; - if (!isTextInput(focus)) - return; - WebCore::Frame* focusedFrame = focus->document()->frame(); - if (!focusedFrame->page()->focusController()->isActive()) - return; - focusedFrame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); -} - -void WebViewCore::updateCacheOnNodeChange() -{ - gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_hasCursorBounds; - Frame* frame = (Frame*) m_cursorFrame; - Node* node = (Node*) m_cursorNode; - IntRect bounds = m_cursorHitBounds; - gCursorBoundsMutex.unlock(); - if (!hasCursorBounds || !node) - return; - if (CacheBuilder::validNode(m_mainFrame, frame, node)) { - RenderObject* renderer = node->renderer(); - if (renderer && renderer->style()->visibility() != HIDDEN) { - IntRect absBox = renderer->absoluteBoundingBoxRect(); - int globalX, globalY; - CacheBuilder::GetGlobalOffset(frame, &globalX, &globalY); - absBox.move(globalX, globalY); - if (absBox == bounds) - return; - DBG_NAV_LOGD("absBox=(%d,%d,%d,%d) bounds=(%d,%d,%d,%d)", - absBox.x(), absBox.y(), absBox.width(), absBox.height(), - bounds.x(), bounds.y(), bounds.width(), bounds.height()); - } - } - DBG_NAV_LOGD("updateFrameCache node=%p", node); - updateFrameCache(); -} - -void WebViewCore::updateFrameCache() -{ - if (!m_frameCacheOutOfDate) { - DBG_NAV_LOG("!m_frameCacheOutOfDate"); - return; - } - - // If there is a pending style recalculation, do not update the frame cache. - // Until the recalculation is complete, there may be internal objects that - // are in an inconsistent state (such as font pointers). - // In any event, there's not much point to updating the cache while a style - // recalculation is pending, since it will simply have to be updated again - // once the recalculation is complete. - // TODO: Do we need to reschedule an update for after the style is recalculated? - if (m_mainFrame && m_mainFrame->document() && m_mainFrame->document()->isPendingStyleRecalc()) { - LOGW("updateFrameCache: pending style recalc, ignoring."); - return; - } -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreBuildNavTimeCounter); -#endif - m_frameCacheOutOfDate = false; -#if DEBUG_NAV_UI - m_now = SkTime::GetMSecs(); -#endif - m_temp = new CachedRoot(); - m_temp->init(m_mainFrame, &m_history); -#if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* graphicsLayer = graphicsRootLayer(); - if (graphicsLayer) - m_temp->setRootLayer(graphicsLayer->contentLayer()); -#endif - CacheBuilder& builder = cacheBuilder(); - WebCore::Settings* settings = m_mainFrame->page()->settings(); - builder.allowAllTextDetection(); -#ifdef ANDROID_META_SUPPORT - if (settings) { - if (!settings->formatDetectionAddress()) - builder.disallowAddressDetection(); - if (!settings->formatDetectionEmail()) - builder.disallowEmailDetection(); - if (!settings->formatDetectionTelephone()) - builder.disallowPhoneDetection(); - } -#endif - builder.buildCache(m_temp); - m_tempPict = new SkPicture(); - recordPicture(m_tempPict); - m_temp->setPicture(m_tempPict); - m_temp->setTextGeneration(m_textGeneration); - WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); - m_temp->setVisibleRect(WebCore::IntRect(m_scrollOffsetX, - m_scrollOffsetY, window->width(), window->height())); - gFrameCacheMutex.lock(); - delete m_frameCacheKit; - delete m_navPictureKit; - m_frameCacheKit = m_temp; - m_navPictureKit = m_tempPict; - m_updatedFrameCache = true; -#if DEBUG_NAV_UI - const CachedNode* cachedFocusNode = m_frameCacheKit->currentFocus(); - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", - cachedFocusNode ? cachedFocusNode->index() : 0, - cachedFocusNode ? cachedFocusNode->nodePointer() : 0); -#endif - gFrameCacheMutex.unlock(); -} - -void WebViewCore::updateFrameCacheIfLoading() -{ - if (!m_check_domtree_version) - updateFrameCache(); -} - -struct TouchNodeData { - Node* mNode; - IntRect mBounds; -}; - -// get the bounding box of the Node -static IntRect getAbsoluteBoundingBox(Node* node) { - IntRect rect; - RenderObject* render = node->renderer(); - if (render->isRenderInline()) - rect = toRenderInline(render)->linesVisualOverflowBoundingBox(); - else if (render->isBox()) - rect = toRenderBox(render)->visualOverflowRect(); - else if (render->isText()) - rect = toRenderText(render)->linesBoundingBox(); - else - LOGE("getAbsoluteBoundingBox failed for node %p, name %s", node, render->renderName()); - FloatPoint absPos = render->localToAbsolute(); - rect.move(absPos.x(), absPos.y()); - return rect; -} - -// get the highlight rectangles for the touch point (x, y) with the slop -Vector<IntRect> WebViewCore::getTouchHighlightRects(int x, int y, int slop) -{ - Vector<IntRect> rects; - m_mousePos = IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY); - HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), - false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop)); - if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) { - LOGE("Should not happen: no in document Node found"); - return rects; - } - const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult(); - if (list.isEmpty()) { - LOGE("Should not happen: no rect-based-test nodes found"); - return rects; - } - Frame* frame = hitTestResult.innerNode()->document()->frame(); - Vector<TouchNodeData> nodeDataList; - ListHashSet<RefPtr<Node> >::const_iterator last = list.end(); - for (ListHashSet<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it) { - // TODO: it seems reasonable to not search across the frame. Isn't it? - // if the node is not in the same frame as the innerNode, skip it - if (it->get()->document()->frame() != frame) - continue; - // traverse up the tree to find the first node that needs highlight - bool found = false; - Node* eventNode = it->get(); - while (eventNode) { - RenderObject* render = eventNode->renderer(); - if (render->isBody() || render->isRenderView()) - break; - if (eventNode->supportsFocus() - || eventNode->hasEventListeners(eventNames().clickEvent) - || eventNode->hasEventListeners(eventNames().mousedownEvent) - || eventNode->hasEventListeners(eventNames().mouseupEvent)) { - found = true; - break; - } - // the nodes in the rectBasedTestResult() are ordered based on z-index during hit testing. - // so do not search for the eventNode across explicit z-index border. - // TODO: this is a hard one to call. z-index is quite complicated as its value only - // matters when you compare two RenderLayer in the same hierarchy level. e.g. in - // the following example, "b" is on the top as its z level is the highest. even "c" - // has 100 as z-index, it is still below "d" as its parent has the same z-index as - // "d" and logically before "d". Of course "a" is the lowest in the z level. - // - // z-index:auto "a" - // z-index:2 "b" - // z-index:1 - // z-index:100 "c" - // z-index:1 "d" - // - // If the fat point touches everyone, the order in the list should be "b", "d", "c" - // and "a". When we search for the event node for "b", we really don't want "a" as - // in the z-order it is behind everything else. - if (!render->style()->hasAutoZIndex()) - break; - eventNode = eventNode->parentNode(); - } - // didn't find any eventNode, skip it - if (!found) - continue; - // first quick check whether it is a duplicated node before computing bounding box - Vector<TouchNodeData>::const_iterator nlast = nodeDataList.end(); - for (Vector<TouchNodeData>::const_iterator n = nodeDataList.begin(); n != nlast; ++n) { - // found the same node, skip it - if (eventNode == n->mNode) { - found = false; - break; - } - } - if (!found) - continue; - // next check whether the node is fully covered by or fully covering another node. - found = false; - IntRect rect = getAbsoluteBoundingBox(eventNode); - if (rect.isEmpty()) { - // if the node's bounds is empty and it is not a ContainerNode, skip it. - if (!eventNode->isContainerNode()) - continue; - // if the node's children are all positioned objects, its bounds can be empty. - // Walk through the children to find the bounding box. - Node* child = static_cast<const ContainerNode*>(eventNode)->firstChild(); - while (child) { - IntRect childrect; - if (child->renderer()) - childrect = getAbsoluteBoundingBox(child); - if (!childrect.isEmpty()) { - rect.unite(childrect); - child = child->traverseNextSibling(eventNode); - } else - child = child->traverseNextNode(eventNode); - } - } - for (int i = nodeDataList.size() - 1; i >= 0; i--) { - TouchNodeData n = nodeDataList.at(i); - // the new node is enclosing an existing node, skip it - if (rect.contains(n.mBounds)) { - found = true; - break; - } - // the new node is fully inside an existing node, remove the existing node - if (n.mBounds.contains(rect)) - nodeDataList.remove(i); - } - if (!found) { - TouchNodeData newNode; - newNode.mNode = eventNode; - newNode.mBounds = rect; - nodeDataList.append(newNode); - } - } - if (!nodeDataList.size()) - return rects; - // finally select the node with the largest overlap with the fat point - TouchNodeData final; - final.mNode = 0; - IntPoint docPos = frame->view()->windowToContents(m_mousePos); - IntRect testRect(docPos.x() - slop, docPos.y() - slop, 2 * slop + 1, 2 * slop + 1); - int area = 0; - Vector<TouchNodeData>::const_iterator nlast = nodeDataList.end(); - for (Vector<TouchNodeData>::const_iterator n = nodeDataList.begin(); n != nlast; ++n) { - IntRect rect = n->mBounds; - rect.intersect(testRect); - int a = rect.width() * rect.height(); - if (a > area) { - final = *n; - area = a; - } - } - // now get the node's highlight rectangles in the page coordinate system - if (final.mNode) { - IntPoint frameAdjust; - if (frame != m_mainFrame) { - frameAdjust = frame->view()->contentsToWindow(IntPoint()); - frameAdjust.move(m_scrollOffsetX, m_scrollOffsetY); - } - if (final.mNode->isLink()) { - // most of the links are inline instead of box style. So the bounding box is not - // a good representation for the highlights. Get the list of rectangles instead. - RenderObject* render = final.mNode->renderer(); - IntPoint offset = roundedIntPoint(render->localToAbsolute()); - render->absoluteRects(rects, offset.x() + frameAdjust.x(), offset.y() + frameAdjust.y()); - bool inside = false; - int distance = INT_MAX; - int newx = x, newy = y; - int i = rects.size(); - while (i--) { - if (rects[i].isEmpty()) { - rects.remove(i); - continue; - } - // check whether the point (x, y) is inside one of the rectangles. - if (inside) - continue; - if (rects[i].contains(x, y)) { - inside = true; - continue; - } - if (x >= rects[i].x() && x < rects[i].right()) { - if (y < rects[i].y()) { - if (rects[i].y() - y < distance) { - newx = x; - newy = rects[i].y(); - distance = rects[i].y() - y; - } - } else if (y >= rects[i].bottom()) { - if (y - rects[i].bottom() + 1 < distance) { - newx = x; - newy = rects[i].bottom() - 1; - distance = y - rects[i].bottom() + 1; - } - } - } else if (y >= rects[i].y() && y < rects[i].bottom()) { - if (x < rects[i].x()) { - if (rects[i].x() - x < distance) { - newx = rects[i].x(); - newy = y; - distance = rects[i].x() - x; - } - } else if (x >= rects[i].right()) { - if (x - rects[i].right() + 1 < distance) { - newx = rects[i].right() - 1; - newy = y; - distance = x - rects[i].right() + 1; - } - } - } - } - if (!rects.isEmpty()) { - if (!inside) { - // if neither x nor y has overlap, just pick the top/left of the first rectangle - if (newx == x && newy == y) { - newx = rects[0].x(); - newy = rects[0].y(); - } - m_mousePos.setX(newx - m_scrollOffsetX); - m_mousePos.setY(newy - m_scrollOffsetY); - DBG_NAV_LOGD("Move x/y from (%d, %d) to (%d, %d) scrollOffset is (%d, %d)", - x, y, m_mousePos.x() + m_scrollOffsetX, m_mousePos.y() + m_scrollOffsetY, - m_scrollOffsetX, m_scrollOffsetY); - } - return rects; - } - } - IntRect rect = final.mBounds; - rect.move(frameAdjust.x(), frameAdjust.y()); - rects.append(rect); - // adjust m_mousePos if it is not inside the returned highlight rectangle - testRect.move(frameAdjust.x(), frameAdjust.y()); - testRect.intersect(rect); - if (!testRect.contains(x, y)) { - m_mousePos = testRect.center(); - m_mousePos.move(-m_scrollOffsetX, -m_scrollOffsetY); - DBG_NAV_LOGD("Move x/y from (%d, %d) to (%d, %d) scrollOffset is (%d, %d)", - x, y, m_mousePos.x() + m_scrollOffsetX, m_mousePos.y() + m_scrollOffsetY, - m_scrollOffsetX, m_scrollOffsetY); - } - } - return rects; -} - -/////////////////////////////////////////////////////////////////////////////// - -void WebViewCore::addPlugin(PluginWidgetAndroid* w) -{ -// SkDebugf("----------- addPlugin %p", w); - /* The plugin must be appended to the end of the array. This ensures that if - the plugin is added while iterating through the array (e.g. sendEvent(...)) - that the iteration process is not corrupted. - */ - *m_plugins.append() = w; -} - -void WebViewCore::removePlugin(PluginWidgetAndroid* w) -{ -// SkDebugf("----------- removePlugin %p", w); - int index = m_plugins.find(w); - if (index < 0) { - SkDebugf("--------------- pluginwindow not found! %p\n", w); - } else { - m_plugins.removeShuffle(index); - } -} - -bool WebViewCore::isPlugin(PluginWidgetAndroid* w) const -{ - return m_plugins.find(w) >= 0; -} - -void WebViewCore::invalPlugin(PluginWidgetAndroid* w) -{ - const double PLUGIN_INVAL_DELAY = 1.0 / 60; - - if (!m_pluginInvalTimer.isActive()) { - m_pluginInvalTimer.startOneShot(PLUGIN_INVAL_DELAY); - } -} - -void WebViewCore::drawPlugins() -{ - SkRegion inval; // accumualte what needs to be redrawn - PluginWidgetAndroid** iter = m_plugins.begin(); - PluginWidgetAndroid** stop = m_plugins.end(); - - for (; iter < stop; ++iter) { - PluginWidgetAndroid* w = *iter; - SkIRect dirty; - if (w->isDirty(&dirty)) { - w->draw(); - inval.op(dirty, SkRegion::kUnion_Op); - } - } - - if (!inval.isEmpty()) { - // inval.getBounds() is our rectangle - const SkIRect& bounds = inval.getBounds(); - WebCore::IntRect r(bounds.fLeft, bounds.fTop, - bounds.width(), bounds.height()); - this->viewInvalidate(r); - } -} - -void WebViewCore::notifyPluginsOnFrameLoad(const Frame* frame) { - // if frame is the parent then notify all plugins - if (!frame->tree()->parent()) { - // trigger an event notifying the plugins that the page has loaded - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kOnLoad_ANPLifecycleAction; - sendPluginEvent(event); - // trigger the on/off screen notification if the page was reloaded - sendPluginVisibleScreen(); - } - // else if frame's parent has completed - else if (!frame->tree()->parent()->loader()->isLoading()) { - // send to all plugins who have this frame in their heirarchy - PluginWidgetAndroid** iter = m_plugins.begin(); - PluginWidgetAndroid** stop = m_plugins.end(); - for (; iter < stop; ++iter) { - Frame* currentFrame = (*iter)->pluginView()->parentFrame(); - while (currentFrame) { - if (frame == currentFrame) { - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kOnLoad_ANPLifecycleAction; - (*iter)->sendEvent(event); - - // trigger the on/off screen notification if the page was reloaded - ANPRectI visibleRect; - getVisibleScreen(visibleRect); - (*iter)->setVisibleScreen(visibleRect, m_scale); - - break; - } - currentFrame = currentFrame->tree()->parent(); - } - } - } -} - -void WebViewCore::getVisibleScreen(ANPRectI& visibleRect) -{ - visibleRect.left = m_scrollOffsetX; - visibleRect.top = m_scrollOffsetY; - visibleRect.right = m_scrollOffsetX + m_screenWidth; - visibleRect.bottom = m_scrollOffsetY + m_screenHeight; -} - -void WebViewCore::sendPluginVisibleScreen() -{ - /* We may want to cache the previous values and only send the notification - to the plugin in the event that one of the values has changed. - */ - - ANPRectI visibleRect; - getVisibleScreen(visibleRect); - - PluginWidgetAndroid** iter = m_plugins.begin(); - PluginWidgetAndroid** stop = m_plugins.end(); - for (; iter < stop; ++iter) { - (*iter)->setVisibleScreen(visibleRect, m_scale); - } -} - -void WebViewCore::sendPluginEvent(const ANPEvent& evt) -{ - /* The list of plugins may be manipulated as we iterate through the list. - This implementation allows for the addition of new plugins during an - iteration, but may fail if a plugin is removed. Currently, there are not - any use cases where a plugin is deleted while processing this loop, but - if it does occur we will have to use an alternate data structure and/or - iteration mechanism. - */ - for (int x = 0; x < m_plugins.count(); x++) { - m_plugins[x]->sendEvent(evt); - } -} - -PluginWidgetAndroid* WebViewCore::getPluginWidget(NPP npp) -{ - PluginWidgetAndroid** iter = m_plugins.begin(); - PluginWidgetAndroid** stop = m_plugins.end(); - for (; iter < stop; ++iter) { - if ((*iter)->pluginView()->instance() == npp) { - return (*iter); - } - } - return 0; -} - -static PluginView* nodeIsPlugin(Node* node) { - RenderObject* renderer = node->renderer(); - if (renderer && renderer->isWidget()) { - Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); - if (widget && widget->isPluginView()) - return static_cast<PluginView*>(widget); - } - return 0; -} - -Node* WebViewCore::cursorNodeIsPlugin() { - gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_hasCursorBounds; - Frame* frame = (Frame*) m_cursorFrame; - Node* node = (Node*) m_cursorNode; - gCursorBoundsMutex.unlock(); - if (hasCursorBounds && CacheBuilder::validNode(m_mainFrame, frame, node) - && nodeIsPlugin(node)) { - return node; - } - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -void WebViewCore::moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, int x, int y) -{ - DBG_NAV_LOGD("m_moveGeneration=%d moveGeneration=%d" - " frame=%p x=%d y=%d", - m_moveGeneration, moveGeneration, frame, x, y); - if (m_moveGeneration > moveGeneration) { - DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", - m_moveGeneration, moveGeneration); - return; // short-circuit if a newer move has already been generated - } - m_lastGeneration = moveGeneration; - moveMouse(frame, x, y); -} - -void WebViewCore::moveFocus(WebCore::Frame* frame, WebCore::Node* node) -{ - DBG_NAV_LOGD("frame=%p node=%p", frame, node); - if (!node || !CacheBuilder::validNode(m_mainFrame, frame, node) - || !node->isElementNode()) - return; - // Code borrowed from FocusController::advanceFocus - WebCore::FocusController* focusController - = m_mainFrame->page()->focusController(); - WebCore::Document* oldDoc - = focusController->focusedOrMainFrame()->document(); - if (oldDoc->focusedNode() == node) - return; - if (node->document() != oldDoc) - oldDoc->setFocusedNode(0); - focusController->setFocusedFrame(frame); - static_cast<WebCore::Element*>(node)->focus(false); -} - -// Update mouse position -void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y) -{ - DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame, - x, y, m_scrollOffsetX, m_scrollOffsetY); - if (!frame || !CacheBuilder::validNode(m_mainFrame, frame, 0)) - frame = m_mainFrame; - // mouse event expects the position in the window coordinate - m_mousePos = WebCore::IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY); - // validNode will still return true if the node is null, as long as we have - // a valid frame. Do not want to make a call on frame unless it is valid. - WebCore::PlatformMouseEvent mouseEvent(m_mousePos, m_mousePos, - WebCore::NoButton, WebCore::MouseEventMoved, 1, false, false, false, - false, WTF::currentTime()); - frame->eventHandler()->handleMouseMoveEvent(mouseEvent); - updateCacheOnNodeChange(); -} - -void WebViewCore::setSelection(int start, int end) -{ - WebCore::Node* focus = currentFocus(); - if (!focus) - return; - WebCore::RenderObject* renderer = focus->renderer(); - if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) - return; - if (start > end) { - int temp = start; - start = end; - end = temp; - } - // Tell our EditorClient that this change was generated from the UI, so it - // does not need to echo it to the UI. - EditorClientAndroid* client = static_cast<EditorClientAndroid*>( - m_mainFrame->editor()->client()); - client->setUiGeneratedSelectionChange(true); - setSelectionRange(focus, start, end); - client->setUiGeneratedSelectionChange(false); - WebCore::Frame* focusedFrame = focus->document()->frame(); - bool isPasswordField = false; - if (focus->isElementNode()) { - WebCore::Element* element = static_cast<WebCore::Element*>(focus); - if (WebCore::InputElement* inputElement = WebCore::toInputElement(element)) - isPasswordField = static_cast<WebCore::HTMLInputElement*>(inputElement)->isPasswordField(); - } - // For password fields, this is done in the UI side via - // bringPointIntoView, since the UI does the drawing. - if (renderer->isTextArea() || !isPasswordField) - revealSelection(); -} - -String WebViewCore::modifySelection(const int direction, const int axis) -{ - DOMSelection* selection = m_mainFrame->domWindow()->getSelection(); - if (selection->rangeCount() > 1) - selection->removeAllRanges(); - switch (axis) { - case AXIS_CHARACTER: - case AXIS_WORD: - case AXIS_SENTENCE: - return modifySelectionTextNavigationAxis(selection, direction, axis); - case AXIS_HEADING: - case AXIS_SIBLING: - case AXIS_PARENT_FIRST_CHILD: - case AXIS_DOCUMENT: - return modifySelectionDomNavigationAxis(selection, direction, axis); - default: - LOGE("Invalid navigation axis: %d", axis); - return String(); - } -} - -void WebViewCore::scrollNodeIntoView(Frame* frame, Node* node) -{ - if (!frame || !node) - return; - - Element* elementNode = 0; - - // If not an Element, find a visible predecessor - // Element to scroll into view. - if (!node->isElementNode()) { - HTMLElement* body = frame->document()->body(); - do { - if (!node || node == body) - return; - node = node->parentNode(); - } while (!node->isElementNode() && !isVisible(node)); - } - - elementNode = static_cast<Element*>(node); - elementNode->scrollIntoViewIfNeeded(true); -} - -String WebViewCore::modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int axis) -{ - Node* body = m_mainFrame->document()->body(); - - ExceptionCode ec = 0; - String markup; - - // initialize the selection if necessary - if (selection->rangeCount() == 0) { - if (m_currentNodeDomNavigationAxis - && CacheBuilder::validNode(m_mainFrame, - m_mainFrame, m_currentNodeDomNavigationAxis)) { - PassRefPtr<Range> rangeRef = - selection->frame()->document()->createRange(); - rangeRef->selectNode(m_currentNodeDomNavigationAxis, ec); - m_currentNodeDomNavigationAxis = 0; - if (ec) - return String(); - selection->addRange(rangeRef.get()); - } else if (currentFocus()) { - selection->setPosition(currentFocus(), 0, ec); - } else if (m_cursorNode - && CacheBuilder::validNode(m_mainFrame, - m_mainFrame, m_cursorNode)) { - PassRefPtr<Range> rangeRef = - selection->frame()->document()->createRange(); - rangeRef->selectNode(reinterpret_cast<Node*>(m_cursorNode), ec); - if (ec) - return String(); - selection->addRange(rangeRef.get()); - } else { - selection->setPosition(body, 0, ec); - } - if (ec) - return String(); - } - - // collapse the selection - if (direction == DIRECTION_FORWARD) - selection->collapseToEnd(ec); - else - selection->collapseToStart(ec); - if (ec) - return String(); - - // Make sure the anchor node is a text node since we are generating - // the markup of the selection which includes the anchor, the focus, - // and any crossed nodes. Forcing the condition that the selection - // starts and ends on text nodes guarantees symmetric selection markup. - // Also this way the text content, rather its container, is highlighted. - Node* anchorNode = selection->anchorNode(); - if (anchorNode->isElementNode()) { - // Collapsed selection while moving forward points to the - // next unvisited node and while moving backward to the - // last visited node. - if (direction == DIRECTION_FORWARD) - advanceAnchorNode(selection, direction, markup, false, ec); - else - advanceAnchorNode(selection, direction, markup, true, ec); - if (ec) - return String(); - if (!markup.isEmpty()) - return markup; - } - - // If the selection is at the end of a non white space text move - // it to the next visible text node with non white space content. - // This is a workaround for the selection getting stuck. - anchorNode = selection->anchorNode(); - if (anchorNode->isTextNode()) { - if (direction == DIRECTION_FORWARD) { - String suffix = anchorNode->textContent().substring( - selection->anchorOffset(), caretMaxOffset(anchorNode)); - // If at the end of non white space text we advance the - // anchor node to either an input element or non empty text. - if (suffix.stripWhiteSpace().isEmpty()) { - advanceAnchorNode(selection, direction, markup, true, ec); - } - } else { - String prefix = anchorNode->textContent().substring(0, - selection->anchorOffset()); - // If at the end of non white space text we advance the - // anchor node to either an input element or non empty text. - if (prefix.stripWhiteSpace().isEmpty()) { - advanceAnchorNode(selection, direction, markup, true, ec); - } - } - if (ec) - return String(); - if (!markup.isEmpty()) - return markup; - } - - // extend the selection - String directionStr; - if (direction == DIRECTION_FORWARD) - directionStr = "forward"; - else - directionStr = "backward"; - - String axisStr; - if (axis == AXIS_CHARACTER) - axisStr = "character"; - else if (axis == AXIS_WORD) - axisStr = "word"; - else - axisStr = "sentence"; - - selection->modify("extend", directionStr, axisStr); - - // Make sure the focus node is a text node in order to have the - // selection generate symmetric markup because the latter - // includes all nodes crossed by the selection. Also this way - // the text content, rather its container, is highlighted. - Node* focusNode = selection->focusNode(); - if (focusNode->isElementNode()) { - focusNode = getImplicitBoundaryNode(selection->focusNode(), - selection->focusOffset(), direction); - if (!focusNode) - return String(); - if (direction == DIRECTION_FORWARD) { - focusNode = focusNode->traversePreviousSiblingPostOrder(body); - if (focusNode && !isContentTextNode(focusNode)) { - Node* textNode = traverseNextContentTextNode(focusNode, - anchorNode, DIRECTION_BACKWARD); - if (textNode) - anchorNode = textNode; - } - if (focusNode && isContentTextNode(focusNode)) { - selection->extend(focusNode, caretMaxOffset(focusNode), ec); - if (ec) - return String(); - } - } else { - focusNode = focusNode->traverseNextSibling(); - if (focusNode && !isContentTextNode(focusNode)) { - Node* textNode = traverseNextContentTextNode(focusNode, - anchorNode, DIRECTION_FORWARD); - if (textNode) - anchorNode = textNode; - } - if (anchorNode && isContentTextNode(anchorNode)) { - selection->extend(focusNode, 0, ec); - if (ec) - return String(); - } - } - } - - // Enforce that the selection does not cross anchor boundaries. This is - // a workaround for the asymmetric behavior of WebKit while crossing - // anchors. - anchorNode = getImplicitBoundaryNode(selection->anchorNode(), - selection->anchorOffset(), direction); - focusNode = getImplicitBoundaryNode(selection->focusNode(), - selection->focusOffset(), direction); - if (anchorNode && focusNode && anchorNode != focusNode) { - Node* inputControl = getIntermediaryInputElement(anchorNode, focusNode, - direction); - if (inputControl) { - if (direction == DIRECTION_FORWARD) { - if (isDescendantOf(inputControl, anchorNode)) { - focusNode = inputControl; - } else { - focusNode = inputControl->traversePreviousSiblingPostOrder( - body); - if (!focusNode) - focusNode = inputControl; - } - // We prefer a text node contained in the input element. - if (!isContentTextNode(focusNode)) { - Node* textNode = traverseNextContentTextNode(focusNode, - anchorNode, DIRECTION_BACKWARD); - if (textNode) - focusNode = textNode; - } - // If we found text in the input select it. - // Otherwise, select the input element itself. - if (isContentTextNode(focusNode)) { - selection->extend(focusNode, caretMaxOffset(focusNode), ec); - } else if (anchorNode != focusNode) { - // Note that the focusNode always has parent and that - // the offset can be one more that the index of the last - // element - this is how WebKit selects such elements. - selection->extend(focusNode->parentNode(), - focusNode->nodeIndex() + 1, ec); - } - if (ec) - return String(); - } else { - if (isDescendantOf(inputControl, anchorNode)) { - focusNode = inputControl; - } else { - focusNode = inputControl->traverseNextSibling(); - if (!focusNode) - focusNode = inputControl; - } - // We prefer a text node contained in the input element. - if (!isContentTextNode(focusNode)) { - Node* textNode = traverseNextContentTextNode(focusNode, - anchorNode, DIRECTION_FORWARD); - if (textNode) - focusNode = textNode; - } - // If we found text in the input select it. - // Otherwise, select the input element itself. - if (isContentTextNode(focusNode)) { - selection->extend(focusNode, caretMinOffset(focusNode), ec); - } else if (anchorNode != focusNode) { - // Note that the focusNode always has parent and that - // the offset can be one more that the index of the last - // element - this is how WebKit selects such elements. - selection->extend(focusNode->parentNode(), - focusNode->nodeIndex() + 1, ec); - } - if (ec) - return String(); - } - } - } - - // make sure the selection is visible - if (direction == DIRECTION_FORWARD) - scrollNodeIntoView(m_mainFrame, selection->focusNode()); - else - scrollNodeIntoView(m_mainFrame, selection->anchorNode()); - - // format markup for the visible content - PassRefPtr<Range> range = selection->getRangeAt(0, ec); - if (ec) - return String(); - IntRect bounds = range->boundingBox(); - selectAt(bounds.center().x(), bounds.center().y()); - markup = formatMarkup(selection); - LOGV("Selection markup: %s", markup.utf8().data()); - - return markup; -} - -Node* WebViewCore::getImplicitBoundaryNode(Node* node, unsigned offset, int direction) -{ - if (node->offsetInCharacters()) - return node; - if (!node->hasChildNodes()) - return node; - if (offset < node->childNodeCount()) - return node->childNode(offset); - else - if (direction == DIRECTION_FORWARD) - return node->traverseNextSibling(); - else - return node->traversePreviousNodePostOrder( - node->document()->body()); -} - -Node* WebViewCore::getNextAnchorNode(Node* anchorNode, bool ignoreFirstNode, int direction) -{ - Node* body = 0; - Node* currentNode = 0; - if (direction == DIRECTION_FORWARD) { - if (ignoreFirstNode) - currentNode = anchorNode->traverseNextNode(body); - else - currentNode = anchorNode; - } else { - body = anchorNode->document()->body(); - if (ignoreFirstNode) - currentNode = anchorNode->traversePreviousSiblingPostOrder(body); - else - currentNode = anchorNode; - } - while (currentNode) { - if (isContentTextNode(currentNode) - || isContentInputElement(currentNode)) - return currentNode; - if (direction == DIRECTION_FORWARD) - currentNode = currentNode->traverseNextNode(); - else - currentNode = currentNode->traversePreviousNodePostOrder(body); - } - return 0; -} - -void WebViewCore::advanceAnchorNode(DOMSelection* selection, int direction, - String& markup, bool ignoreFirstNode, ExceptionCode& ec) -{ - Node* anchorNode = getImplicitBoundaryNode(selection->anchorNode(), - selection->anchorOffset(), direction); - if (!anchorNode) { - ec = NOT_FOUND_ERR; - return; - } - // If the anchor offset is invalid i.e. the anchor node has no - // child with that index getImplicitAnchorNode returns the next - // logical node in the current direction. In such a case our - // position in the DOM tree was has already been advanced, - // therefore we there is no need to do that again. - if (selection->anchorNode()->isElementNode()) { - unsigned anchorOffset = selection->anchorOffset(); - unsigned childNodeCount = selection->anchorNode()->childNodeCount(); - if (anchorOffset >= childNodeCount) - ignoreFirstNode = false; - } - // Find the next anchor node given our position in the DOM and - // whether we want the current node to be considered as well. - Node* nextAnchorNode = getNextAnchorNode(anchorNode, ignoreFirstNode, - direction); - if (!nextAnchorNode) { - ec = NOT_FOUND_ERR; - return; - } - if (nextAnchorNode->isElementNode()) { - // If this is an input element tell the WebView thread - // to set the cursor to that control. - if (isContentInputElement(nextAnchorNode)) { - IntRect bounds = nextAnchorNode->getRect(); - selectAt(bounds.center().x(), bounds.center().y()); - } - Node* textNode = 0; - // Treat the text content of links as any other text but - // for the rest input elements select the control itself. - if (nextAnchorNode->hasTagName(WebCore::HTMLNames::aTag)) - textNode = traverseNextContentTextNode(nextAnchorNode, - nextAnchorNode, direction); - // We prefer to select the text content of the link if such, - // otherwise just select the element itself. - if (textNode) { - nextAnchorNode = textNode; - } else { - if (direction == DIRECTION_FORWARD) { - selection->setBaseAndExtent(nextAnchorNode, - caretMinOffset(nextAnchorNode), nextAnchorNode, - caretMaxOffset(nextAnchorNode), ec); - } else { - selection->setBaseAndExtent(nextAnchorNode, - caretMaxOffset(nextAnchorNode), nextAnchorNode, - caretMinOffset(nextAnchorNode), ec); - } - if (!ec) - markup = formatMarkup(selection); - // make sure the selection is visible - scrollNodeIntoView(selection->frame(), nextAnchorNode); - return; - } - } - if (direction == DIRECTION_FORWARD) - selection->setPosition(nextAnchorNode, - caretMinOffset(nextAnchorNode), ec); - else - selection->setPosition(nextAnchorNode, - caretMaxOffset(nextAnchorNode), ec); -} - -bool WebViewCore::isContentInputElement(Node* node) -{ - return (isVisible(node) - && (node->hasTagName(WebCore::HTMLNames::selectTag) - || node->hasTagName(WebCore::HTMLNames::aTag) - || node->hasTagName(WebCore::HTMLNames::inputTag) - || node->hasTagName(WebCore::HTMLNames::buttonTag))); -} - -bool WebViewCore::isContentTextNode(Node* node) -{ - if (!node || !node->isTextNode()) - return false; - Text* textNode = static_cast<Text*>(node); - return (isVisible(textNode) && textNode->length() > 0 - && !textNode->containsOnlyWhitespace()); -} - -Text* WebViewCore::traverseNextContentTextNode(Node* fromNode, Node* toNode, int direction) -{ - Node* currentNode = fromNode; - do { - if (direction == DIRECTION_FORWARD) - currentNode = currentNode->traverseNextNode(toNode); - else - currentNode = currentNode->traversePreviousNodePostOrder(toNode); - } while (currentNode && !isContentTextNode(currentNode)); - return static_cast<Text*>(currentNode); -} - -Node* WebViewCore::getIntermediaryInputElement(Node* fromNode, Node* toNode, int direction) -{ - if (fromNode == toNode) - return 0; - if (direction == DIRECTION_FORWARD) { - Node* currentNode = fromNode; - while (currentNode && currentNode != toNode) { - if (isContentInputElement(currentNode)) - return currentNode; - currentNode = currentNode->traverseNextNodePostOrder(); - } - currentNode = fromNode; - while (currentNode && currentNode != toNode) { - if (isContentInputElement(currentNode)) - return currentNode; - currentNode = currentNode->traverseNextNode(); - } - } else { - Node* currentNode = fromNode->traversePreviousNode(); - while (currentNode && currentNode != toNode) { - if (isContentInputElement(currentNode)) - return currentNode; - currentNode = currentNode->traversePreviousNode(); - } - currentNode = fromNode->traversePreviousNodePostOrder(); - while (currentNode && currentNode != toNode) { - if (isContentInputElement(currentNode)) - return currentNode; - currentNode = currentNode->traversePreviousNodePostOrder(); - } - } - return 0; -} - -bool WebViewCore::isDescendantOf(Node* parent, Node* node) -{ - Node* currentNode = node; - while (currentNode) { - if (currentNode == parent) { - return true; - } - currentNode = currentNode->parentNode(); - } - return false; -} - -String WebViewCore::modifySelectionDomNavigationAxis(DOMSelection* selection, int direction, int axis) -{ - HTMLElement* body = m_mainFrame->document()->body(); - if (!m_currentNodeDomNavigationAxis && selection->focusNode()) { - m_currentNodeDomNavigationAxis = selection->focusNode(); - selection->empty(); - if (m_currentNodeDomNavigationAxis->isTextNode()) - m_currentNodeDomNavigationAxis = - m_currentNodeDomNavigationAxis->parentNode(); - } - if (!m_currentNodeDomNavigationAxis) - m_currentNodeDomNavigationAxis = currentFocus(); - if (!m_currentNodeDomNavigationAxis - || !CacheBuilder::validNode(m_mainFrame, m_mainFrame, - m_currentNodeDomNavigationAxis)) - m_currentNodeDomNavigationAxis = body; - Node* currentNode = m_currentNodeDomNavigationAxis; - if (axis == AXIS_HEADING) { - if (currentNode == body && direction == DIRECTION_BACKWARD) - currentNode = currentNode->lastDescendant(); - do { - if (direction == DIRECTION_FORWARD) - currentNode = currentNode->traverseNextNode(body); - else - currentNode = currentNode->traversePreviousNode(body); - } while (currentNode && (currentNode->isTextNode() - || !isVisible(currentNode) || !isHeading(currentNode))); - } else if (axis == AXIS_PARENT_FIRST_CHILD) { - if (direction == DIRECTION_FORWARD) { - currentNode = currentNode->firstChild(); - while (currentNode && (currentNode->isTextNode() - || !isVisible(currentNode))) - currentNode = currentNode->nextSibling(); - } else { - do { - if (currentNode == body) - return String(); - currentNode = currentNode->parentNode(); - } while (currentNode && (currentNode->isTextNode() - || !isVisible(currentNode))); - } - } else if (axis == AXIS_SIBLING) { - do { - if (direction == DIRECTION_FORWARD) - currentNode = currentNode->nextSibling(); - else { - if (currentNode == body) - return String(); - currentNode = currentNode->previousSibling(); - } - } while (currentNode && (currentNode->isTextNode() - || !isVisible(currentNode))); - } else if (axis == AXIS_DOCUMENT) { - currentNode = body; - if (direction == DIRECTION_FORWARD) - currentNode = currentNode->lastDescendant(); - } else { - LOGE("Invalid axis: %d", axis); - return String(); - } - if (currentNode) { - m_currentNodeDomNavigationAxis = currentNode; - scrollNodeIntoView(m_mainFrame, currentNode); - String selectionString = createMarkup(currentNode); - LOGV("Selection markup: %s", selectionString.utf8().data()); - return selectionString; - } - return String(); -} - -bool WebViewCore::isHeading(Node* node) -{ - if (node->hasTagName(WebCore::HTMLNames::h1Tag) - || node->hasTagName(WebCore::HTMLNames::h2Tag) - || node->hasTagName(WebCore::HTMLNames::h3Tag) - || node->hasTagName(WebCore::HTMLNames::h4Tag) - || node->hasTagName(WebCore::HTMLNames::h5Tag) - || node->hasTagName(WebCore::HTMLNames::h6Tag)) { - return true; - } - - if (node->isElementNode()) { - Element* element = static_cast<Element*>(node); - String roleAttribute = - element->getAttribute(WebCore::HTMLNames::roleAttr).string(); - if (equalIgnoringCase(roleAttribute, "heading")) - return true; - } - - return false; -} - -bool WebViewCore::isVisible(Node* node) -{ - // start off an element - Element* element = 0; - if (node->isElementNode()) - element = static_cast<Element*>(node); - else - element = node->parentElement(); - // check renderer - if (!element->renderer()) { - return false; - } - // check size - if (element->offsetHeight() == 0 || element->offsetWidth() == 0) { - return false; - } - // check style - Node* body = m_mainFrame->document()->body(); - Node* currentNode = element; - while (currentNode && currentNode != body) { - RenderStyle* style = currentNode->computedStyle(); - if (style && - (style->display() == NONE || style->visibility() == HIDDEN)) { - return false; - } - currentNode = currentNode->parentNode(); - } - return true; -} - -String WebViewCore::formatMarkup(DOMSelection* selection) -{ - ExceptionCode ec = 0; - String markup = String(); - PassRefPtr<Range> wholeRange = selection->getRangeAt(0, ec); - if (ec) - return String(); - if (!wholeRange->startContainer() || !wholeRange->startContainer()) - return String(); - // Since formatted markup contains invisible nodes it - // is created from the concatenation of the visible fragments. - Node* firstNode = wholeRange->firstNode(); - Node* pastLastNode = wholeRange->pastLastNode(); - Node* currentNode = firstNode; - PassRefPtr<Range> currentRange; - - while (currentNode != pastLastNode) { - Node* nextNode = currentNode->traverseNextNode(); - if (!isVisible(currentNode)) { - if (currentRange) { - markup = markup + currentRange->toHTML().utf8().data(); - currentRange = 0; - } - } else { - if (!currentRange) { - currentRange = selection->frame()->document()->createRange(); - if (ec) - break; - if (currentNode == firstNode) { - currentRange->setStart(wholeRange->startContainer(), - wholeRange->startOffset(), ec); - if (ec) - break; - } else { - currentRange->setStart(currentNode->parentNode(), - currentNode->nodeIndex(), ec); - if (ec) - break; - } - } - if (nextNode == pastLastNode) { - currentRange->setEnd(wholeRange->endContainer(), - wholeRange->endOffset(), ec); - if (ec) - break; - markup = markup + currentRange->toHTML().utf8().data(); - } else { - if (currentNode->offsetInCharacters()) - currentRange->setEnd(currentNode, - currentNode->maxCharacterOffset(), ec); - else - currentRange->setEnd(currentNode->parentNode(), - currentNode->nodeIndex() + 1, ec); - if (ec) - break; - } - } - currentNode = nextNode; - } - return markup.stripWhiteSpace(); -} - -void WebViewCore::selectAt(int x, int y) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_selectAt, - x, y); - checkException(env); -} - -void WebViewCore::deleteSelection(int start, int end, int textGeneration) -{ - setSelection(start, end); - if (start == end) - return; - WebCore::Node* focus = currentFocus(); - if (!focus) - return; - // Prevent our editor client from passing a message to change the - // selection. - EditorClientAndroid* client = static_cast<EditorClientAndroid*>( - m_mainFrame->editor()->client()); - client->setUiGeneratedSelectionChange(true); - PlatformKeyboardEvent down(AKEYCODE_DEL, 0, 0, true, false, false, false); - PlatformKeyboardEvent up(AKEYCODE_DEL, 0, 0, false, false, false, false); - key(down); - key(up); - client->setUiGeneratedSelectionChange(false); - m_textGeneration = textGeneration; - m_shouldPaintCaret = true; -} - -void WebViewCore::replaceTextfieldText(int oldStart, - int oldEnd, const WTF::String& replace, int start, int end, - int textGeneration) -{ - WebCore::Node* focus = currentFocus(); - if (!focus) - return; - setSelection(oldStart, oldEnd); - // Prevent our editor client from passing a message to change the - // selection. - EditorClientAndroid* client = static_cast<EditorClientAndroid*>( - m_mainFrame->editor()->client()); - client->setUiGeneratedSelectionChange(true); - WebCore::TypingCommand::insertText(focus->document(), replace, - false); - client->setUiGeneratedSelectionChange(false); - // setSelection calls revealSelection, so there is no need to do it here. - setSelection(start, end); - m_textGeneration = textGeneration; - m_shouldPaintCaret = true; -} - -void WebViewCore::passToJs(int generation, const WTF::String& current, - const PlatformKeyboardEvent& event) -{ - WebCore::Node* focus = currentFocus(); - if (!focus) { - DBG_NAV_LOG("!focus"); - clearTextEntry(); - return; - } - WebCore::RenderObject* renderer = focus->renderer(); - if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) { - DBG_NAV_LOGD("renderer==%p || not text", renderer); - clearTextEntry(); - return; - } - // Block text field updates during a key press. - m_blockTextfieldUpdates = true; - // Also prevent our editor client from passing a message to change the - // selection. - EditorClientAndroid* client = static_cast<EditorClientAndroid*>( - m_mainFrame->editor()->client()); - client->setUiGeneratedSelectionChange(true); - key(event); - client->setUiGeneratedSelectionChange(false); - m_blockTextfieldUpdates = false; - m_textGeneration = generation; - WebCore::RenderTextControl* renderText = - static_cast<WebCore::RenderTextControl*>(renderer); - WTF::String test = renderText->text(); - if (test != current) { - // If the text changed during the key event, update the UI text field. - updateTextfield(focus, false, test); - } else { - DBG_NAV_LOG("test == current"); - } - // Now that the selection has settled down, send it. - updateTextSelection(); - m_shouldPaintCaret = true; -} - -void WebViewCore::scrollFocusedTextInput(float xPercent, int y) -{ - WebCore::Node* focus = currentFocus(); - if (!focus) { - DBG_NAV_LOG("!focus"); - clearTextEntry(); - return; - } - WebCore::RenderObject* renderer = focus->renderer(); - if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) { - DBG_NAV_LOGD("renderer==%p || not text", renderer); - clearTextEntry(); - return; - } - WebCore::RenderTextControl* renderText = - static_cast<WebCore::RenderTextControl*>(renderer); - int x = (int) (xPercent * (renderText->scrollWidth() - - renderText->clientWidth())); - DBG_NAV_LOGD("x=%d y=%d xPercent=%g scrollW=%d clientW=%d", x, y, - xPercent, renderText->scrollWidth(), renderText->clientWidth()); - renderText->setScrollLeft(x); - renderText->setScrollTop(y); -} - -void WebViewCore::setFocusControllerActive(bool active) -{ - m_mainFrame->page()->focusController()->setActive(active); -} - -void WebViewCore::saveDocumentState(WebCore::Frame* frame) -{ - if (!CacheBuilder::validNode(m_mainFrame, frame, 0)) - frame = m_mainFrame; - WebCore::HistoryItem *item = frame->loader()->history()->currentItem(); - - // item can be null when there is no offical URL for the current page. This happens - // when the content is loaded using with WebCoreFrameBridge::LoadData() and there - // is no failing URL (common case is when content is loaded using data: scheme) - if (item) { - item->setDocumentState(frame->document()->formElementsState()); - } -} - -// Create an array of java Strings. -static jobjectArray makeLabelArray(JNIEnv* env, const uint16_t** labels, size_t count) -{ - jclass stringClass = env->FindClass("java/lang/String"); - LOG_ASSERT(stringClass, "Could not find java/lang/String"); - jobjectArray array = env->NewObjectArray(count, stringClass, 0); - LOG_ASSERT(array, "Could not create new string array"); - - for (size_t i = 0; i < count; i++) { - jobject newString = env->NewString(&labels[i][1], labels[i][0]); - env->SetObjectArrayElement(array, i, newString); - env->DeleteLocalRef(newString); - checkException(env); - } - env->DeleteLocalRef(stringClass); - return array; -} - -void WebViewCore::openFileChooser(PassRefPtr<WebCore::FileChooser> chooser) { - if (!chooser) - return; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - - WTF::String acceptType = chooser->acceptTypes(); - jstring jAcceptType = wtfStringToJstring(env, acceptType, true); - jstring jName = (jstring) env->CallObjectMethod( - m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser, jAcceptType); - checkException(env); - env->DeleteLocalRef(jAcceptType); - - const UChar* string = static_cast<const UChar*>(env->GetStringChars(jName, NULL)); - - if (!string) - return; - - WTF::String webcoreString = jstringToWtfString(env, jName); - env->ReleaseStringChars(jName, string); - - if (webcoreString.length()) - chooser->chooseFile(webcoreString); -} - -void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, - bool multiple, const int selected[], size_t selectedCountOrSelection) -{ - // If m_popupReply is not null, then we already have a list showing. - if (m_popupReply != 0) - return; - - LOG_ASSERT(m_javaGlue->m_obj, "No java widget associated with this view!"); - - // Create an array of java Strings for the drop down. - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobjectArray labelArray = makeLabelArray(env, labels, count); - - // Create an array determining whether each item is enabled. - jintArray enabledArray = env->NewIntArray(enabledCount); - checkException(env); - jint* ptrArray = env->GetIntArrayElements(enabledArray, 0); - checkException(env); - for (size_t i = 0; i < enabledCount; i++) { - ptrArray[i] = enabled[i]; - } - env->ReleaseIntArrayElements(enabledArray, ptrArray, 0); - checkException(env); - - if (multiple) { - // Pass up an array representing which items are selected. - jintArray selectedArray = env->NewIntArray(selectedCountOrSelection); - checkException(env); - jint* selArray = env->GetIntArrayElements(selectedArray, 0); - checkException(env); - for (size_t i = 0; i < selectedCountOrSelection; i++) { - selArray[i] = selected[i]; - } - env->ReleaseIntArrayElements(selectedArray, selArray, 0); - - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_requestListBox, labelArray, enabledArray, - selectedArray); - env->DeleteLocalRef(selectedArray); - } else { - // Pass up the single selection. - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_requestSingleListBox, labelArray, enabledArray, - selectedCountOrSelection); - } - - env->DeleteLocalRef(labelArray); - env->DeleteLocalRef(enabledArray); - checkException(env); - - Retain(reply); - m_popupReply = reply; -} - -bool WebViewCore::key(const PlatformKeyboardEvent& event) -{ - WebCore::EventHandler* eventHandler; - WebCore::Node* focusNode = currentFocus(); - DBG_NAV_LOGD("keyCode=%s unichar=%d focusNode=%p", - event.keyIdentifier().utf8().data(), event.unichar(), focusNode); - if (focusNode) { - WebCore::Frame* frame = focusNode->document()->frame(); - WebFrame* webFrame = WebFrame::getWebFrame(frame); - eventHandler = frame->eventHandler(); - VisibleSelection old = frame->selection()->selection(); - bool handled = eventHandler->keyEvent(event); - if (isContentEditable(focusNode)) { - // keyEvent will return true even if the contentEditable did not - // change its selection. In the case that it does not, we want to - // return false so that the key will be sent back to our navigation - // system. - handled |= frame->selection()->selection() != old; - } - return handled; - } else { - eventHandler = m_mainFrame->eventHandler(); - } - return eventHandler->keyEvent(event); -} - -// For when the user clicks the trackball, presses dpad center, or types into an -// unfocused textfield. In the latter case, 'fake' will be true -void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node, bool fake) { - if (!node) { - WebCore::IntPoint pt = m_mousePos; - pt.move(m_scrollOffsetX, m_scrollOffsetY); - WebCore::HitTestResult hitTestResult = m_mainFrame->eventHandler()-> - hitTestResultAtPoint(pt, false); - node = hitTestResult.innerNode(); - frame = node->document()->frame(); - DBG_NAV_LOGD("m_mousePos=(%d,%d) m_scrollOffset=(%d,%d) pt=(%d,%d)" - " node=%p", m_mousePos.x(), m_mousePos.y(), - m_scrollOffsetX, m_scrollOffsetY, pt.x(), pt.y(), node); - } - if (node) { - EditorClientAndroid* client - = static_cast<EditorClientAndroid*>( - m_mainFrame->editor()->client()); - client->setShouldChangeSelectedRange(false); - handleMouseClick(frame, node, fake); - client->setShouldChangeSelectedRange(true); - } -} - -#if USE(ACCELERATED_COMPOSITING) -GraphicsLayerAndroid* WebViewCore::graphicsRootLayer() const -{ - RenderView* contentRenderer = m_mainFrame->contentRenderer(); - if (!contentRenderer) - return 0; - return static_cast<GraphicsLayerAndroid*>( - contentRenderer->compositor()->rootPlatformLayer()); -} -#endif - -bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState) -{ - bool preventDefault = false; - -#if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* rootLayer = graphicsRootLayer(); - if (rootLayer) - rootLayer->pauseDisplay(true); -#endif - -#if ENABLE(TOUCH_EVENTS) // Android - #define MOTION_EVENT_ACTION_POINTER_DOWN 5 - #define MOTION_EVENT_ACTION_POINTER_UP 6 - - WebCore::TouchEventType type = WebCore::TouchStart; - WebCore::PlatformTouchPoint::State defaultTouchState; - Vector<WebCore::PlatformTouchPoint::State> touchStates(points.size()); - - switch (action) { - case 0: // MotionEvent.ACTION_DOWN - type = WebCore::TouchStart; - defaultTouchState = WebCore::PlatformTouchPoint::TouchPressed; - break; - case 1: // MotionEvent.ACTION_UP - type = WebCore::TouchEnd; - defaultTouchState = WebCore::PlatformTouchPoint::TouchReleased; - break; - case 2: // MotionEvent.ACTION_MOVE - type = WebCore::TouchMove; - defaultTouchState = WebCore::PlatformTouchPoint::TouchMoved; - break; - case 3: // MotionEvent.ACTION_CANCEL - type = WebCore::TouchCancel; - defaultTouchState = WebCore::PlatformTouchPoint::TouchCancelled; - break; - case 5: // MotionEvent.ACTION_POINTER_DOWN - type = WebCore::TouchStart; - defaultTouchState = WebCore::PlatformTouchPoint::TouchStationary; - break; - case 6: // MotionEvent.ACTION_POINTER_UP - type = WebCore::TouchEnd; - defaultTouchState = WebCore::PlatformTouchPoint::TouchStationary; - break; - case 0x100: // WebViewCore.ACTION_LONGPRESS - type = WebCore::TouchLongPress; - defaultTouchState = WebCore::PlatformTouchPoint::TouchPressed; - break; - case 0x200: // WebViewCore.ACTION_DOUBLETAP - type = WebCore::TouchDoubleTap; - defaultTouchState = WebCore::PlatformTouchPoint::TouchPressed; - break; - default: - // We do not support other kinds of touch event inside WebCore - // at the moment. - LOGW("Java passed a touch event type that we do not support in WebCore: %d", action); - return 0; - } - - for (int c = 0; c < static_cast<int>(points.size()); c++) { - points[c].setX(points[c].x() - m_scrollOffsetX); - points[c].setY(points[c].y() - m_scrollOffsetY); - - // Setting the touch state for each point. - // Note: actionIndex will be 0 for all actions that are not ACTION_POINTER_DOWN/UP. - if (action == MOTION_EVENT_ACTION_POINTER_DOWN && c == actionIndex) { - touchStates[c] = WebCore::PlatformTouchPoint::TouchPressed; - } else if (action == MOTION_EVENT_ACTION_POINTER_UP && c == actionIndex) { - touchStates[c] = WebCore::PlatformTouchPoint::TouchReleased; - } else { - touchStates[c] = defaultTouchState; - }; - } - - WebCore::PlatformTouchEvent te(ids, points, type, touchStates, metaState); - preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te); -#endif - -#if USE(ACCELERATED_COMPOSITING) - if (rootLayer) - rootLayer->pauseDisplay(false); -#endif - return preventDefault; -} - -void WebViewCore::touchUp(int touchGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y) -{ - if (touchGeneration == 0) { - // m_mousePos should be set in getTouchHighlightRects() - WebCore::HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(m_mousePos, false); - node = hitTestResult.innerNode(); - if (node) - frame = node->document()->frame(); - else - frame = 0; - DBG_NAV_LOGD("touch up on (%d, %d), scrollOffset is (%d, %d), node:%p, frame:%p", m_mousePos.x() + m_scrollOffsetX, m_mousePos.y() + m_scrollOffsetY, m_scrollOffsetX, m_scrollOffsetY, node, frame); - } else { - if (m_touchGeneration > touchGeneration) { - DBG_NAV_LOGD("m_touchGeneration=%d > touchGeneration=%d" - " x=%d y=%d", m_touchGeneration, touchGeneration, x, y); - return; // short circuit if a newer touch has been generated - } - // This moves m_mousePos to the correct place, and handleMouseClick uses - // m_mousePos to determine where the click happens. - moveMouse(frame, x, y); - m_lastGeneration = touchGeneration; - } - if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) { - frame->loader()->resetMultipleFormSubmissionProtection(); - } - DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p" - " x=%d y=%d", touchGeneration, frame, node, x, y); - handleMouseClick(frame, node, false); -} - -// Check for the "x-webkit-soft-keyboard" attribute. If it is there and -// set to hidden, do not show the soft keyboard. Node passed as a parameter -// must not be null. -static bool shouldSuppressKeyboard(const WebCore::Node* node) { - LOG_ASSERT(node, "node passed to shouldSuppressKeyboard cannot be null"); - const NamedNodeMap* attributes = node->attributes(); - if (!attributes) return false; - size_t length = attributes->length(); - for (size_t i = 0; i < length; i++) { - const Attribute* a = attributes->attributeItem(i); - if (a->localName() == "x-webkit-soft-keyboard" && a->value() == "hidden") - return true; - } - return false; -} - -// Common code for both clicking with the trackball and touchUp -// Also used when typing into a non-focused textfield to give the textfield focus, -// in which case, 'fake' is set to true -bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr, bool fake) -{ - bool valid = !framePtr || CacheBuilder::validNode(m_mainFrame, framePtr, nodePtr); - WebFrame* webFrame = WebFrame::getWebFrame(m_mainFrame); - if (valid && nodePtr) { - // Need to special case area tags because an image map could have an area element in the middle - // so when attempting to get the default, the point chosen would be follow the wrong link. - if (nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) { - webFrame->setUserInitiatedAction(true); - nodePtr->dispatchSimulatedClick(0, true, true); - webFrame->setUserInitiatedAction(false); - DBG_NAV_LOG("area"); - return true; - } - } - if (!valid || !framePtr) - framePtr = m_mainFrame; - webFrame->setUserInitiatedAction(true); - WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton, - WebCore::MouseEventPressed, 1, false, false, false, false, - WTF::currentTime()); - // ignore the return from as it will return true if the hit point can trigger selection change - framePtr->eventHandler()->handleMousePressEvent(mouseDown); - WebCore::PlatformMouseEvent mouseUp(m_mousePos, m_mousePos, WebCore::LeftButton, - WebCore::MouseEventReleased, 1, false, false, false, false, - WTF::currentTime()); - bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); - webFrame->setUserInitiatedAction(false); - - // If the user clicked on a textfield, make the focusController active - // so we show the blinking cursor. - WebCore::Node* focusNode = currentFocus(); - DBG_NAV_LOGD("m_mousePos={%d,%d} focusNode=%p handled=%s", m_mousePos.x(), - m_mousePos.y(), focusNode, handled ? "true" : "false"); - if (focusNode) { - WebCore::RenderObject* renderer = focusNode->renderer(); - if (renderer && (renderer->isTextField() || renderer->isTextArea())) { - bool ime = !shouldSuppressKeyboard(focusNode) - && !(static_cast<WebCore::HTMLInputElement*>(focusNode))->readOnly(); - if (ime) { -#if ENABLE(WEB_AUTOFILL) - if (renderer->isTextField()) { - EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(framePtr->page()->editorClient()); - WebAutoFill* autoFill = editorC->getAutoFill(); - autoFill->formFieldFocused(static_cast<HTMLFormControlElement*>(focusNode)); - } -#endif - if (!fake) { - RenderTextControl* rtc - = static_cast<RenderTextControl*> (renderer); - requestKeyboardWithSelection(focusNode, rtc->selectionStart(), - rtc->selectionEnd()); - } - } else if (!fake) { - requestKeyboard(false); - } - } else if (!fake){ - // If the selection is contentEditable, show the keyboard so the - // user can type. Otherwise hide the keyboard because no text - // input is needed. - if (isContentEditable(focusNode)) { - requestKeyboard(true); - } else if (!nodeIsPlugin(focusNode)) { - clearTextEntry(); - } - } - } else if (!fake) { - // There is no focusNode, so the keyboard is not needed. - clearTextEntry(); - } - return handled; -} - -void WebViewCore::popupReply(int index) -{ - if (m_popupReply) { - m_popupReply->replyInt(index); - Release(m_popupReply); - m_popupReply = 0; - } -} - -void WebViewCore::popupReply(const int* array, int count) -{ - if (m_popupReply) { - m_popupReply->replyIntArray(array, count); - Release(m_popupReply); - m_popupReply = 0; - } -} - -void WebViewCore::formDidBlur(const WebCore::Node* node) -{ - // If the blur is on a text input, keep track of the node so we can - // hide the soft keyboard when the new focus is set, if it is not a - // text input. - if (isTextInput(node)) - m_blurringNodePointer = reinterpret_cast<int>(node); -} - -void WebViewCore::focusNodeChanged(const WebCore::Node* newFocus) -{ - if (isTextInput(newFocus)) - m_shouldPaintCaret = true; - else if (m_blurringNodePointer) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_formDidBlur, m_blurringNodePointer); - checkException(env); - m_blurringNodePointer = 0; - } -} - -void WebViewCore::addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jMessageStr = wtfStringToJstring(env, message); - jstring jSourceIDStr = wtfStringToJstring(env, sourceID); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_addMessageToConsole, jMessageStr, lineNumber, - jSourceIDStr, msgLevel); - env->DeleteLocalRef(jMessageStr); - env->DeleteLocalRef(jSourceIDStr); - checkException(env); -} - -void WebViewCore::jsAlert(const WTF::String& url, const WTF::String& text) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jInputStr = wtfStringToJstring(env, text); - jstring jUrlStr = wtfStringToJstring(env, url); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsAlert, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); -} - -void WebViewCore::exceededDatabaseQuota(const WTF::String& url, const WTF::String& databaseIdentifier, const unsigned long long currentQuota, unsigned long long estimatedSize) -{ -#if ENABLE(DATABASE) - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jDatabaseIdentifierStr = wtfStringToJstring(env, databaseIdentifier); - jstring jUrlStr = wtfStringToJstring(env, url); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_exceededDatabaseQuota, jUrlStr, - jDatabaseIdentifierStr, currentQuota, estimatedSize); - env->DeleteLocalRef(jDatabaseIdentifierStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); -#endif -} - -void WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded) -{ -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded); - checkException(env); -#endif -} - -void WebViewCore::populateVisitedLinks(WebCore::PageGroup* group) -{ - m_groupForVisitedLinks = group; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_populateVisitedLinks); - checkException(env); -} - -void WebViewCore::geolocationPermissionsShowPrompt(const WTF::String& origin) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring originString = wtfStringToJstring(env, origin); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_geolocationPermissionsShowPrompt, - originString); - env->DeleteLocalRef(originString); - checkException(env); -} - -void WebViewCore::geolocationPermissionsHidePrompt() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_geolocationPermissionsHidePrompt); - checkException(env); -} - -jobject WebViewCore::getDeviceMotionService() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject object = env->CallObjectMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_getDeviceMotionService); - checkException(env); - return object; -} - -jobject WebViewCore::getDeviceOrientationService() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject object = env->CallObjectMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_getDeviceOrientationService); - checkException(env); - return object; -} - -bool WebViewCore::jsConfirm(const WTF::String& url, const WTF::String& text) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jInputStr = wtfStringToJstring(env, text); - jstring jUrlStr = wtfStringToJstring(env, url); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsConfirm, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -bool WebViewCore::jsPrompt(const WTF::String& url, const WTF::String& text, const WTF::String& defaultValue, WTF::String& result) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jUrlStr = wtfStringToJstring(env, url); - jstring jInputStr = wtfStringToJstring(env, text); - jstring jDefaultStr = wtfStringToJstring(env, defaultValue); - jstring returnVal = static_cast<jstring>(env->CallObjectMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsPrompt, jUrlStr, jInputStr, jDefaultStr)); - env->DeleteLocalRef(jUrlStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jDefaultStr); - checkException(env); - - // If returnVal is null, it means that the user cancelled the dialog. - if (!returnVal) - return false; - - result = jstringToWtfString(env, returnVal); - env->DeleteLocalRef(returnVal); - return true; -} - -bool WebViewCore::jsUnload(const WTF::String& url, const WTF::String& message) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jInputStr = wtfStringToJstring(env, message); - jstring jUrlStr = wtfStringToJstring(env, url); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsUnload, jUrlStr, jInputStr); - env->DeleteLocalRef(jInputStr); - env->DeleteLocalRef(jUrlStr); - checkException(env); - return result; -} - -bool WebViewCore::jsInterrupt() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsInterrupt); - checkException(env); - return result; -} - -AutoJObject -WebViewCore::getJavaObject() -{ - return m_javaGlue->object(JSC::Bindings::getJNIEnv()); -} - -jobject -WebViewCore::getWebViewJavaObject() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - return env->GetObjectField(m_javaGlue->object(env).get(), gWebViewCoreFields.m_webView); -} - -void WebViewCore::updateTextSelection() { - WebCore::Node* focusNode = currentFocus(); - if (!focusNode) - return; - RenderObject* renderer = focusNode->renderer(); - if (!renderer || (!renderer->isTextArea() && !renderer->isTextField())) - return; - RenderTextControl* rtc = static_cast<RenderTextControl*>(renderer); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_updateTextSelection, reinterpret_cast<int>(focusNode), - rtc->selectionStart(), rtc->selectionEnd(), m_textGeneration); - checkException(env); -} - -void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, - const WTF::String& text) -{ - if (m_blockTextfieldUpdates) - return; - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (changeToPassword) { - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield, - (int) ptr, true, 0, m_textGeneration); - checkException(env); - return; - } - jstring string = wtfStringToJstring(env, text); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield, - (int) ptr, false, string, m_textGeneration); - env->DeleteLocalRef(string); - checkException(env); -} - -void WebViewCore::clearTextEntry() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_clearTextEntry); -} - -void WebViewCore::setBackgroundColor(SkColor c) -{ - WebCore::FrameView* view = m_mainFrame->view(); - if (!view) - return; - - // need (int) cast to find the right constructor - WebCore::Color bcolor((int)SkColorGetR(c), (int)SkColorGetG(c), - (int)SkColorGetB(c), (int)SkColorGetA(c)); - view->setBaseBackgroundColor(bcolor); - - // Background color of 0 indicates we want a transparent background - if (c == 0) - view->setTransparent(true); -} - -jclass WebViewCore::getPluginClass(const WTF::String& libName, const char* className) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - - jstring libString = wtfStringToJstring(env, libName); - jstring classString = env->NewStringUTF(className); - jobject pluginClass = env->CallObjectMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_getPluginClass, - libString, classString); - checkException(env); - - // cleanup unneeded local JNI references - env->DeleteLocalRef(libString); - env->DeleteLocalRef(classString); - - if (pluginClass != NULL) { - return static_cast<jclass>(pluginClass); - } else { - return NULL; - } -} - -void WebViewCore::showFullScreenPlugin(jobject childView, NPP npp) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = m_javaGlue->object(env); - - env->CallVoidMethod(obj.get(), - m_javaGlue->m_showFullScreenPlugin, childView, (int)npp); - checkException(env); -} - -void WebViewCore::hideFullScreenPlugin() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_hideFullScreenPlugin); - checkException(env); -} - -jobject WebViewCore::createSurface(jobject view) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject result = env->CallObjectMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_createSurface, view); - checkException(env); - return result; -} - -jobject WebViewCore::addSurface(jobject view, int x, int y, int width, int height) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject result = env->CallObjectMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_addSurface, - view, x, y, width, height); - checkException(env); - return result; -} - -void WebViewCore::updateSurface(jobject childView, int x, int y, int width, int height) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_updateSurface, childView, - x, y, width, height); - checkException(env); -} - -void WebViewCore::destroySurface(jobject childView) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_destroySurface, childView); - checkException(env); -} - -jobject WebViewCore::getContext() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject obj = m_javaGlue->object(env); - - jobject result = env->CallObjectMethod(obj.get(), m_javaGlue->m_getContext); - checkException(env); - return result; -} - -void WebViewCore::keepScreenOn(bool screenOn) { - if ((screenOn && m_screenOnCounter == 0) || (!screenOn && m_screenOnCounter == 1)) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_keepScreenOn, screenOn); - checkException(env); - } - - // update the counter - if (screenOn) - m_screenOnCounter++; - else if (m_screenOnCounter > 0) - m_screenOnCounter--; -} - -bool WebViewCore::validNodeAndBounds(Frame* frame, Node* node, - const IntRect& originalAbsoluteBounds) -{ - bool valid = CacheBuilder::validNode(m_mainFrame, frame, node); - if (!valid) - return false; - RenderObject* renderer = node->renderer(); - if (!renderer) - return false; - IntRect absBounds = node->hasTagName(HTMLNames::areaTag) - ? CacheBuilder::getAreaRect(static_cast<HTMLAreaElement*>(node)) - : renderer->absoluteBoundingBoxRect(); - return absBounds == originalAbsoluteBounds; -} - -void WebViewCore::showRect(int left, int top, int width, int height, - int contentWidth, int contentHeight, float xPercentInDoc, - float xPercentInView, float yPercentInDoc, float yPercentInView) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_showRect, - left, top, width, height, contentWidth, contentHeight, - xPercentInDoc, xPercentInView, yPercentInDoc, yPercentInView); - checkException(env); -} - -void WebViewCore::centerFitRect(int x, int y, int width, int height) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_centerFitRect, x, y, width, height); - checkException(env); -} - - -void WebViewCore::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setScrollbarModes, - horizontalMode, verticalMode); - checkException(env); -} - -void WebViewCore::notifyWebAppCanBeInstalled() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setInstallableWebApp); - checkException(env); -} - -#if ENABLE(VIDEO) -void WebViewCore::enterFullscreenForVideoLayer(int layerId, const WTF::String& url) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jUrlStr = wtfStringToJstring(env, url); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_enterFullscreenForVideoLayer, layerId, jUrlStr); - checkException(env); -} -#endif - -void WebViewCore::setWebTextViewAutoFillable(int queryId, const string16& previewSummary) -{ -#if ENABLE(WEB_AUTOFILL) - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring preview = env->NewString(previewSummary.data(), previewSummary.length()); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setWebTextViewAutoFillable, queryId, preview); - env->DeleteLocalRef(preview); -#endif -} - -bool WebViewCore::drawIsPaused() const -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - return env->GetBooleanField(m_javaGlue->object(env).get(), - gWebViewCoreFields.m_drawIsPaused); -} - -#if USE(CHROME_NETWORK_STACK) -void WebViewCore::setWebRequestContextUserAgent() -{ - // We cannot create a WebRequestContext, because we might not know it this is a private tab or not yet - if (m_webRequestContext) - m_webRequestContext->setUserAgent(WebFrame::getWebFrame(m_mainFrame)->userAgentForURL(0)); // URL not used -} - -void WebViewCore::setWebRequestContextCacheMode(int cacheMode) -{ - m_cacheMode = cacheMode; - // We cannot create a WebRequestContext, because we might not know it this is a private tab or not yet - if (!m_webRequestContext) - return; - - m_webRequestContext->setCacheMode(cacheMode); -} - -WebRequestContext* WebViewCore::webRequestContext() -{ - if (!m_webRequestContext) { - Settings* settings = mainFrame()->settings(); - m_webRequestContext = new WebRequestContext(settings && settings->privateBrowsingEnabled()); - setWebRequestContextUserAgent(); - setWebRequestContextCacheMode(m_cacheMode); - } - return m_webRequestContext.get(); -} -#endif - -void WebViewCore::scrollRenderLayer(int layer, const SkRect& rect) -{ -#if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* root = graphicsRootLayer(); - if (!root) - return; - - LayerAndroid* layerAndroid = root->platformLayer(); - if (!layerAndroid) - return; - - LayerAndroid* target = layerAndroid->findById(layer); - if (!target) - return; - - RenderLayer* owner = target->owningLayer(); - if (!owner) - return; - - if (owner->stackingContext()) - owner->scrollToOffset(rect.fLeft, rect.fTop, true, false); -#endif -} - -//---------------------------------------------------------------------- -// Native JNI methods -//---------------------------------------------------------------------- -static void RevealSelection(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->revealSelection(); -} - -static jstring RequestLabel(JNIEnv *env, jobject obj, int framePointer, - int nodePointer) -{ - return wtfStringToJstring(env, GET_NATIVE_VIEW(env, obj)->requestLabel( - (WebCore::Frame*) framePointer, (WebCore::Node*) nodePointer)); -} - -static void ClearContent(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - viewImpl->clearContent(); -} - -static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->updateFrameCacheIfLoading(); -} - -static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, - jint textWrapWidth, jfloat scale, jint screenWidth, jint screenHeight, - jint anchorX, jint anchorY, jboolean ignoreHeight) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOGV("webviewcore::nativeSetSize(%u %u)\n viewImpl: %p", (unsigned)width, (unsigned)height, viewImpl); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetSize"); - viewImpl->setSizeScreenWidthAndScale(width, height, textWrapWidth, scale, - screenWidth, screenHeight, anchorX, anchorY, ignoreHeight); -} - -static void SetScrollOffset(JNIEnv *env, jobject obj, jint gen, jboolean sendScrollEvent, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "need viewImpl"); - - viewImpl->setScrollOffset(gen, sendScrollEvent, x, y); -} - -static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h, - jint v) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "need viewImpl"); - - viewImpl->setGlobalBounds(x, y, h, v); -} - -static jboolean Key(JNIEnv *env, jobject obj, jint keyCode, jint unichar, - jint repeatCount, jboolean isShift, jboolean isAlt, jboolean isSym, - jboolean isDown) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - return GET_NATIVE_VIEW(env, obj)->key(PlatformKeyboardEvent(keyCode, - unichar, repeatCount, isDown, isShift, isAlt, isSym)); -} - -static void Click(JNIEnv *env, jobject obj, int framePtr, int nodePtr, jboolean fake) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in Click"); - - viewImpl->click(reinterpret_cast<WebCore::Frame*>(framePtr), - reinterpret_cast<WebCore::Node*>(nodePtr), fake); -} - -static void ContentInvalidateAll(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->contentInvalidateAll(); -} - -static void DeleteSelection(JNIEnv *env, jobject obj, jint start, jint end, - jint textGeneration) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - viewImpl->deleteSelection(start, end, textGeneration); -} - -static void SetSelection(JNIEnv *env, jobject obj, jint start, jint end) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - viewImpl->setSelection(start, end); -} - -static jstring ModifySelection(JNIEnv *env, jobject obj, jint direction, jint granularity) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - String selectionString = viewImpl->modifySelection(direction, granularity); - return wtfStringToJstring(env, selectionString); -} - -static void ReplaceTextfieldText(JNIEnv *env, jobject obj, - jint oldStart, jint oldEnd, jstring replace, jint start, jint end, - jint textGeneration) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - WTF::String webcoreString = jstringToWtfString(env, replace); - viewImpl->replaceTextfieldText(oldStart, - oldEnd, webcoreString, start, end, textGeneration); -} - -static void PassToJs(JNIEnv *env, jobject obj, - jint generation, jstring currentText, jint keyCode, - jint keyValue, jboolean down, jboolean cap, jboolean fn, jboolean sym) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WTF::String current = jstringToWtfString(env, currentText); - GET_NATIVE_VIEW(env, obj)->passToJs(generation, current, - PlatformKeyboardEvent(keyCode, keyValue, 0, down, cap, fn, sym)); -} - -static void ScrollFocusedTextInput(JNIEnv *env, jobject obj, jfloat xPercent, - jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - viewImpl->scrollFocusedTextInput(xPercent, y); -} - -static void SetFocusControllerActive(JNIEnv *env, jobject obj, jboolean active) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - LOGV("webviewcore::nativeSetFocusControllerActive()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetFocusControllerActive"); - viewImpl->setFocusControllerActive(active); -} - -static void SaveDocumentState(JNIEnv *env, jobject obj, jint frame) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - LOGV("webviewcore::nativeSaveDocumentState()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSaveDocumentState"); - viewImpl->saveDocumentState((WebCore::Frame*) frame); -} - -void WebViewCore::addVisitedLink(const UChar* string, int length) -{ - if (m_groupForVisitedLinks) - m_groupForVisitedLinks->addVisitedLink(string, length); -} - -static jint UpdateLayers(JNIEnv *env, jobject obj, jobject region) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - BaseLayerAndroid* result = viewImpl->createBaseLayer(); - SkRegion* nativeRegion = GraphicsJNI::getNativeRegion(env, region); - if (result) { - SkIRect bounds; - LayerAndroid* root = static_cast<LayerAndroid*>(result->getChild(0)); - if (root) { - root->bounds().roundOut(&bounds); - nativeRegion->setRect(bounds); - } - } - return reinterpret_cast<jint>(result); -} - -static jint RecordContent(JNIEnv *env, jobject obj, jobject region, jobject pt) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - SkRegion* nativeRegion = GraphicsJNI::getNativeRegion(env, region); - SkIPoint nativePt; - BaseLayerAndroid* result = viewImpl->recordContent(nativeRegion, &nativePt); - GraphicsJNI::ipoint_to_jpoint(nativePt, env, pt); - return reinterpret_cast<jint>(result); -} - -static void SplitContent(JNIEnv *env, jobject obj, jint content) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - viewImpl->splitContent(reinterpret_cast<PictureSet*>(content)); -} - -static void SendListBoxChoice(JNIEnv* env, jobject obj, jint choice) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoice"); - viewImpl->popupReply(choice); -} - -// Set aside a predetermined amount of space in which to place the listbox -// choices, to avoid unnecessary allocations. -// The size here is arbitrary. We want the size to be at least as great as the -// number of items in the average multiple-select listbox. -#define PREPARED_LISTBOX_STORAGE 10 - -static void SendListBoxChoices(JNIEnv* env, jobject obj, jbooleanArray jArray, - jint size) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativeSendListBoxChoices"); - jboolean* ptrArray = env->GetBooleanArrayElements(jArray, 0); - SkAutoSTMalloc<PREPARED_LISTBOX_STORAGE, int> storage(size); - int* array = storage.get(); - int count = 0; - for (int i = 0; i < size; i++) { - if (ptrArray[i]) { - array[count++] = i; - } - } - env->ReleaseBooleanArrayElements(jArray, ptrArray, JNI_ABORT); - viewImpl->popupReply(array, count); -} - -static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr, - jboolean caseInsensitive) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - if (!addr) - return 0; - int length = env->GetStringLength(addr); - if (!length) - return 0; - const jchar* addrChars = env->GetStringChars(addr, 0); - int start, end; - bool success = CacheBuilder::FindAddress(addrChars, length, - &start, &end, caseInsensitive) == CacheBuilder::FOUND_COMPLETE; - jstring ret = 0; - if (success) - ret = env->NewString(addrChars + start, end - start); - env->ReleaseStringChars(addr, addrChars); - return ret; -} - -static jboolean HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jintArray idArray, - jintArray xArray, jintArray yArray, - jint count, jint actionIndex, jint metaState) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - jint* ptrIdArray = env->GetIntArrayElements(idArray, 0); - jint* ptrXArray = env->GetIntArrayElements(xArray, 0); - jint* ptrYArray = env->GetIntArrayElements(yArray, 0); - Vector<int> ids(count); - Vector<IntPoint> points(count); - for (int c = 0; c < count; c++) { - ids[c] = ptrIdArray[c]; - points[c].setX(ptrXArray[c]); - points[c].setY(ptrYArray[c]); - } - env->ReleaseIntArrayElements(idArray, ptrIdArray, JNI_ABORT); - env->ReleaseIntArrayElements(xArray, ptrXArray, JNI_ABORT); - env->ReleaseIntArrayElements(yArray, ptrYArray, JNI_ABORT); - - return viewImpl->handleTouchEvent(action, ids, points, actionIndex, metaState); -} - -static void TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, - jint frame, jint node, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->touchUp(touchGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y); -} - -static jstring RetrieveHref(JNIEnv *env, jobject obj, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WTF::String result = viewImpl->retrieveHref(x, y); - if (!result.isEmpty()) - return wtfStringToJstring(env, result); - return 0; -} - -static jstring RetrieveAnchorText(JNIEnv *env, jobject obj, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - WTF::String result = viewImpl->retrieveAnchorText(x, y); - if (!result.isEmpty()) - return wtfStringToJstring(env, result); - return 0; -} - -static jstring RetrieveImageSource(JNIEnv *env, jobject obj, jint x, jint y) -{ - WTF::String result = GET_NATIVE_VIEW(env, obj)->retrieveImageSource(x, y); - return !result.isEmpty() ? wtfStringToJstring(env, result) : 0; -} - -static void StopPaintingCaret(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->setShouldPaintCaret(false); -} - -static void MoveFocus(JNIEnv *env, jobject obj, jint framePtr, jint nodePtr) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->moveFocus((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr); -} - -static void MoveMouse(JNIEnv *env, jobject obj, jint frame, - jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->moveMouse((WebCore::Frame*) frame, x, y); -} - -static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, - jint frame, jint x, jint y) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->moveMouseIfLatest(moveGeneration, - (WebCore::Frame*) frame, x, y); -} - -static void UpdateFrameCache(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->updateFrameCache(); -} - -static jint GetContentMinPrefWidth(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Frame* frame = viewImpl->mainFrame(); - if (frame) { - WebCore::Document* document = frame->document(); - if (document) { - WebCore::RenderObject* renderer = document->renderer(); - if (renderer && renderer->isRenderView()) { - return renderer->minPreferredLogicalWidth(); - } - } - } - return 0; -} - -static void SetViewportSettingsFromNative(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - WebCore::Settings* s = viewImpl->mainFrame()->page()->settings(); - if (!s) - return; - -#ifdef ANDROID_META_SUPPORT - env->SetIntField(obj, gWebViewCoreFields.m_viewportWidth, s->viewportWidth()); - env->SetIntField(obj, gWebViewCoreFields.m_viewportHeight, s->viewportHeight()); - env->SetIntField(obj, gWebViewCoreFields.m_viewportInitialScale, s->viewportInitialScale()); - env->SetIntField(obj, gWebViewCoreFields.m_viewportMinimumScale, s->viewportMinimumScale()); - env->SetIntField(obj, gWebViewCoreFields.m_viewportMaximumScale, s->viewportMaximumScale()); - env->SetBooleanField(obj, gWebViewCoreFields.m_viewportUserScalable, s->viewportUserScalable()); - env->SetIntField(obj, gWebViewCoreFields.m_viewportDensityDpi, s->viewportTargetDensityDpi()); -#endif -} - -static void SetBackgroundColor(JNIEnv *env, jobject obj, jint color) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->setBackgroundColor((SkColor) color); -} - -static void DumpDomTree(JNIEnv *env, jobject obj, jboolean useFile) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->dumpDomTree(useFile); -} - -static void DumpRenderTree(JNIEnv *env, jobject obj, jboolean useFile) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->dumpRenderTree(useFile); -} - -static void DumpNavTree(JNIEnv *env, jobject obj) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - viewImpl->dumpNavTree(); -} - -static void DumpV8Counters(JNIEnv*, jobject) -{ -#if USE(V8) -#ifdef ANDROID_INSTRUMENT - V8Counters::dumpCounters(); -#endif -#endif -} - -static void SetJsFlags(JNIEnv *env, jobject obj, jstring flags) -{ -#if USE(V8) - WTF::String flagsString = jstringToWtfString(env, flags); - WTF::CString utf8String = flagsString.utf8(); - WebCore::ScriptController::setFlags(utf8String.data(), utf8String.length()); -#endif -} - - -// Called from the Java side to set a new quota for the origin or new appcache -// max size in response to a notification that the original quota was exceeded or -// that the appcache has reached its maximum size. -static void SetNewStorageLimit(JNIEnv* env, jobject obj, jlong quota) { -#if ENABLE(DATABASE) || ENABLE(OFFLINE_WEB_APPLICATIONS) - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - Frame* frame = viewImpl->mainFrame(); - - // The main thread is blocked awaiting this response, so now we can wake it - // up. - ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(frame->page()->chrome()->client()); - chromeC->wakeUpMainThreadWithNewQuota(quota); -#endif -} - -// Called from Java to provide a Geolocation permission state for the specified origin. -static void GeolocationPermissionsProvide(JNIEnv* env, jobject obj, jstring origin, jboolean allow, jboolean remember) { - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - Frame* frame = viewImpl->mainFrame(); - - ChromeClientAndroid* chromeClient = static_cast<ChromeClientAndroid*>(frame->page()->chrome()->client()); - chromeClient->provideGeolocationPermissions(jstringToWtfString(env, origin), allow, remember); -} - -static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jstring scheme) { -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); -#endif - WebCore::SchemeRegistry::registerURLSchemeAsLocal(jstringToWtfString(env, scheme)); -} - -static bool FocusBoundsChanged(JNIEnv* env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->focusBoundsChanged(); -} - -static void Pause(JNIEnv* env, jobject obj) -{ - // This is called for the foreground tab when the browser is put to the - // background (and also for any tab when it is put to the background of the - // 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. - ChromeClient* chromeClient = GET_NATIVE_VIEW(env, obj)->mainFrame()->page()->chrome()->client(); - ChromeClientAndroid* chromeClientAndroid = static_cast<ChromeClientAndroid*>(chromeClient); - chromeClientAndroid->storeGeolocationPermissions(); - - Frame* mainFrame = GET_NATIVE_VIEW(env, obj)->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { - Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation(); - if (geolocation) - geolocation->suspend(); - } - - GET_NATIVE_VIEW(env, obj)->deviceMotionAndOrientationManager()->maybeSuspendClients(); - - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kPause_ANPLifecycleAction; - GET_NATIVE_VIEW(env, obj)->sendPluginEvent(event); - - GET_NATIVE_VIEW(env, obj)->setIsPaused(true); -} - -static void Resume(JNIEnv* env, jobject obj) -{ - Frame* mainFrame = GET_NATIVE_VIEW(env, obj)->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { - Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation(); - if (geolocation) - geolocation->resume(); - } - - GET_NATIVE_VIEW(env, obj)->deviceMotionAndOrientationManager()->maybeResumeClients(); - - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kResume_ANPLifecycleAction; - GET_NATIVE_VIEW(env, obj)->sendPluginEvent(event); - - GET_NATIVE_VIEW(env, obj)->setIsPaused(false); -} - -static void FreeMemory(JNIEnv* env, jobject obj) -{ - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kFreeMemory_ANPLifecycleAction; - GET_NATIVE_VIEW(env, obj)->sendPluginEvent(event); -} - -static void ProvideVisitedHistory(JNIEnv *env, jobject obj, jobject hist) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - - jobjectArray array = static_cast<jobjectArray>(hist); - - jsize len = env->GetArrayLength(array); - for (jsize i = 0; i < len; i++) { - jstring item = static_cast<jstring>(env->GetObjectArrayElement(array, i)); - const UChar* str = static_cast<const UChar*>(env->GetStringChars(item, 0)); - jsize len = env->GetStringLength(item); - viewImpl->addVisitedLink(str, len); - env->ReleaseStringChars(item, str); - env->DeleteLocalRef(item); - } -} - -// Notification from the UI thread that the plugin's full-screen surface has been discarded -static void FullScreenPluginHidden(JNIEnv* env, jobject obj, jint npp) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - PluginWidgetAndroid* plugin = viewImpl->getPluginWidget((NPP)npp); - if (plugin) - plugin->exitFullScreen(false); -} - -static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - return WebCore::IntRect(L, T, R - L, B - T); -} - -static bool ValidNodeAndBounds(JNIEnv *env, jobject obj, int frame, int node, - jobject rect) -{ - IntRect nativeRect = jrect_to_webrect(env, rect); - return GET_NATIVE_VIEW(env, obj)->validNodeAndBounds( - reinterpret_cast<Frame*>(frame), - reinterpret_cast<Node*>(node), nativeRect); -} - -static jobject GetTouchHighlightRects(JNIEnv* env, jobject obj, jint x, jint y, jint slop) -{ - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - if (!viewImpl) - return 0; - Vector<IntRect> rects = viewImpl->getTouchHighlightRects(x, y, slop); - if (rects.isEmpty()) - return 0; - - jclass arrayClass = env->FindClass("java/util/ArrayList"); - LOG_ASSERT(arrayClass, "Could not find java/util/ArrayList"); - jmethodID init = env->GetMethodID(arrayClass, "<init>", "(I)V"); - LOG_ASSERT(init, "Could not find constructor for ArrayList"); - jobject array = env->NewObject(arrayClass, init, rects.size()); - LOG_ASSERT(array, "Could not create a new ArrayList"); - jmethodID add = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z"); - LOG_ASSERT(add, "Could not find add method on ArrayList"); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find android/graphics/Rect"); - jmethodID rectinit = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(rectinit, "Could not find init method on Rect"); - - for (size_t i = 0; i < rects.size(); i++) { - jobject rect = env->NewObject(rectClass, rectinit, rects[i].x(), - rects[i].y(), rects[i].right(), rects[i].bottom()); - if (rect) { - env->CallBooleanMethod(array, add, rect); - env->DeleteLocalRef(rect); - } - } - - env->DeleteLocalRef(rectClass); - env->DeleteLocalRef(arrayClass); - return array; -} - -static void AutoFillForm(JNIEnv* env, jobject obj, jint queryId) -{ -#if ENABLE(WEB_AUTOFILL) - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - if (!viewImpl) - return; - - WebCore::Frame* frame = viewImpl->mainFrame(); - if (frame) { - EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(frame->page()->editorClient()); - WebAutoFill* autoFill = editorC->getAutoFill(); - autoFill->fillFormFields(queryId); - } -#endif -} - -static void ScrollRenderLayer(JNIEnv* env, jobject obj, jint layer, jobject jRect) -{ - SkRect rect; - GraphicsJNI::jrect_to_rect(env, jRect, &rect); - GET_NATIVE_VIEW(env, obj)->scrollRenderLayer(layer, rect); -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gJavaWebViewCoreMethods[] = { - { "nativeClearContent", "()V", - (void*) ClearContent }, - { "nativeFocusBoundsChanged", "()Z", - (void*) FocusBoundsChanged } , - { "nativeKey", "(IIIZZZZ)Z", - (void*) Key }, - { "nativeClick", "(IIZ)V", - (void*) Click }, - { "nativeContentInvalidateAll", "()V", - (void*) ContentInvalidateAll }, - { "nativeSendListBoxChoices", "([ZI)V", - (void*) SendListBoxChoices }, - { "nativeSendListBoxChoice", "(I)V", - (void*) SendListBoxChoice }, - { "nativeSetSize", "(IIIFIIIIZ)V", - (void*) SetSize }, - { "nativeSetScrollOffset", "(IZII)V", - (void*) SetScrollOffset }, - { "nativeSetGlobalBounds", "(IIII)V", - (void*) SetGlobalBounds }, - { "nativeSetSelection", "(II)V", - (void*) SetSelection } , - { "nativeModifySelection", "(II)Ljava/lang/String;", - (void*) ModifySelection }, - { "nativeDeleteSelection", "(III)V", - (void*) DeleteSelection } , - { "nativeReplaceTextfieldText", "(IILjava/lang/String;III)V", - (void*) ReplaceTextfieldText } , - { "nativeMoveFocus", "(II)V", - (void*) MoveFocus }, - { "nativeMoveMouse", "(III)V", - (void*) MoveMouse }, - { "nativeMoveMouseIfLatest", "(IIII)V", - (void*) MoveMouseIfLatest }, - { "passToJs", "(ILjava/lang/String;IIZZZZ)V", - (void*) PassToJs }, - { "nativeScrollFocusedTextInput", "(FI)V", - (void*) ScrollFocusedTextInput }, - { "nativeSetFocusControllerActive", "(Z)V", - (void*) SetFocusControllerActive }, - { "nativeSaveDocumentState", "(I)V", - (void*) SaveDocumentState }, - { "nativeFindAddress", "(Ljava/lang/String;Z)Ljava/lang/String;", - (void*) FindAddress }, - { "nativeHandleTouchEvent", "(I[I[I[IIII)Z", - (void*) HandleTouchEvent }, - { "nativeTouchUp", "(IIIII)V", - (void*) TouchUp }, - { "nativeRetrieveHref", "(II)Ljava/lang/String;", - (void*) RetrieveHref }, - { "nativeRetrieveAnchorText", "(II)Ljava/lang/String;", - (void*) RetrieveAnchorText }, - { "nativeRetrieveImageSource", "(II)Ljava/lang/String;", - (void*) RetrieveImageSource }, - { "nativeStopPaintingCaret", "()V", - (void*) StopPaintingCaret }, - { "nativeUpdateFrameCache", "()V", - (void*) UpdateFrameCache }, - { "nativeGetContentMinPrefWidth", "()I", - (void*) GetContentMinPrefWidth }, - { "nativeUpdateLayers", "(Landroid/graphics/Region;)I", - (void*) UpdateLayers }, - { "nativeRecordContent", "(Landroid/graphics/Region;Landroid/graphics/Point;)I", - (void*) RecordContent }, - { "setViewportSettingsFromNative", "()V", - (void*) SetViewportSettingsFromNative }, - { "nativeSplitContent", "(I)V", - (void*) SplitContent }, - { "nativeSetBackgroundColor", "(I)V", - (void*) SetBackgroundColor }, - { "nativeRegisterURLSchemeAsLocal", "(Ljava/lang/String;)V", - (void*) RegisterURLSchemeAsLocal }, - { "nativeDumpDomTree", "(Z)V", - (void*) DumpDomTree }, - { "nativeDumpRenderTree", "(Z)V", - (void*) DumpRenderTree }, - { "nativeDumpNavTree", "()V", - (void*) DumpNavTree }, - { "nativeDumpV8Counters", "()V", - (void*) DumpV8Counters }, - { "nativeSetNewStorageLimit", "(J)V", - (void*) SetNewStorageLimit }, - { "nativeGeolocationPermissionsProvide", "(Ljava/lang/String;ZZ)V", - (void*) GeolocationPermissionsProvide }, - { "nativePause", "()V", (void*) Pause }, - { "nativeResume", "()V", (void*) Resume }, - { "nativeFreeMemory", "()V", (void*) FreeMemory }, - { "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags }, - { "nativeRequestLabel", "(II)Ljava/lang/String;", - (void*) RequestLabel }, - { "nativeRevealSelection", "()V", (void*) RevealSelection }, - { "nativeUpdateFrameCacheIfLoading", "()V", - (void*) UpdateFrameCacheIfLoading }, - { "nativeProvideVisitedHistory", "([Ljava/lang/String;)V", - (void*) ProvideVisitedHistory }, - { "nativeFullScreenPluginHidden", "(I)V", - (void*) FullScreenPluginHidden }, - { "nativeValidNodeAndBounds", "(IILandroid/graphics/Rect;)Z", - (void*) ValidNodeAndBounds }, - { "nativeGetTouchHighlightRects", "(III)Ljava/util/ArrayList;", - (void*) GetTouchHighlightRects }, - { "nativeAutoFillForm", "(I)V", - (void*) AutoFillForm }, - { "nativeScrollLayer", "(ILandroid/graphics/Rect;)V", - (void*) ScrollRenderLayer }, -}; - -int registerWebViewCore(JNIEnv* env) -{ - jclass widget = env->FindClass("android/webkit/WebViewCore"); - LOG_ASSERT(widget, - "Unable to find class android/webkit/WebViewCore"); - gWebViewCoreFields.m_nativeClass = env->GetFieldID(widget, "mNativeClass", - "I"); - LOG_ASSERT(gWebViewCoreFields.m_nativeClass, - "Unable to find android/webkit/WebViewCore.mNativeClass"); - gWebViewCoreFields.m_viewportWidth = env->GetFieldID(widget, - "mViewportWidth", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportWidth, - "Unable to find android/webkit/WebViewCore.mViewportWidth"); - gWebViewCoreFields.m_viewportHeight = env->GetFieldID(widget, - "mViewportHeight", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportHeight, - "Unable to find android/webkit/WebViewCore.mViewportHeight"); - gWebViewCoreFields.m_viewportInitialScale = env->GetFieldID(widget, - "mViewportInitialScale", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportInitialScale, - "Unable to find android/webkit/WebViewCore.mViewportInitialScale"); - gWebViewCoreFields.m_viewportMinimumScale = env->GetFieldID(widget, - "mViewportMinimumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportMinimumScale, - "Unable to find android/webkit/WebViewCore.mViewportMinimumScale"); - gWebViewCoreFields.m_viewportMaximumScale = env->GetFieldID(widget, - "mViewportMaximumScale", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportMaximumScale, - "Unable to find android/webkit/WebViewCore.mViewportMaximumScale"); - gWebViewCoreFields.m_viewportUserScalable = env->GetFieldID(widget, - "mViewportUserScalable", "Z"); - LOG_ASSERT(gWebViewCoreFields.m_viewportUserScalable, - "Unable to find android/webkit/WebViewCore.mViewportUserScalable"); - gWebViewCoreFields.m_viewportDensityDpi = env->GetFieldID(widget, - "mViewportDensityDpi", "I"); - LOG_ASSERT(gWebViewCoreFields.m_viewportDensityDpi, - "Unable to find android/webkit/WebViewCore.mViewportDensityDpi"); - gWebViewCoreFields.m_webView = env->GetFieldID(widget, - "mWebView", "Landroid/webkit/WebView;"); - LOG_ASSERT(gWebViewCoreFields.m_webView, - "Unable to find android/webkit/WebViewCore.mWebView"); - gWebViewCoreFields.m_drawIsPaused = env->GetFieldID(widget, - "mDrawIsPaused", "Z"); - LOG_ASSERT(gWebViewCoreFields.m_drawIsPaused, - "Unable to find android/webkit/WebViewCore.mDrawIsPaused"); - gWebViewCoreFields.m_lowMemoryUsageMb = env->GetFieldID(widget, "mLowMemoryUsageThresholdMb", "I"); - gWebViewCoreFields.m_highMemoryUsageMb = env->GetFieldID(widget, "mHighMemoryUsageThresholdMb", "I"); - gWebViewCoreFields.m_highUsageDeltaMb = env->GetFieldID(widget, "mHighUsageDeltaMb", "I"); - - gWebViewCoreStaticMethods.m_isSupportedMediaMimeType = - env->GetStaticMethodID(widget, "isSupportedMediaMimeType", "(Ljava/lang/String;)Z"); - LOG_FATAL_IF(!gWebViewCoreStaticMethods.m_isSupportedMediaMimeType, - "Could not find static method isSupportedMediaMimeType from WebViewCore"); - - env->DeleteLocalRef(widget); - - return jniRegisterNativeMethods(env, "android/webkit/WebViewCore", - gJavaWebViewCoreMethods, NELEM(gJavaWebViewCoreMethods)); -} - -} /* namespace android */ diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h deleted file mode 100644 index 8d8f303..0000000 --- a/WebKit/android/jni/WebViewCore.h +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright 2006, 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 WEBVIEWCORE_H -#define WEBVIEWCORE_H - -#include "CacheBuilder.h" -#include "CachedHistory.h" -#include "DeviceMotionAndOrientationManager.h" -#include "DOMSelection.h" -#include "FileChooser.h" -#include "PictureSet.h" -#include "PlatformGraphicsContext.h" -#include "SkColor.h" -#include "SkTDArray.h" -#include "SkRegion.h" -#include "Timer.h" -#include "WebCoreRefObject.h" -#include "WebCoreJni.h" -#include "WebRequestContext.h" -#include "android_npapi.h" - -#include <jni.h> -#include <ui/KeycodeLabels.h> -#include <ui/PixelFormat.h> - -namespace WebCore { - class Color; - class FrameView; - class HTMLAnchorElement; - class HTMLElement; - class HTMLImageElement; - class HTMLSelectElement; - class RenderPart; - class RenderText; - class Node; - class PlatformKeyboardEvent; - class QualifiedName; - class RenderTextControl; - class ScrollView; - class TimerBase; - class PageGroup; -} - -#if USE(ACCELERATED_COMPOSITING) -namespace WebCore { - class GraphicsLayerAndroid; -} -#endif - -namespace WebCore { - class BaseLayerAndroid; -} - -struct PluginWidgetAndroid; -class SkPicture; -class SkIRect; - -namespace android { - - enum Direction { - DIRECTION_BACKWARD = 0, - DIRECTION_FORWARD = 1 - }; - - enum NavigationAxis { - AXIS_CHARACTER = 0, - AXIS_WORD = 1, - AXIS_SENTENCE = 2, - AXIS_HEADING = 3, - AXIS_SIBLING = 4, - AXIS_PARENT_FIRST_CHILD = 5, - AXIS_DOCUMENT = 6 - }; - - class CachedFrame; - class CachedNode; - class CachedRoot; - class ListBoxReply; - - class WebCoreReply : public WebCoreRefObject { - public: - virtual ~WebCoreReply() {} - - virtual void replyInt(int value) { - SkDEBUGF(("WebCoreReply::replyInt(%d) not handled\n", value)); - } - - virtual void replyIntArray(const int* array, int count) { - SkDEBUGF(("WebCoreReply::replyIntArray() not handled\n")); - } - // add more replyFoo signatures as needed - }; - - // one instance of WebViewCore per page for calling into Java's WebViewCore - class WebViewCore : public WebCoreRefObject { - public: - /** - * Initialize the native WebViewCore with a JNI environment, a Java - * WebViewCore object and the main frame. - */ - WebViewCore(JNIEnv* env, jobject javaView, WebCore::Frame* mainframe); - ~WebViewCore(); - - // helper function - static WebViewCore* getWebViewCore(const WebCore::FrameView* view); - static WebViewCore* getWebViewCore(const WebCore::ScrollView* view); - - // Followings are called from native WebCore to Java - - /** - * Notification that a form was blurred. Pass a message to hide the - * keyboard if it was showing for that Node. - * @param Node The Node that blurred. - */ - void formDidBlur(const WebCore::Node*); - void focusNodeChanged(const WebCore::Node*); - - /** - * Scroll to an absolute position. - * @param x The x coordinate. - * @param y The y coordinate. - * @param animate If it is true, animate to the new scroll position - * - * This method calls Java to trigger a gradual scroll event. - */ - void scrollTo(int x, int y, bool animate = false); - - /** - * Record the invalid rectangle - */ - void contentInvalidate(const WebCore::IntRect &rect); - void contentInvalidateAll(); - - /** - * Satisfy any outstanding invalidates, so that the current state - * of the DOM is drawn. - */ - void contentDraw(); - - /** - * copy the layers to the UI side - */ - void layersDraw(); - -#if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* graphicsRootLayer() const; -#endif - - /** Invalidate the view/screen, NOT the content/DOM, but expressed in - * content/DOM coordinates (i.e. they need to eventually be scaled, - * by webview into view.java coordinates - */ - void viewInvalidate(const WebCore::IntRect& rect); - - /** - * Invalidate part of the content that may be offscreen at the moment - */ - void offInvalidate(const WebCore::IntRect &rect); - - /** - * Called by webcore when the progress indicator is done - * used to rebuild and display any changes in focus - */ - void notifyProgressFinished(); - - /** - * Notify the view that WebCore did its first layout. - */ - void didFirstLayout(); - - /** - * Notify the view to update the viewport. - */ - void updateViewport(); - - /** - * Notify the view to restore the screen width, which in turn restores - * the scale. Also restore the scale for the text wrap. - */ - void restoreScale(float scale, float textWrapScale); - - /** - * 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 String - * @param text If changeToPassword is false, this is the new text that - * should go into the textfield. - */ - void updateTextfield(WebCore::Node* pointer, - bool changeToPassword, const WTF::String& text); - - /** - * Tell the java side to update the current selection in the focused - * textfield to the WebTextView. This function finds the currently - * focused textinput, and passes its selection to java. - * If there is no focus, or it is not a text input, this does nothing. - */ - void updateTextSelection(); - - void clearTextEntry(); - // JavaScript support - void jsAlert(const WTF::String& url, const WTF::String& text); - bool jsConfirm(const WTF::String& url, const WTF::String& text); - bool jsPrompt(const WTF::String& url, const WTF::String& message, - const WTF::String& defaultValue, WTF::String& result); - bool jsUnload(const WTF::String& url, const WTF::String& message); - bool jsInterrupt(); - - /** - * Tell the Java side that the origin has exceeded its database quota. - * @param url The URL of the page that caused the quota overflow - * @param databaseIdentifier the id of the database that caused the - * quota overflow. - * @param currentQuota The current quota for the origin - * @param estimatedSize The estimated size of the database - */ - void exceededDatabaseQuota(const WTF::String& url, - const WTF::String& databaseIdentifier, - const unsigned long long currentQuota, - const unsigned long long estimatedSize); - - /** - * Tell the Java side that the appcache has exceeded its max size. - * @param spaceNeeded is the amount of disk space that would be needed - * in order for the last appcache operation to succeed. - */ - void reachedMaxAppCacheSize(const unsigned long long spaceNeeded); - - /** - * Set up the PageGroup's idea of which links have been visited, - * with the browser history. - * @param group the object to deliver the links to. - */ - void populateVisitedLinks(WebCore::PageGroup*); - - /** - * Instruct the browser to show a Geolocation permission prompt for the - * specified origin. - * @param origin The origin of the frame requesting Geolocation - * permissions. - */ - void geolocationPermissionsShowPrompt(const WTF::String& origin); - /** - * Instruct the browser to hide the Geolocation permission prompt. - */ - void geolocationPermissionsHidePrompt(); - - jobject getDeviceMotionService(); - jobject getDeviceOrientationService(); - - void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel); - - /** - * Tell the Java side of the scrollbar mode - */ - void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode); - - // - // Followings support calls from Java to native WebCore - // - - WTF::String retrieveHref(int x, int y); - WTF::String retrieveAnchorText(int x, int y); - WTF::String retrieveImageSource(int x, int y); - WTF::String requestLabel(WebCore::Frame* , WebCore::Node* ); - - // If the focus is a textfield (<input>), textarea, or contentEditable, - // scroll the selection on screen (if necessary). - void revealSelection(); - // Create a single picture to represent the drawn DOM (used by navcache) - void recordPicture(SkPicture* picture); - - void moveFocus(WebCore::Frame* frame, WebCore::Node* node); - void moveMouse(WebCore::Frame* frame, int x, int y); - void moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, int x, int y); - - // set the scroll amount that webview.java is currently showing - void setScrollOffset(int moveGeneration, bool sendScrollEvent, int dx, int dy); - - void setGlobalBounds(int x, int y, int h, int v); - - void setSizeScreenWidthAndScale(int width, int height, int screenWidth, - float scale, int realScreenWidth, int screenHeight, int anchorX, - int anchorY, bool ignoreHeight); - - /** - * Handle key events from Java. - * @return Whether keyCode was handled by this class. - */ - bool key(const WebCore::PlatformKeyboardEvent& event); - - /** - * Handle (trackball) click event / dpad center press from Java. - * Also used when typing into an unfocused textfield, in which case 'fake' - * will be true. - */ - void click(WebCore::Frame* frame, WebCore::Node* node, bool fake); - - /** - * Handle touch event - */ - bool handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState); - - /** - * Handle motionUp event from the UI thread (called touchUp in the - * WebCore thread). - * @param touchGeneration Generation number for touches so we can ignore - * touches when a newer one has been generated. - * @param frame Pointer to Frame containing the node that was touched. - * @param node Pointer to Node that was touched. - * @param x x-position of the touch. - * @param y y-position of the touch. - */ - void touchUp(int touchGeneration, WebCore::Frame* frame, - WebCore::Node* node, int x, int y); - - /** - * Sets the index of the label from a popup - */ - void popupReply(int index); - void popupReply(const int* array, int count); - - /** - * Delete text from start to end in the focused textfield. - * If start == end, set the selection, but perform no deletion. - * If there is no focus, silently fail. - * If start and end are out of order, swap them. - */ - void deleteSelection(int start, int end, int textGeneration); - - /** - * Set the selection of the currently focused textfield to (start, end). - * If start and end are out of order, swap them. - */ - void setSelection(int start, int end); - - /** - * Modifies the current selection. - * - * Note: Accessibility support. - * - * direction - The direction in which to alter the selection. - * granularity - The granularity of the selection modification. - * - * returns - The selected HTML as a string. This is not a well formed - * HTML, rather the selection annotated with the tags of all - * intermediary elements it crosses. - */ - String modifySelection(const int direction, const int granularity); - - /** - * Moves the selection to the given node in a given frame i.e. selects that node. - * - * Note: Accessibility support. - * - * frame - The frame in which to select is the node to be selected. - * node - The node to be selected. - * - * returns - The selected HTML as a string. This is not a well formed - * HTML, rather the selection annotated with the tags of all - * intermediary elements it crosses. - */ - String moveSelection(WebCore::Frame* frame, WebCore::Node* node); - - /** - * In the currently focused textfield, replace the characters from oldStart to oldEnd - * (if oldStart == oldEnd, this will be an insert at that position) with replace, - * and set the selection to (start, end). - */ - void replaceTextfieldText(int oldStart, - int oldEnd, const WTF::String& replace, int start, int end, - int textGeneration); - void passToJs(int generation, - const WTF::String& , const WebCore::PlatformKeyboardEvent& ); - /** - * Scroll the focused textfield to (x, y) in document space - */ - void scrollFocusedTextInput(float x, int y); - /** - * Set the FocusController's active and focused states, so that - * the caret will draw (true) or not. - */ - void setFocusControllerActive(bool active); - - void saveDocumentState(WebCore::Frame* frame); - - void addVisitedLink(const UChar*, int); - - // TODO: I don't like this hack but I need to access the java object in - // order to send it as a parameter to java - AutoJObject getJavaObject(); - - // Return the parent WebView Java object associated with this - // WebViewCore. - jobject getWebViewJavaObject(); - - void setBackgroundColor(SkColor c); - void updateFrameCache(); - void updateCacheOnNodeChange(); - void dumpDomTree(bool); - void dumpRenderTree(bool); - void dumpNavTree(); - - /* We maintain a list of active plugins. The list is edited by the - pluginview itself. The list is used to service invals to the plugin - pageflipping bitmap. - */ - void addPlugin(PluginWidgetAndroid*); - void removePlugin(PluginWidgetAndroid*); - // returns true if the pluginwidgit is in our active list - bool isPlugin(PluginWidgetAndroid*) const; - void invalPlugin(PluginWidgetAndroid*); - void drawPlugins(); - - // send the current screen size/zoom to all of the plugins in our list - void sendPluginVisibleScreen(); - - // send onLoad event to plugins who are descendents of the given frame - void notifyPluginsOnFrameLoad(const Frame*); - - // gets a rect representing the current on-screen portion of the document - void getVisibleScreen(ANPRectI&); - - // send this event to all of the plugins in our list - void sendPluginEvent(const ANPEvent&); - - // lookup the plugin widget struct given an NPP - PluginWidgetAndroid* getPluginWidget(NPP npp); - - // return the cursorNode if it is a plugin - Node* cursorNodeIsPlugin(); - - // Notify the Java side whether it needs to pass down the touch events - void needTouchEvents(bool); - - void requestKeyboardWithSelection(const WebCore::Node*, int selStart, int selEnd); - // Notify the Java side that webkit is requesting a keyboard - void requestKeyboard(bool showKeyboard); - - // Generates a class loader that contains classes from the plugin's apk - jclass getPluginClass(const WTF::String& libName, const char* className); - - // Creates a full screen surface for a plugin - void showFullScreenPlugin(jobject webkitPlugin, NPP npp); - - // Instructs the UI thread to discard the plugin's full-screen surface - void hideFullScreenPlugin(); - - // Creates a childView for the plugin but does not attach to the view hierarchy - jobject createSurface(jobject view); - - // Adds the plugin's view (aka surface) to the view hierarchy - jobject addSurface(jobject view, int x, int y, int width, int height); - - // Updates a Surface coordinates and dimensions for a plugin - void updateSurface(jobject childView, int x, int y, int width, int height); - - // Destroys a SurfaceView for a plugin - void destroySurface(jobject childView); - - // Returns the context (android.content.Context) of the WebView - jobject getContext(); - - // Manages requests to keep the screen on while the WebView is visible - void keepScreenOn(bool screenOn); - - bool validNodeAndBounds(Frame* , Node* , const IntRect& ); - - // Make the rect (left, top, width, height) visible. If it can be fully - // fit, center it on the screen. Otherwise make sure the point specified - // by (left + xPercentInDoc * width, top + yPercentInDoc * height) - // pinned at the screen position (xPercentInView, yPercentInView). - void showRect(int left, int top, int width, int height, int contentWidth, - int contentHeight, float xPercentInDoc, float xPercentInView, - float yPercentInDoc, float yPercentInView); - - // Scale the rect (x, y, width, height) to make it just fit and centered - // in the current view. - void centerFitRect(int x, int y, int width, int height); - - // return a list of rects matching the touch point (x, y) with the slop - Vector<IntRect> getTouchHighlightRects(int x, int y, int slop); - - // Open a file chooser for selecting a file to upload - void openFileChooser(PassRefPtr<WebCore::FileChooser> ); - - // reset the picture set to empty - void clearContent(); - - bool focusBoundsChanged(); - - // record the inval area, and the picture size - BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* ); - - // This creates a new BaseLayerAndroid by copying the current m_content - // and doing a copy of the layers. The layers' content may be updated - // as we are calling layersSync(). - BaseLayerAndroid* createBaseLayer(); - - int textWrapWidth() const { return m_textWrapWidth; } - float scale() const { return m_scale; } - float textWrapScale() const { return m_screenWidth * m_scale / m_textWrapWidth; } - WebCore::Frame* mainFrame() const { return m_mainFrame; } - void updateCursorBounds(const CachedRoot* root, - const CachedFrame* cachedFrame, const CachedNode* cachedNode); - void updateFrameCacheIfLoading(); - - // utility to split slow parts of the picture set - void splitContent(PictureSet*); - - void notifyWebAppCanBeInstalled(); - -#if ENABLE(VIDEO) - void enterFullscreenForVideoLayer(int layerId, const WTF::String& url); -#endif - - void setWebTextViewAutoFillable(int queryId, const string16& previewSummary); - - DeviceMotionAndOrientationManager* deviceMotionAndOrientationManager() { return &m_deviceMotionAndOrientationManager; } - - 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 shouldPaintCaret() { return m_shouldPaintCaret; } - void setShouldPaintCaret(bool should) { m_shouldPaintCaret = should; } - 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; } - int screenHeight() const { return m_screenHeight; } -#if USE(CHROME_NETWORK_STACK) - void setWebRequestContextUserAgent(); - void setWebRequestContextCacheMode(int mode); - WebRequestContext* webRequestContext(); -#endif - // Attempts to scroll the layer to the x,y coordinates of rect. The - // layer is the id of the LayerAndroid. - void scrollRenderLayer(int layer, const SkRect& rect); - // call only from webkit thread (like add/remove), return true if inst - // is still alive - static bool isInstance(WebViewCore*); - // if there exists at least one WebViewCore instance then we return the - // application context, otherwise NULL is returned. - static jobject getApplicationContext(); - // Check whether a media mimeType is supported in Android media framework. - static bool isSupportedMediaMimeType(const WTF::String& mimeType); - - // these members are shared with webview.cpp - static Mutex gFrameCacheMutex; - CachedRoot* m_frameCacheKit; // nav data being built by webcore - SkPicture* m_navPictureKit; - int m_moveGeneration; // copy of state in WebViewNative triggered by move - int m_touchGeneration; // copy of state in WebViewNative triggered by touch - int m_lastGeneration; // last action using up to date cache - bool m_updatedFrameCache; - bool m_findIsUp; - bool m_hasCursorBounds; - WebCore::IntRect m_cursorBounds; - WebCore::IntRect m_cursorHitBounds; - void* m_cursorFrame; - IntPoint m_cursorLocation; - void* m_cursorNode; - static Mutex gCursorBoundsMutex; - // These two fields go together: we use the mutex to protect access to - // m_buttons, so that we, and webview.cpp can look/modify the m_buttons - // field safely from our respective threads - static Mutex gButtonMutex; - WTF::Vector<Container> m_buttons; - // end of shared members - - // internal functions - private: - CacheBuilder& cacheBuilder(); - WebCore::Node* currentFocus(); - // Compare the new set of buttons to the old one. All of the new - // buttons either replace our old ones or should be added to our list. - // Then check the old buttons to see if any are no longer needed. - void updateButtonList(WTF::Vector<Container>* buttons); - void reset(bool fromConstructor); - // Create a set of pictures to represent the drawn DOM, driven by - // the invalidated region and the time required to draw (used to draw) - void recordPictureSet(PictureSet* master); - - friend class ListBoxReply; - struct JavaGlue; - struct JavaGlue* m_javaGlue; - WebCore::Frame* m_mainFrame; - WebCoreReply* m_popupReply; - WebCore::Node* m_lastFocused; - WebCore::IntRect m_lastFocusedBounds; - int m_blurringNodePointer; - int m_lastFocusedSelStart; - int m_lastFocusedSelEnd; - PictureSet m_content; // the set of pictures to draw - SkRegion m_addInval; // the accumulated inval region (not yet drawn) - SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures - // 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. - int m_textGeneration; - CachedRoot* m_temp; - SkPicture* m_tempPict; - int m_maxXScroll; - int m_maxYScroll; - int m_scrollOffsetX; // webview.java's current scroll in X - int m_scrollOffsetY; // webview.java's current scroll in Y - WebCore::IntPoint m_mousePos; - bool m_frameCacheOutOfDate; - bool m_progressDone; - int m_lastPassed; - int m_lastVelocity; - CachedHistory m_history; - int m_screenWidth; // width of the visible rect in document coordinates - int m_screenHeight;// height of the visible rect in document coordinates - int m_textWrapWidth; - float m_scale; - unsigned m_domtree_version; - bool m_check_domtree_version; - PageGroup* m_groupForVisitedLinks; - bool m_isPaused; - int m_cacheMode; - bool m_shouldPaintCaret; - - SkTDArray<PluginWidgetAndroid*> m_plugins; - WebCore::Timer<WebViewCore> m_pluginInvalTimer; - void pluginInvalTimerFired(WebCore::Timer<WebViewCore>*) { - this->drawPlugins(); - } - int m_screenOnCounter; - - void doMaxScroll(CacheBuilder::Direction dir); - SkPicture* rebuildPicture(const SkIRect& inval); - void rebuildPictureSet(PictureSet* ); - void sendNotifyProgressFinished(); - /* - * Handle a mouse click, either from a touch or trackball press. - * @param frame Pointer to the Frame containing the node that was clicked on. - * @param node Pointer to the Node that was clicked on. - * @param fake This is a fake mouse click, used to put a textfield into focus. Do not - * open the IME. - */ - bool handleMouseClick(WebCore::Frame*, WebCore::Node*, bool fake); - WebCore::HTMLAnchorElement* retrieveAnchorElement(int x, int y); - WebCore::HTMLElement* retrieveElement(int x, int y, - const WebCore::QualifiedName& ); - WebCore::HTMLImageElement* retrieveImageElement(int x, int y); - // below are members responsible for accessibility support - String modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int granularity); - String modifySelectionDomNavigationAxis(DOMSelection* selection, int direction, int granularity); - Text* traverseNextContentTextNode(Node* fromNode, Node* toNode ,int direction); - bool isVisible(Node* node); - bool isHeading(Node* node); - String formatMarkup(DOMSelection* selection); - void selectAt(int x, int y); - Node* m_currentNodeDomNavigationAxis; - void scrollNodeIntoView(Frame* frame, Node* node); - bool isContentTextNode(Node* node); - Node* getIntermediaryInputElement(Node* fromNode, Node* toNode, int direction); - bool isContentInputElement(Node* node); - bool isDescendantOf(Node* parent, Node* node); - void advanceAnchorNode(DOMSelection* selection, int direction, String& markup, bool ignoreFirstNode, ExceptionCode& ec); - Node* getNextAnchorNode(Node* anchorNode, bool skipFirstHack, int direction); - Node* getImplicitBoundaryNode(Node* node, unsigned offset, int direction); - -#if ENABLE(TOUCH_EVENTS) - bool m_forwardingTouchEvents; -#endif -#if DEBUG_NAV_UI - uint32_t m_now; -#endif - DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager; -#if USE(CHROME_NETWORK_STACK) - scoped_refptr<WebRequestContext> m_webRequestContext; -#endif - - // called from constructor, to add this to a global list - static void addInstance(WebViewCore*); - // called from destructor, to remove this from a global list - static void removeInstance(WebViewCore*); - }; - -} // namespace android - -#endif // WEBVIEWCORE_H diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp deleted file mode 100644 index dc10f21..0000000 --- a/WebKit/android/nav/CacheBuilder.cpp +++ /dev/null @@ -1,3201 +0,0 @@ -/* - * Copyright 2006, 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 "CachedPrefix.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "ColumnInfo.h" -#include "Document.h" -#include "EventListener.h" -#include "EventNames.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClientAndroid.h" -#include "FrameTree.h" -#include "FrameView.h" -//#include "GraphicsContext.h" -#include "HTMLAreaElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLMapElement.h" -#include "HTMLNames.h" -#include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" -#include "HTMLTextAreaElement.h" -#include "InlineTextBox.h" -#include "KURL.h" -#include "LayerAndroid.h" -#include "PluginView.h" -#include "RegisteredEventListener.h" -#include "RenderImage.h" -#include "RenderInline.h" -#include "RenderLayerBacking.h" -#include "RenderListBox.h" -#include "RenderSkinCombo.h" -#include "RenderTextControl.h" -#include "RenderView.h" -#include "RenderWidget.h" -#include "SkCanvas.h" -#include "SkPoint.h" -#include "Text.h" -#include "WebCoreFrameBridge.h" -#include "WebCoreViewBridge.h" -#include "Widget.h" -#include <wtf/unicode/Unicode.h> - -#ifdef DUMP_NAV_CACHE_USING_PRINTF - FILE* gNavCacheLogFile = NULL; - android::Mutex gWriteLogMutex; -#endif - -#include "CacheBuilder.h" - -#define MINIMUM_FOCUSABLE_WIDTH 3 -#define MINIMUM_FOCUSABLE_HEIGHT 3 -#define MAXIMUM_FOCUS_RING_COUNT 32 - -namespace android { - -CacheBuilder* CacheBuilder::Builder(Frame* frame) { - return &((FrameLoaderClientAndroid*) frame->loader()->client())->getCacheBuilder(); -} - -Frame* CacheBuilder::FrameAnd(CacheBuilder* cacheBuilder) { - FrameLoaderClientAndroid* loader = (FrameLoaderClientAndroid*) - ((char*) cacheBuilder - OFFSETOF(FrameLoaderClientAndroid, m_cacheBuilder)); - return loader->getFrame(); -} - -Frame* CacheBuilder::FrameAnd(const CacheBuilder* cacheBuilder) { - FrameLoaderClientAndroid* loader = (FrameLoaderClientAndroid*) - ((char*) cacheBuilder - OFFSETOF(FrameLoaderClientAndroid, m_cacheBuilder)); - return loader->getFrame(); -} - -CacheBuilder::LayerTracker::~LayerTracker() { - // Check for a stacking context to prevent a crash in layers without a - // parent. - if (mRenderLayer && mRenderLayer->stackingContext()) - // Restore the scroll position of the layer. Does not affect layers - // without overflow scroll as the layer will not be scrolled. - mRenderLayer->scrollToOffset(mScroll.x(), mScroll.y(), false, false); -} - -#if DUMP_NAV_CACHE - -static bool hasEventListener(Node* node, const AtomicString& eventType) { - if (!node->isElementNode()) - return false; - Element* element = static_cast<Element*>(node); - EventListener* listener = element->getAttributeEventListener(eventType); - return 0 != listener; -} - -#define DEBUG_BUFFER_SIZE 256 -#define DEBUG_WRAP_SIZE 150 -#define DEBUG_WRAP_MAX 170 - -Frame* CacheBuilder::Debug::frameAnd() const { - CacheBuilder* nav = (CacheBuilder*) ((char*) this - OFFSETOF(CacheBuilder, mDebug)); - return CacheBuilder::FrameAnd(nav); -} - -void CacheBuilder::Debug::attr(const AtomicString& name, const AtomicString& value) { - if (name.isNull() || name.isEmpty() || value.isNull() || value.isEmpty()) - return; - uChar(name.characters(), name.length(), false); - print("="); - wideString(value.characters(), value.length(), false); - print(" "); -} - -void CacheBuilder::Debug::comma(const char* str) { - print(str); - print(", "); -} - -void CacheBuilder::Debug::flush() { - int len; - do { - int limit = mIndex; - if (limit < DEBUG_WRAP_SIZE) - return; - if (limit < DEBUG_WRAP_MAX) - len = limit; - else { - limit = DEBUG_WRAP_MAX; - len = DEBUG_WRAP_SIZE; - while (len < limit) { - char test = mBuffer[len]; - if (test < '/' || (test > '9' && test < 'A') || (test > 'Z' && test < 'a') || test > 'z') - break; - len++; - } - while (len > 0 && mBuffer[len - 1] == '\\') - len--; - while (mBuffer[len] == '"') - len++; - } - const char* prefix = mPrefix; - if (prefix[0] == '\"') { - // see if we're inside a quote - int quoteCount = 0; - for (int index = 0; index < len; index++) { - if (mBuffer[index] == '\\') { - index++; - continue; - } - if (mBuffer[index] == '\n') { - quoteCount = 0; - continue; - } - if (mBuffer[index] == '"') - quoteCount++; - } - if ((quoteCount & 1) == 0) - prefix = "\n"; - } - DUMP_NAV_LOGD("%.*s", len, mBuffer); - int copy = mIndex - len; - strcpy(mBuffer, prefix); - memcpy(&mBuffer[strlen(prefix)], &mBuffer[len], copy); - mIndex = strlen(prefix) + copy; - } while (true); -} - -void CacheBuilder::Debug::frameName(char*& namePtr, const char* max) const { - if (namePtr >= max) - return; - Frame* frame = frameAnd(); - Frame* parent = frame->tree()->parent(); - if (parent) - Builder(parent)->mDebug.frameName(namePtr, max); - const AtomicString& name = frame->tree()->name(); - if (name.length() == 0) - return; - unsigned index = 0; - if (name.startsWith(AtomicString("opener"))) - index = 6; - for (; index < name.length(); index++) { - char ch = name[index]; - if (ch <= ' ') - ch = '_'; - if (WTF::isASCIIAlphanumeric(ch) || ch == '_') - *namePtr++ = ch; - } -} - -void CacheBuilder::Debug::frames() { - Frame* frame = frameAnd(); - Document* doc = frame->document(); - if (doc == NULL) - return; - bool top = frame->tree()->parent() == NULL; - if (top) { -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gWriteLogMutex.lock(); - ASSERT(gNavCacheLogFile == NULL); - gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a"); -#endif - groups(); - } - Frame* child = frame->tree()->firstChild(); - bool hasChild = child != NULL; - if (top && hasChild) - DUMP_NAV_LOGD("\nnamespace TEST_SPACE {\n\n"); - while (child) { - Builder(child)->mDebug.frames(); - child = child->tree()->nextSibling(); - } - if (hasChild) { - child = frame->tree()->firstChild(); - while (child) { - char childName[256]; - char* childNamePtr = childName; - Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1); - *childNamePtr = '\0'; - if (child == frame->tree()->firstChild()) - DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP[] = {\n", childName); - Frame* next = child->tree()->nextSibling(); - Document* doc = child->document(); - if (doc != NULL) { - RenderObject* renderer = doc->renderer(); - if (renderer != NULL) { - RenderLayer* layer = renderer->enclosingLayer(); - if (layer != NULL) { - DUMP_NAV_LOGD("{ "); - DUMP_NAV_LOGD("TEST%s_RECTS, ", childName); - DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", childName); - DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", childName); - DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", childName); - DUMP_NAV_LOGD("TEST%s_WIDTH, ", childName); - DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", childName); - DUMP_NAV_LOGD("0, 0, 0, 0,\n"); - DUMP_NAV_LOGD("TEST%s_FOCUS, ", childName); - Frame* grandChild = child->tree()->firstChild(); - if (grandChild) { - char grandChildName[256]; - char* grandChildNamePtr = grandChildName; - Builder(grandChild)->mDebug.frameName(grandChildNamePtr, - grandChildNamePtr + sizeof(grandChildName) - 1); - *grandChildNamePtr = '\0'; - DUMP_NAV_LOGD("TEST%s_GROUP, ", grandChildName); - DUMP_NAV_LOGD("sizeof(TEST%s_GROUP) / sizeof(DebugTestFrameGroup), ", grandChildName); - } else - DUMP_NAV_LOGD("NULL, 0, "); - DUMP_NAV_LOGD("\"%s\"\n", childName); - DUMP_NAV_LOGD("}%c\n", next ? ',' : ' '); - } - } - } - child = next; - } - DUMP_NAV_LOGD("};\n"); - } - if (top) { - if (hasChild) - DUMP_NAV_LOGD("\n} // end of namespace\n\n"); - char name[256]; - char* frameNamePtr = name; - frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1); - *frameNamePtr = '\0'; - DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP = {\n", name); - DUMP_NAV_LOGD("TEST%s_RECTS, ", name); - DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", name); - DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", name); - DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", name); - DUMP_NAV_LOGD("TEST%s_WIDTH, ", name); - DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", name); - DUMP_NAV_LOGD("TEST%s_MAX_H, ", name); - DUMP_NAV_LOGD("TEST%s_MIN_H, ", name); - DUMP_NAV_LOGD("TEST%s_MAX_V, ", name); - DUMP_NAV_LOGD("TEST%s_MIN_V,\n", name); - DUMP_NAV_LOGD("TEST%s_FOCUS, ", name); - if (hasChild) { - child = frame->tree()->firstChild(); - char childName[256]; - char* childNamePtr = childName; - Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1); - *childNamePtr = '\0'; - DUMP_NAV_LOGD("TEST_SPACE::TEST%s_GROUP, ", childName); - DUMP_NAV_LOGD("sizeof(TEST_SPACE::TEST%s_GROUP) / sizeof(DebugTestFrameGroup), \n" ,childName); - } else - DUMP_NAV_LOGD("NULL, 0, "); - DUMP_NAV_LOGD("\"%s\"\n", name); - DUMP_NAV_LOGD("};\n"); -#ifdef DUMP_NAV_CACHE_USING_PRINTF - if (gNavCacheLogFile) - fclose(gNavCacheLogFile); - gNavCacheLogFile = NULL; - gWriteLogMutex.unlock(); -#endif - } -} - -void CacheBuilder::Debug::init(char* buffer, size_t size) { - mBuffer = buffer; - mBufferSize = size; - mIndex = 0; - mPrefix = ""; -} - -void CacheBuilder::Debug::groups() { - Frame* frame = frameAnd(); - Frame* child = frame->tree()->firstChild(); - bool hasChild = child != NULL; - if (frame->tree()->parent() == NULL && hasChild) - DUMP_NAV_LOGD("namespace TEST_SPACE {\n\n"); - while (child) { - Builder(child)->mDebug.groups(); - child = child->tree()->nextSibling(); - } - if (frame->tree()->parent() == NULL && hasChild) - DUMP_NAV_LOGD("\n} // end of namespace\n\n"); - Document* doc = frame->document(); - char name[256]; - char* frameNamePtr = name; - frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1); - *frameNamePtr = '\0'; - if (doc == NULL) { - DUMP_NAV_LOGD("// %s has no document\n", name); - return; - } - RenderObject* renderer = doc->renderer(); - if (renderer == NULL) { - DUMP_NAV_LOGD("// %s has no renderer\n", name); - return; - } - RenderLayer* layer = renderer->enclosingLayer(); - if (layer == NULL) { - DUMP_NAV_LOGD("// %s has no enclosingLayer\n", name); - return; - } - Node* node = doc; - Node* focus = doc->focusedNode(); - bool atLeastOne = false; - do { - if ((atLeastOne |= isFocusable(node)) != false) - break; - } while ((node = node->traverseNextNode()) != NULL); - int focusIndex = -1; - if (atLeastOne == false) { - DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n" - "{{0, 0, 0, 0}, \"\", 0, -1, \"\", {0, 0, 0, 0}, false, 0}\n" - "};\n\n", name); - DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = 1;" - " // no focusable nodes\n", name); - DUMP_NAV_LOGD("#define TEST%s_RECTPARTS NULL\n", name); - } else { - node = doc; - int count = 1; - DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n", name); - do { - String properties; - if (hasEventListener(node, eventNames().clickEvent)) - properties.append("ONCLICK | "); - if (hasEventListener(node, eventNames().mousedownEvent)) - properties.append("MOUSEDOWN | "); - if (hasEventListener(node, eventNames().mouseupEvent)) - properties.append("MOUSEUP | "); - if (hasEventListener(node, eventNames().mouseoverEvent)) - properties.append("MOUSEOVER | "); - if (hasEventListener(node, eventNames().mouseoutEvent)) - properties.append("MOUSEOUT | "); - if (hasEventListener(node, eventNames().keydownEvent)) - properties.append("KEYDOWN | "); - if (hasEventListener(node, eventNames().keyupEvent)) - properties.append("KEYUP | "); - if (CacheBuilder::HasFrame(node)) - properties.append("FRAME | "); - if (focus == node) { - properties.append("FOCUS | "); - focusIndex = count; - } - if (node->isKeyboardFocusable(NULL)) - properties.append("KEYBOARD_FOCUSABLE | "); - if (node->isMouseFocusable()) - properties.append("MOUSE_FOCUSABLE | "); - if (node->isFocusable()) - properties.append("SIMPLE_FOCUSABLE | "); - if (properties.isEmpty()) - properties.append("0"); - else - properties.truncate(properties.length() - 3); - IntRect rect = node->getRect(); - if (node->hasTagName(HTMLNames::areaTag)) - rect = getAreaRect(static_cast<HTMLAreaElement*>(node)); - char buffer[DEBUG_BUFFER_SIZE]; - memset(buffer, 0, sizeof(buffer)); - mBuffer = buffer; - mBufferSize = sizeof(buffer); - mPrefix = "\"\n\""; - mIndex = snprintf(buffer, sizeof(buffer), "{{%d, %d, %d, %d}, ", rect.x(), rect.y(), - rect.width(), rect.height()); - localName(node); - uChar(properties.characters(), properties.length(), false); - print(", "); - int parentIndex = ParentIndex(node, count, node->parentNode()); - char scratch[256]; - snprintf(scratch, sizeof(scratch), "%d", parentIndex); - comma(scratch); - Element* element = static_cast<Element*>(node); - if (node->isElementNode() && element->hasID()) - wideString(element->getIdAttribute()); - else if (node->isTextNode()) { - #if 01 // set to one to abbreviate text that can be omitted from the address detection code - if (rect.isEmpty() && node->textContent().length() > 100) { - wideString(node->textContent().characters(), 100, false); - snprintf(scratch, sizeof(scratch), "/* + %d bytes */", - node->textContent().length() - 100); - print(scratch); - } else - #endif - wideString(node->textContent().characters(), node->textContent().length(), true); - } else if (node->hasTagName(HTMLNames::aTag) || - node->hasTagName(HTMLNames::areaTag)) - { - HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node); - wideString(anchor->href()); - } else if (node->hasTagName(HTMLNames::imgTag)) { - HTMLImageElement* image = static_cast<HTMLImageElement*>(node); - wideString(image->src()); - } else - print("\"\""); - RenderObject* renderer = node->renderer(); - int tabindex = node->isElementNode() ? node->tabIndex() : 0; - RenderLayer* layer = 0; - if (renderer) { - const IntRect& absB = renderer->absoluteBoundingBoxRect(); - bool hasLayer = renderer->hasLayer(); - layer = hasLayer ? toRenderBoxModelObject(renderer)->layer() : 0; - snprintf(scratch, sizeof(scratch), ", {%d, %d, %d, %d}, %s" - ", %d, %s, %s},", - absB.x(), absB.y(), absB.width(), absB.height(), - renderer->hasOverflowClip() ? "true" : "false", tabindex, - hasLayer ? "true" : "false", - hasLayer && layer->isComposited() ? "true" : "false"); - // TODO: add renderer->style()->visibility() - print(scratch); - } else - print(", {0, 0, 0, 0}, false, 0},"); - - flush(); - snprintf(scratch, sizeof(scratch), "// %d: ", count); - mPrefix = "\n// "; - print(scratch); - //print(renderer ? renderer->information().ascii() : "NO_RENDER_INFO"); - if (node->isElementNode()) { - Element* element = static_cast<Element*>(node); - NamedNodeMap* attrs = element->attributes(); - unsigned length = attrs->length(); - if (length > 0) { - newLine(); - print("// attr: "); - for (unsigned i = 0; i < length; i++) { - Attribute* a = attrs->attributeItem(i); - attr(a->localName(), a->value()); - } - } - } - if (renderer) { - RenderStyle* style = renderer->style(); - snprintf(scratch, sizeof(scratch), "// renderStyle:" - " visibility=%s hasBackGround=%d" - " tapHighlightColor().alpha()=0x%02x" - " isTransparent()=%s", - style->visibility() == HIDDEN ? "HIDDEN" : "VISIBLE", - renderer->hasBackground(), style->tapHighlightColor().alpha(), - renderer->isTransparent() ? "true" : "false"); - newLine(); - print(scratch); - RenderBlock* renderBlock = static_cast<RenderBlock*>(renderer); - if (renderer->isRenderBlock() && renderBlock->hasColumns()) { - const RenderBox* box = static_cast<RenderBox*>(renderer); - const IntRect& oRect = box->visibleOverflowRect(); - snprintf(scratch, sizeof(scratch), "// renderBlock:" - " columnCount=%d columnGap=%d direction=%d" - " hasOverflowClip=%d overflow=(%d,%d,w=%d,h=%d)", - renderBlock->columnInfo()->columnCount(), renderBlock->columnGap(), - renderBlock->style()->direction(), renderer->hasOverflowClip(), - oRect.x(), oRect.y(), oRect.width(), oRect.height()); - newLine(); - print(scratch); - } - } - #if USE(ACCELERATED_COMPOSITING) - if (renderer && renderer->hasLayer()) { - RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); - RenderLayerBacking* back = layer->backing(); - GraphicsLayer* grLayer = back ? back->graphicsLayer() : 0; - LayerAndroid* aLayer = grLayer ? grLayer->platformLayer() : 0; - const SkPicture* pict = aLayer ? aLayer->picture() : 0; - const IntRect& r = renderer->absoluteBoundingBoxRect(); - snprintf(scratch, sizeof(scratch), "// layer:%p back:%p" - " gLayer:%p aLayer:%p pict:%p r:(%d,%d,w=%d,h=%d)", - layer, back, grLayer, aLayer, pict, r.x(), r.y(), - r.width(), r.height()); - newLine(); - print(scratch); - } - #endif - count++; - newLine(); - } while ((node = node->traverseNextNode()) != NULL); - DUMP_NAV_LOGD("}; // focusables = %d\n", count - 1); - DUMP_NAV_LOGD("\n"); - DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = %d;\n\n", name, count - 1); - // look for rects with multiple parts - node = doc; - count = 1; - bool hasRectParts = false; - int globalOffsetX, globalOffsetY; - GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); - do { - IntRect rect; - bool _isFocusable = isFocusable(node) || (node->isTextNode() - && node->getRect().isEmpty() == false - ); - int nodeIndex = count++; - if (_isFocusable == false) - continue; - RenderObject* renderer = node->renderer(); - if (renderer == NULL) - continue; - WTF::Vector<IntRect> rects; - IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX); - IntRect focusBounds = IntRect(0, 0, INT_MAX, INT_MAX); - IntRect* rectPtr = &focusBounds; - int imageCount = 0; - if (node->isTextNode()) { - Text* textNode = (Text*) node; - if (CacheBuilder::ConstructTextRects(textNode, 0, textNode, - INT_MAX, globalOffsetX, globalOffsetY, rectPtr, - clipBounds, &rects) == false) - continue; - } else { - IntRect nodeBounds = node->getRect(); - if (CacheBuilder::ConstructPartRects(node, nodeBounds, rectPtr, - globalOffsetX, globalOffsetY, &rects, &imageCount) == false) - continue; - } - unsigned arraySize = rects.size(); - if (arraySize > 1 || (arraySize == 1 && (rectPtr->width() != rect.width())) || - rectPtr->height() != rect.height()) { - if (hasRectParts == false) { - DUMP_NAV_LOGD("static DebugTestRectPart TEST%s_RECTPARTS[] = {\n", name); - hasRectParts = true; - } - if (node->isTextNode() == false) { - unsigned rectIndex = 0; - for (; rectIndex < arraySize; rectIndex++) { - rectPtr = &rects.at(rectIndex); - DUMP_NAV_LOGD("{ %d, %d, %d, %d, %d }, // %d\n", nodeIndex, - rectPtr->x(), rectPtr->y(), rectPtr->width(), - rectPtr->height(), rectIndex + 1); - } - } else { - RenderText* renderText = (RenderText*) node->renderer(); - InlineTextBox* textBox = renderText->firstTextBox(); - unsigned rectIndex = 0; - while (textBox) { - FloatPoint pt = renderText->localToAbsolute(); - IntRect rect = textBox->selectionRect((int) pt.x(), (int) pt.y(), 0, INT_MAX); - mIndex = 0; - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "{ %d, %d, %d, %d, %d", - nodeIndex, rect.x(), rect.y(), rect.width(), rect.height()); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d", - textBox->len(), 0 /*textBox->selectionHeight()*/, - 0 /*textBox->selectionTop()*/); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d", - 0 /*textBox->spaceAdd()*/, textBox->start(), 0 /*textBox->textPos()*/); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d, %d", - textBox->x(), textBox->y(), textBox->logicalWidth(), textBox->logicalHeight()); - int baseline = textBox->renderer()->style(textBox->isFirstLineStyle())->font().ascent(); - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d }, // %d ", - baseline, imageCount, ++rectIndex); - wideString(node->textContent().characters() + textBox->start(), textBox->len(), true); - DUMP_NAV_LOGD("%.*s\n", mIndex, mBuffer); - textBox = textBox->nextTextBox(); - } - } - } - } while ((node = node->traverseNextNode()) != NULL); - if (hasRectParts) - DUMP_NAV_LOGD("{0}\n};\n\n"); - else - DUMP_NAV_LOGD("static DebugTestRectPart* TEST%s_RECTPARTS = NULL;\n", name); - } - int contentsWidth = layer->width(); - int contentsHeight = layer->height(); - DUMP_NAV_LOGD("static int TEST%s_FOCUS = %d;\n", name, focusIndex); - DUMP_NAV_LOGD("static int TEST%s_WIDTH = %d;\n", name, contentsWidth); - DUMP_NAV_LOGD("static int TEST%s_HEIGHT = %d;\n\n", name, contentsHeight); -} - -bool CacheBuilder::Debug::isFocusable(Node* node) { - if (node->hasTagName(HTMLNames::areaTag)) - return true; - if (node->renderer() == false) - return false; - if (node->isKeyboardFocusable(NULL)) - return true; - if (node->isMouseFocusable()) - return true; - if (node->isFocusable()) - return true; - if (CacheBuilder::AnyIsClick(node)) - return false; - if (CacheBuilder::HasTriggerEvent(node)) - return true; - return false; -} - -void CacheBuilder::Debug::localName(Node* node) { - const AtomicString& local = node->localName(); - if (node->isTextNode()) - print("\"#text\""); - else - wideString(local.characters(), local.length(), false); - print(", "); -} - -void CacheBuilder::Debug::newLine(int indent) { - if (mPrefix[0] != '\n') - print(&mPrefix[0], 1); - flush(); - int lastnewline = mIndex - 1; - while (lastnewline >= 0 && mBuffer[lastnewline] != '\n') - lastnewline--; - lastnewline++; - char* buffer = mBuffer; - if (lastnewline > 0) { - DUMP_NAV_LOGD("%.*s", lastnewline, buffer); - mIndex -= lastnewline; - buffer += lastnewline; - } - size_t prefixLen = strlen(mPrefix); - int minPrefix = prefixLen - 1; - while (minPrefix >= 0 && mPrefix[minPrefix] != '\n') - minPrefix--; - minPrefix = prefixLen - minPrefix - 1; - if (mIndex > minPrefix) - DUMP_NAV_LOGD("%.*s\n", mIndex, buffer); - mIndex = 0; - setIndent(indent); -} - -int CacheBuilder::Debug::ParentIndex(Node* node, int count, Node* parent) -{ - if (parent == NULL) - return -1; - ASSERT(node != parent); - int result = count; - Node* previous = node; - do { - result--; - previous = previous->traversePreviousNode(); - } while (previous && previous != parent); - if (previous != NULL) - return result; - result = count; - do { - result++; - } while ((node = node->traverseNextNode()) != NULL && node != parent); - if (node != NULL) - return result; - ASSERT(0); - return -1; -} - -void CacheBuilder::Debug::print(const char* name) { - print(name, strlen(name)); -} - -void CacheBuilder::Debug::print(const char* name, unsigned len) { - do { - if (mIndex + len >= DEBUG_BUFFER_SIZE) - flush(); - int copyLen = mIndex + len < DEBUG_BUFFER_SIZE ? - len : DEBUG_BUFFER_SIZE - mIndex; - memcpy(&mBuffer[mIndex], name, copyLen); - mIndex += copyLen; - name += copyLen; - len -= copyLen; - } while (len > 0); - mBuffer[mIndex] = '\0'; -} - -void CacheBuilder::Debug::setIndent(int indent) -{ - char scratch[64]; - snprintf(scratch, sizeof(scratch), "%.*s", indent, - " "); - print(scratch); -} - -void CacheBuilder::Debug::uChar(const UChar* name, unsigned len, bool hex) { - const UChar* end = name + len; - bool wroteHex = false; - while (name < end) { - unsigned ch = *name++; - if (ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0) - ch = ' '; - if (ch < ' ' || ch == 0x7f) { - if (hex) { - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "\\x%02x", ch); - wroteHex = true; - } else - mBuffer[mIndex++] = '?'; - } else if (ch >= 0x80) { - if (hex) { - if (ch < 0x800) - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\\x%02x\\x%02x", ch >> 6 | 0xc0, (ch & 0x3f) | 0x80); - else - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\\x%02x\\x%02x\\x%02x", ch >> 12 | 0xe0, - (ch >> 6 & 0x3f) | 0x80, (ch & 0x3f) | 0x80); - wroteHex = true; - } else - mBuffer[mIndex++] = '?'; - } else { - if (wroteHex && WTF::isASCIIHexDigit((UChar) ch)) - mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, - "\" \""); - else if (ch == '"' || ch == '\\') - mBuffer[mIndex++] = '\\'; - mBuffer[mIndex++] = ch; - wroteHex = false; - } - if (mIndex + 1 >= DEBUG_BUFFER_SIZE) - flush(); - } - flush(); -} - -void CacheBuilder::Debug::validateFrame() { - Frame* frame = frameAnd(); - Page* page = frame->page(); - ASSERT(page); - ASSERT((int) page > 0x10000); - Frame* child = frame->tree()->firstChild(); - while (child) { - Builder(child)->mDebug.validateFrame(); - child = child->tree()->nextSibling(); - } -} - -void CacheBuilder::Debug::wideString(const UChar* chars, int length, bool hex) { - if (length == 0) - print("\"\""); - else { - print("\""); - uChar(chars, length, hex); - print("\""); - } -} - -void CacheBuilder::Debug::wideString(const String& str) { - wideString(str.characters(), str.length(), false); -} - -#endif // DUMP_NAV_CACHE - -CacheBuilder::CacheBuilder() -{ - mAllowableTypes = ALL_CACHEDNODE_BITS; -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gNavCacheLogFile = NULL; -#endif -} - -void CacheBuilder::adjustForColumns(const ClipColumnTracker& track, - CachedNode* node, IntRect* bounds, RenderBlock* renderer) -{ - if (!renderer->hasColumns()) - return; - int x = 0; - int y = 0; - int tx = track.mBounds.x(); - int ty = track.mBounds.y(); - int columnGap = track.mColumnGap; - size_t limit = track.mColumnInfo->columnCount(); - for (size_t index = 0; index < limit; index++) { - IntRect column = renderer->columnRectAt(track.mColumnInfo, index); - column.move(tx, ty); - IntRect test = *bounds; - test.move(x, y); - if (column.contains(test)) { - if ((x | y) == 0) - return; - *bounds = test; - node->move(x, y); - return; - } - int xOffset = column.width() + columnGap; - x += track.mDirection == LTR ? xOffset : -xOffset; - y -= column.height(); - } -} - -// Checks if a node has one of event listener types. -bool CacheBuilder::NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length) { - for (int i = 0; i < length; ++i) { - if (!node->getEventListeners(eventTypes[i]).isEmpty()) - return true; - } - return false; -} - -bool CacheBuilder::AnyChildIsClick(Node* node) -{ - AtomicString eventTypes[5] = { - eventNames().clickEvent, - eventNames().mousedownEvent, - eventNames().mouseupEvent, - eventNames().keydownEvent, - eventNames().keyupEvent - }; - - Node* child = node->firstChild(); - while (child != NULL) { - if (child->isFocusable() || - NodeHasEventListeners(child, eventTypes, 5)) - return true; - if (AnyChildIsClick(child)) - return true; - child = child->nextSibling(); - } - return false; -} - -bool CacheBuilder::AnyIsClick(Node* node) -{ - if (node->hasTagName(HTMLNames::bodyTag)) - return AnyChildIsClick(node); - - AtomicString eventTypeSetOne[4] = { - eventNames().mouseoverEvent, - eventNames().mouseoutEvent, - eventNames().keydownEvent, - eventNames().keyupEvent - }; - - if (!NodeHasEventListeners(node, eventTypeSetOne, 4)) - return false; - - AtomicString eventTypeSetTwo[3] = { - eventNames().clickEvent, - eventNames().mousedownEvent, - eventNames().mouseupEvent - }; - - if (NodeHasEventListeners(node, eventTypeSetTwo, 3)) - return false; - - return AnyChildIsClick(node); -} - -void CacheBuilder::buildCache(CachedRoot* root) -{ - Frame* frame = FrameAnd(this); - mPictureSetDisabled = false; - BuildFrame(frame, frame, root, (CachedFrame*) root); - root->finishInit(); // set up frame parent pointers, child pointers - setData((CachedFrame*) root); -} - -static Node* ParentWithChildren(Node* node) -{ - Node* parent = node; - while ((parent = parent->parentNode())) { - if (parent->childNodeCount() > 1) - return parent; - } - return 0; -} - -// FIXME -// Probably this should check for null instead of the caller. If the -// Tracker object is the last thing in the dom, checking for null in the -// caller in some cases fails to set up Tracker state which may be useful -// to the nodes parsed immediately after the tracked noe. -static Node* OneAfter(Node* node) -{ - Node* parent = node; - Node* sibling = NULL; - while ((parent = parent->parentNode()) != NULL) { - sibling = parent->nextSibling(); - if (sibling != NULL) - break; - } - return sibling; -} - -// return true if this renderer is really a pluinview, and it wants -// key-events (i.e. focus) -static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) { - if (renderer->isWidget()) { - Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); - if (widget && (widget->isPluginView() || widget->isPluginViewBase())) { - // check if this plugin really wants key events (TODO) - return true; - } - } - return false; -} - -#if USE(ACCELERATED_COMPOSITING) -static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location, int id) -{ - DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index, - location.x(), location.y(), id); - CachedLayer cachedLayer; - cachedLayer.setCachedNodeIndex(index); - cachedLayer.setOffset(location); - cachedLayer.setUniqueId(id); - frame->add(cachedLayer); -} -#endif - -static int FindColorIndex(WTF::Vector<CachedColor>& colorTracker, - const CachedColor& cachedColor) -{ - CachedColor* work = colorTracker.begin() - 1; - CachedColor* end = colorTracker.end(); - while (++work < end) { - if (*work == cachedColor) - return work - colorTracker.begin(); - } - int result = colorTracker.size(); - colorTracker.grow(result + 1); - CachedColor& newColor = colorTracker.last(); - newColor = cachedColor; - return result; -} - -static void InitColor(CachedColor* color) -{ - color->setFillColor(RenderStyle::initialRingFillColor()); - color->setInnerWidth(RenderStyle::initialRingInnerWidth()); - color->setOuterWidth(RenderStyle::initialRingOuterWidth()); - color->setOutset(RenderStyle::initialRingOutset()); - color->setPressedInnerColor(RenderStyle::initialRingPressedInnerColor()); - color->setPressedOuterColor(RenderStyle::initialRingPressedOuterColor()); - color->setRadius(RenderStyle::initialRingRadius()); - color->setSelectedInnerColor(RenderStyle::initialRingSelectedInnerColor()); - color->setSelectedOuterColor(RenderStyle::initialRingSelectedOuterColor()); -} - -// when new focus is found, push it's parent on a stack - // as long as more focii are found with the same (grand) parent, note it - // (which only requires retrieving the last parent on the stack) -// when the parent's last child is found, pop the stack -// different from Tracker in that Tracker only pushes focii with children - -// making this work with focus - child focus - grandchild focus is tricky -// if I keep the generation number, I may be able to more quickly determine that -// a node is a grandchild of the focus's parent -// this additionally requires being able to find the grandchild's parent - -// keep nodes that are focusable -void CacheBuilder::BuildFrame(Frame* root, Frame* frame, - CachedRoot* cachedRoot, CachedFrame* cachedFrame) -{ - WTF::Vector<FocusTracker> tracker(1); // sentinel - { - FocusTracker* baseTracker = tracker.data(); - bzero(baseTracker, sizeof(FocusTracker)); - baseTracker->mCachedNodeIndex = -1; - } - WTF::Vector<LayerTracker> layerTracker(1); // sentinel - bzero(layerTracker.data(), sizeof(LayerTracker)); - WTF::Vector<ClipColumnTracker> clipTracker(1); // sentinel - bzero(clipTracker.data(), sizeof(ClipColumnTracker)); - WTF::Vector<TabIndexTracker> tabIndexTracker(1); // sentinel - bzero(tabIndexTracker.data(), sizeof(TabIndexTracker)); - WTF::Vector<CachedColor> colorTracker(1); - InitColor(colorTracker.data()); -#if DUMP_NAV_CACHE - char* frameNamePtr = cachedFrame->mDebug.mFrameName; - Builder(frame)->mDebug.frameName(frameNamePtr, frameNamePtr + - sizeof(cachedFrame->mDebug.mFrameName) - 1); - *frameNamePtr = '\0'; - int nodeIndex = 1; -#endif - NodeWalk walk; - Document* doc = frame->document(); - Node* parent = doc; - CachedNode cachedParentNode; - cachedParentNode.init(parent); -#if DUMP_NAV_CACHE - cachedParentNode.mDebug.mNodeIndex = nodeIndex; -#endif - cachedFrame->add(colorTracker[0]); - cachedFrame->add(cachedParentNode); - Node* node = parent; - int cacheIndex = 1; - int colorIndex = 0; // assume no special css ring colors - const void* lastStyleDataPtr = 0; - int textInputIndex = 0; - Node* focused = doc->focusedNode(); - if (focused) - cachedRoot->setFocusBounds(focused->getRect()); - int globalOffsetX, globalOffsetY; - GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); -#if USE(ACCELERATED_COMPOSITING) - // The frame itself might be composited so we need to track the layer. Do - // not track the base frame's layer as the main content is draw as part of - // BaseLayerAndroid's picture. - if (frame != root && frame->contentRenderer() - && frame->contentRenderer()->usesCompositing() && node->lastChild()) - TrackLayer(layerTracker, frame->contentRenderer(), node->lastChild(), - globalOffsetX, globalOffsetY); -#endif - while (walk.mMore || (node = node->traverseNextNode()) != NULL) { -#if DUMP_NAV_CACHE - nodeIndex++; -#endif - FocusTracker* last = &tracker.last(); - int lastChildIndex = cachedFrame->size() - 1; - while (node == last->mLastChild) { - if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex)) - cacheIndex--; - tracker.removeLast(); - lastChildIndex = last->mCachedNodeIndex; - last = &tracker.last(); - } - do { - const ClipColumnTracker* lastClip = &clipTracker.last(); - if (node != lastClip->mLastChild) - break; - clipTracker.removeLast(); - } while (true); - do { - const LayerTracker* lastLayer = &layerTracker.last(); - if (node != lastLayer->mLastChild) - break; - layerTracker.removeLast(); - } while (true); - do { - const TabIndexTracker* lastTabIndex = &tabIndexTracker.last(); - if (node != lastTabIndex->mLastChild) - break; - tabIndexTracker.removeLast(); - } while (true); - Frame* child = HasFrame(node); - CachedNode cachedNode; - if (child != NULL) { - if (child->document() == NULL) - continue; - RenderObject* nodeRenderer = node->renderer(); - if (nodeRenderer != NULL && nodeRenderer->style()->visibility() == HIDDEN) - continue; - CachedFrame cachedChild; - cachedChild.init(cachedRoot, cacheIndex, child); - int childFrameIndex = cachedFrame->childCount(); - cachedFrame->addFrame(cachedChild); - cachedNode.init(node); - cachedNode.setIndex(cacheIndex++); - cachedNode.setDataIndex(childFrameIndex); - cachedNode.setType(FRAME_CACHEDNODETYPE); -#if DUMP_NAV_CACHE - cachedNode.mDebug.mNodeIndex = nodeIndex; - cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex( - node, nodeIndex, NULL); -#endif - cachedFrame->add(cachedNode); - CachedFrame* childPtr = cachedFrame->lastChild(); - BuildFrame(root, child, cachedRoot, childPtr); - continue; - } - int tabIndex = node->tabIndex(); - Node* lastChild = node->lastChild(); - if (tabIndex <= 0) - tabIndex = tabIndexTracker.last().mTabIndex; - else if (tabIndex > 0 && lastChild) { - DBG_NAV_LOGD("tabIndex=%d node=%p", tabIndex, node); - tabIndexTracker.grow(tabIndexTracker.size() + 1); - TabIndexTracker& indexTracker = tabIndexTracker.last(); - indexTracker.mTabIndex = tabIndex; - indexTracker.mLastChild = OneAfter(lastChild); - } - RenderObject* nodeRenderer = node->renderer(); - bool isTransparent = false; - bool hasCursorRing = true; - if (nodeRenderer != NULL) { - RenderStyle* style = nodeRenderer->style(); - if (style->visibility() == HIDDEN) - continue; - isTransparent = nodeRenderer->hasBackground() == false; -#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR - hasCursorRing = style->tapHighlightColor().alpha() > 0; -#endif -#if USE(ACCELERATED_COMPOSITING) - // If this renderer has its own layer and the layer is composited, - // start tracking it. - if (lastChild && nodeRenderer->hasLayer() && toRenderBoxModelObject(nodeRenderer)->layer()->backing()) - TrackLayer(layerTracker, nodeRenderer, lastChild, globalOffsetX, globalOffsetY); -#endif - } - bool more = walk.mMore; - walk.reset(); - // GetGlobalBounds(node, &bounds, false); - bool computeCursorRings = false; - bool hasClip = false; - bool hasMouseOver = false; - bool isUnclipped = false; - bool isFocus = node == focused; - bool takesFocus = false; - int columnGap = 0; - int imageCount = 0; - TextDirection direction = LTR; - String exported; - CachedNodeType type = NORMAL_CACHEDNODETYPE; - CachedColor cachedColor; - CachedInput cachedInput; - IntRect bounds; - IntRect absBounds; - IntRect originalAbsBounds; - ColumnInfo* columnInfo = NULL; - if (node->hasTagName(HTMLNames::areaTag)) { - type = AREA_CACHEDNODETYPE; - HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node); - bounds = getAreaRect(area); - originalAbsBounds = bounds; - bounds.move(globalOffsetX, globalOffsetY); - absBounds = bounds; - isUnclipped = true; // FIXME: areamaps require more effort to detect - // assume areamaps are always visible for now - takesFocus = true; - goto keepNode; - } - if (nodeRenderer == NULL) - continue; - - // some common setup - absBounds = nodeRenderer->absoluteBoundingBoxRect(); - originalAbsBounds = absBounds; - absBounds.move(globalOffsetX, globalOffsetY); - hasClip = nodeRenderer->hasOverflowClip(); - - if (node->hasTagName(HTMLNames::canvasTag)) - mPictureSetDisabled = true; - if (checkForPluginViewThatWantsFocus(nodeRenderer)) { - bounds = absBounds; - isUnclipped = true; - takesFocus = true; - type = PLUGIN_CACHEDNODETYPE; - goto keepNode; - } - // Only use the root contentEditable element - if (node->isContentEditable() && !node->parentOrHostNode()->isContentEditable()) { - bounds = absBounds; - takesFocus = true; - type = CONTENT_EDITABLE_CACHEDNODETYPE; - goto keepNode; - } - if (nodeRenderer->isRenderBlock()) { - RenderBlock* renderBlock = (RenderBlock*) nodeRenderer; - if (renderBlock->hasColumns()) { - columnInfo = renderBlock->columnInfo(); - columnGap = renderBlock->columnGap(); - direction = renderBlock->style()->direction(); - } - } - if ((hasClip != false || columnInfo != NULL) && lastChild) { - clipTracker.grow(clipTracker.size() + 1); - ClipColumnTracker& clip = clipTracker.last(); - clip.mBounds = absBounds; - clip.mLastChild = OneAfter(lastChild); - clip.mNode = node; - clip.mColumnInfo = columnInfo; - clip.mColumnGap = columnGap; - clip.mHasClip = hasClip; - clip.mDirection = direction; - if (columnInfo != NULL) { - const IntRect& oRect = ((RenderBox*)nodeRenderer)->visualOverflowRect(); - clip.mBounds.move(oRect.x(), oRect.y()); - } - } - if (node->isTextNode() && mAllowableTypes != NORMAL_CACHEDNODE_BITS) { - if (last->mSomeParentTakesFocus) // don't look at text inside focusable node - continue; - CachedNodeType checkType; - if (isFocusableText(&walk, more, node, &checkType, - &exported) == false) - continue; - #if DUMP_NAV_CACHE - { - char buffer[DEBUG_BUFFER_SIZE]; - mDebug.init(buffer, sizeof(buffer)); - mDebug.print("text link found: "); - mDebug.wideString(exported); - DUMP_NAV_LOGD("%s\n", buffer); - } - #endif - type = checkType; - // !!! test ! is the following line correctly needed for frames to work? - cachedNode.init(node); - const ClipColumnTracker& clipTrack = clipTracker.last(); - const IntRect& clip = clipTrack.mHasClip ? clipTrack.mBounds : - IntRect(0, 0, INT_MAX, INT_MAX); - if (ConstructTextRects((WebCore::Text*) node, walk.mStart, - (WebCore::Text*) walk.mFinalNode, walk.mEnd, globalOffsetX, - globalOffsetY, &bounds, clip, &cachedNode.mCursorRing) == false) - continue; - absBounds = bounds; - cachedNode.setBounds(bounds); - if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH) - continue; - if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) - continue; - computeCursorRings = true; - isUnclipped = true; // FIXME: to hide or partially occlude synthesized links, each - // focus ring will also need the offset and length of characters - // used to produce it - goto keepTextNode; - } - if (node->hasTagName(WebCore::HTMLNames::inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(node); - if (input->isTextField()) { - if (input->readOnly()) - continue; - type = TEXT_INPUT_CACHEDNODETYPE; - cachedInput.init(); - cachedInput.setAutoComplete(input->autoComplete()); - cachedInput.setFormPointer(input->form()); - cachedInput.setIsTextField(true); - exported = input->value().threadsafeCopy(); - cachedInput.setMaxLength(input->maxLength()); - cachedInput.setTypeFromElement(input); - // If this does not need to be threadsafe, we can use crossThreadString(). - // See http://trac.webkit.org/changeset/49160. - cachedInput.setName(input->name().string().threadsafeCopy()); - // can't detect if this is drawn on top (example: deviant.com login parts) - isUnclipped = isTransparent; - } else if (input->isInputTypeHidden()) - continue; - else if (input->isRadioButton() || input->isCheckbox()) - isTransparent = false; - } else if (node->hasTagName(HTMLNames::textareaTag)) { - HTMLTextAreaElement* area = static_cast<HTMLTextAreaElement*>(node); - if (area->readOnly()) - continue; - cachedInput.init(); - type = TEXT_INPUT_CACHEDNODETYPE; - cachedInput.setFormPointer(area->form()); - cachedInput.setIsTextArea(true); - exported = area->value().threadsafeCopy(); - } else if (node->hasTagName(HTMLNames::aTag)) { - const HTMLAnchorElement* anchorNode = - (const HTMLAnchorElement*) node; - if (!anchorNode->isFocusable() && !HasTriggerEvent(node)) - continue; - if (node->disabled()) - continue; - hasMouseOver = NodeHasEventListeners(node, &eventNames().mouseoverEvent, 1); - type = ANCHOR_CACHEDNODETYPE; - KURL href = anchorNode->href(); - if (!href.isEmpty() && !WebCore::protocolIsJavaScript(href.string())) - // Set the exported string for all non-javascript anchors. - exported = href.string().threadsafeCopy(); - } else if (node->hasTagName(HTMLNames::selectTag)) { - type = SELECT_CACHEDNODETYPE; - } - if (type == TEXT_INPUT_CACHEDNODETYPE) { - RenderTextControl* renderText = - static_cast<RenderTextControl*>(nodeRenderer); - if (isFocus) - cachedRoot->setSelection(renderText->selectionStart(), renderText->selectionEnd()); - // FIXME: Are we sure there will always be a style and font, and it's correct? - RenderStyle* style = nodeRenderer->style(); - if (style) { - isUnclipped |= !style->hasAppearance(); - int lineHeight = -1; - Length lineHeightLength = style->lineHeight(); - // If the lineHeight is negative, WebTextView will calculate it - // based on the text size, using the Paint. - // See RenderStyle.computedLineHeight. - if (lineHeightLength.isPositive()) - lineHeight = style->computedLineHeight(); - cachedInput.setLineHeight(lineHeight); - cachedInput.setTextSize(style->font().size()); - cachedInput.setIsRtlText(style->direction() == RTL - || style->textAlign() == WebCore::RIGHT - || style->textAlign() == WebCore::WEBKIT_RIGHT); - } - cachedInput.setPaddingLeft(renderText->paddingLeft() + renderText->borderLeft()); - cachedInput.setPaddingTop(renderText->paddingTop() + renderText->borderTop()); - cachedInput.setPaddingRight(renderText->paddingRight() + renderText->borderRight()); - cachedInput.setPaddingBottom(renderText->paddingBottom() + renderText->borderBottom()); - } - takesFocus = true; - bounds = absBounds; - if (type != ANCHOR_CACHEDNODETYPE) { - bool isFocusable = node->isKeyboardFocusable(NULL) || - node->isMouseFocusable() || node->isFocusable(); - if (isFocusable == false) { - if (node->disabled()) - continue; - bool overOrOut = HasOverOrOut(node); - bool hasTrigger = HasTriggerEvent(node); - if (overOrOut == false && hasTrigger == false) - continue; - takesFocus = hasTrigger; - } - } - computeCursorRings = true; - keepNode: - cachedNode.init(node); - if (computeCursorRings == false) { - cachedNode.setBounds(bounds); - cachedNode.mCursorRing.append(bounds); - } else if (ConstructPartRects(node, bounds, &cachedNode.mBounds, - globalOffsetX, globalOffsetY, &cachedNode.mCursorRing, - &imageCount) == false) - continue; - keepTextNode: - if (nodeRenderer) { // area tags' node->renderer() == 0 - RenderStyle* style = nodeRenderer->style(); - const void* styleDataPtr = style->ringData(); - // to save time, see if we're pointing to the same style data as before - if (lastStyleDataPtr != styleDataPtr) { - lastStyleDataPtr = styleDataPtr; - cachedColor.setFillColor(style->ringFillColor()); - cachedColor.setInnerWidth(style->ringInnerWidth()); - cachedColor.setOuterWidth(style->ringOuterWidth()); - cachedColor.setOutset(style->ringOutset()); - cachedColor.setPressedInnerColor(style->ringPressedInnerColor()); - cachedColor.setPressedOuterColor(style->ringPressedOuterColor()); - cachedColor.setRadius(style->ringRadius()); - cachedColor.setSelectedInnerColor(style->ringSelectedInnerColor()); - cachedColor.setSelectedOuterColor(style->ringSelectedOuterColor()); - int oldSize = colorTracker.size(); - colorIndex = FindColorIndex(colorTracker, cachedColor); - if (colorIndex == oldSize) - cachedFrame->add(cachedColor); - } - } else - colorIndex = 0; - IntRect clip = hasClip ? bounds : absBounds; - size_t clipIndex = clipTracker.size(); - if (clipTracker.last().mNode == node) - clipIndex -= 1; - while (--clipIndex > 0) { - const ClipColumnTracker& clipTrack = clipTracker.at(clipIndex); - if (clipTrack.mHasClip == false) { - adjustForColumns(clipTrack, &cachedNode, &absBounds, static_cast<RenderBlock*>(nodeRenderer)); - continue; - } - const IntRect& parentClip = clipTrack.mBounds; - if (hasClip == false && type == ANCHOR_CACHEDNODETYPE) - clip = parentClip; - else - clip.intersect(parentClip); - hasClip = true; - } - bool isInLayer = false; -#if USE(ACCELERATED_COMPOSITING) - // If this renderer has a composited parent layer (including itself), - // add the node to the cached layer. - // FIXME: does not work for area rects - RenderLayer* enclosingLayer = nodeRenderer->enclosingLayer(); - if (enclosingLayer && enclosingLayer->enclosingCompositingLayer()) { - LayerAndroid* layer = layerTracker.last().mLayer; - if (layer) { - const IntRect& layerClip = layerTracker.last().mBounds; - if (!layerClip.isEmpty() && !cachedNode.clip(layerClip)) { - DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex); - continue; // skip this node if outside of the clip - } - isInLayer = true; - isUnclipped = true; // assume that layers do not have occluded nodes - hasClip = false; - AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(), - layer->uniqueId()); - } - } -#endif - if (hasClip) { - if (clip.isEmpty()) - continue; // skip this node if clip prevents all drawing - else if (cachedNode.clip(clip) == false) - continue; // skip this node if outside of the clip - } - cachedNode.setNavableRects(); - cachedNode.setColorIndex(colorIndex); - cachedNode.setExport(exported); - cachedNode.setHasCursorRing(hasCursorRing); - cachedNode.setHasMouseOver(hasMouseOver); - cachedNode.setHitBounds(absBounds); - cachedNode.setIndex(cacheIndex); - cachedNode.setIsFocus(isFocus); - cachedNode.setIsInLayer(isInLayer); - cachedNode.setIsTransparent(isTransparent); - cachedNode.setIsUnclipped(isUnclipped); - cachedNode.setOriginalAbsoluteBounds(originalAbsBounds); - cachedNode.setParentIndex(last->mCachedNodeIndex); - cachedNode.setParentGroup(ParentWithChildren(node)); - cachedNode.setSingleImage(imageCount == 1); - cachedNode.setTabIndex(tabIndex); - cachedNode.setType(type); - if (type == TEXT_INPUT_CACHEDNODETYPE) { - cachedFrame->add(cachedInput); - cachedNode.setDataIndex(textInputIndex); - textInputIndex++; - } else - cachedNode.setDataIndex(-1); -#if DUMP_NAV_CACHE - cachedNode.mDebug.mNodeIndex = nodeIndex; - cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex( - node, nodeIndex, (Node*) cachedNode.parentGroup()); -#endif - cachedFrame->add(cachedNode); - { - int lastIndex = cachedFrame->size() - 1; - if (node == focused) { - CachedNode* cachedNodePtr = cachedFrame->getIndex(lastIndex); - cachedRoot->setCachedFocus(cachedFrame, cachedNodePtr); - } - if (lastChild != NULL) { - tracker.grow(tracker.size() + 1); - FocusTracker& working = tracker.last(); - working.mCachedNodeIndex = lastIndex; - working.mLastChild = OneAfter(lastChild); - last = &tracker.at(tracker.size() - 2); - working.mSomeParentTakesFocus = last->mSomeParentTakesFocus | takesFocus; - } - } - cacheIndex++; - } - while (tracker.size() > 1) { - FocusTracker* last = &tracker.last(); - int lastChildIndex = cachedFrame->size() - 1; - if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex)) - cacheIndex--; - tracker.removeLast(); - } -} - -bool CacheBuilder::CleanUpContainedNodes(CachedRoot* cachedRoot, - CachedFrame* cachedFrame, const FocusTracker* last, int lastChildIndex) -{ - // if outer is body, disable outer - // or if there's more than one inner, disable outer - // or if inner is keyboard focusable, disable outer - // else disable inner by removing it - int childCount = lastChildIndex - last->mCachedNodeIndex; - if (childCount == 0) - return false; - CachedNode* lastCached = cachedFrame->getIndex(last->mCachedNodeIndex); - Node* lastNode = (Node*) lastCached->nodePointer(); - if ((childCount > 1 && lastNode->hasTagName(HTMLNames::selectTag) == false) || - lastNode->hasTagName(HTMLNames::bodyTag) || - lastNode->hasTagName(HTMLNames::formTag)) { - lastCached->setBounds(IntRect(0, 0, 0, 0)); - lastCached->mCursorRing.clear(); - lastCached->setNavableRects(); - return false; - } - CachedNode* onlyChildCached = cachedFrame->lastNode(); - Node* onlyChild = (Node*) onlyChildCached->nodePointer(); - bool outerIsMouseMoveOnly = - lastNode->isKeyboardFocusable(NULL) == false && - lastNode->isMouseFocusable() == false && - lastNode->isFocusable() == false && - HasOverOrOut(lastNode) == true && - HasTriggerEvent(lastNode) == false; - if (onlyChildCached->parent() == lastCached) - onlyChildCached->setParentIndex(lastCached->parentIndex()); - bool hasFocus = lastCached->isFocus() || onlyChildCached->isFocus(); - if (outerIsMouseMoveOnly || onlyChild->isKeyboardFocusable(NULL) - || onlyChildCached->isPlugin()) { - int index = lastCached->index(); - *lastCached = *onlyChildCached; - lastCached->setIndex(index); - CachedFrame* frame = cachedFrame->hasFrame(lastCached); - if (frame) - frame->setIndexInParent(index); - } - cachedFrame->removeLast(); - if (hasFocus) - cachedRoot->setCachedFocus(cachedFrame, cachedFrame->lastNode()); - return true; -} - -Node* CacheBuilder::currentFocus() const -{ - Frame* frame = FrameAnd(this); - Document* doc = frame->document(); - if (doc != NULL) { - Node* focus = doc->focusedNode(); - if (focus != NULL) - return focus; - } - Frame* child = frame->tree()->firstChild(); - while (child) { - CacheBuilder* cacheBuilder = Builder(child); - Node* focus = cacheBuilder->currentFocus(); - if (focus) - return focus; - child = child->tree()->nextSibling(); - } - return NULL; -} - -static bool strCharCmp(const char* matches, const UChar* test, int wordLength, - int wordCount) -{ - for (int index = 0; index < wordCount; index++) { - for (int inner = 0; inner < wordLength; inner++) { - if (matches[inner] != test[inner]) { - matches += wordLength; - goto next; - } - } - return true; -next: - ; - } - return false; -} - -static const int stateTwoLetter[] = { - 0x02060c00, // A followed by: [KLRSZ] - 0x00000000, // B - 0x00084001, // C followed by: [AOT] - 0x00000014, // D followed by: [CE] - 0x00000000, // E - 0x00001800, // F followed by: [LM] - 0x00100001, // G followed by: [AU] - 0x00000100, // H followed by: [I] - 0x00002809, // I followed by: [ADLN] - 0x00000000, // J - 0x01040000, // K followed by: [SY] - 0x00000001, // L followed by: [A] - 0x000ce199, // M followed by: [ADEHINOPST] - 0x0120129c, // N followed by: [CDEHJMVY] - 0x00020480, // O followed by: [HKR] - 0x00420001, // P followed by: [ARW] - 0x00000000, // Q - 0x00000100, // R followed by: [I] - 0x0000000c, // S followed by: [CD] - 0x00802000, // T followed by: [NX] - 0x00080000, // U followed by: [T] - 0x00080101, // V followed by: [AIT] - 0x01200101 // W followed by: [AIVY] -}; - -static const char firstIndex[] = { - 0, 5, 5, 8, 10, 10, 12, 14, - 15, 19, 19, 21, 22, 32, 40, 43, - 46, 46, 47, 49, 51, 52, 55, 59 -}; - -// from http://infolab.stanford.edu/~manku/bitcount/bitcount.html -#define TWO(c) (0x1u << (c)) -#define MASK(c) (((unsigned int)(-1)) / (TWO(TWO(c)) + 1u)) -#define COUNT(x,c) ((x) & MASK(c)) + (((x) >> (TWO(c))) & MASK(c)) - -int bitcount (unsigned int n) -{ - n = COUNT(n, 0); - n = COUNT(n, 1); - n = COUNT(n, 2); - n = COUNT(n, 3); - return COUNT(n, 4); -} - -#undef TWO -#undef MASK -#undef COUNT - -static bool isUnicodeSpace(UChar ch) -{ - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0; -} - -static bool validZip(int stateIndex, const UChar* zipPtr) -{ - static const struct { - char mLow; - char mHigh; - char mException1; - char mException2; - } zipRange[] = { - { 99, 99, -1, -1 }, // AK Alaska - { 35, 36, -1, -1 }, // AL Alabama - { 71, 72, -1, -1 }, // AR Arkansas - { 96, 96, -1, -1 }, // AS American Samoa - { 85, 86, -1, -1 }, // AZ Arizona - { 90, 96, -1, -1 }, // CA California - { 80, 81, -1, -1 }, // CO Colorado - { 6, 6, -1, -1 }, // CT Connecticut - { 20, 20, -1, -1 }, // DC District of Columbia - { 19, 19, -1, -1 }, // DE Delaware - { 32, 34, -1, -1 }, // FL Florida - { 96, 96, -1, -1 }, // FM Federated States of Micronesia - { 30, 31, -1, -1 }, // GA Georgia - { 96, 96, -1, -1 }, // GU Guam - { 96, 96, -1, -1 }, // HI Hawaii - { 50, 52, -1, -1 }, // IA Iowa - { 83, 83, -1, -1 }, // ID Idaho - { 60, 62, -1, -1 }, // IL Illinois - { 46, 47, -1, -1 }, // IN Indiana - { 66, 67, 73, -1 }, // KS Kansas - { 40, 42, -1, -1 }, // KY Kentucky - { 70, 71, -1, -1 }, // LA Louisiana - { 1, 2, -1, -1 }, // MA Massachusetts - { 20, 21, -1, -1 }, // MD Maryland - { 3, 4, -1, -1 }, // ME Maine - { 96, 96, -1, -1 }, // MH Marshall Islands - { 48, 49, -1, -1 }, // MI Michigan - { 55, 56, -1, -1 }, // MN Minnesota - { 63, 65, -1, -1 }, // MO Missouri - { 96, 96, -1, -1 }, // MP Northern Mariana Islands - { 38, 39, -1, -1 }, // MS Mississippi - { 55, 56, -1, -1 }, // MT Montana - { 27, 28, -1, -1 }, // NC North Carolina - { 58, 58, -1, -1 }, // ND North Dakota - { 68, 69, -1, -1 }, // NE Nebraska - { 3, 4, -1, -1 }, // NH New Hampshire - { 7, 8, -1, -1 }, // NJ New Jersey - { 87, 88, 86, -1 }, // NM New Mexico - { 88, 89, 96, -1 }, // NV Nevada - { 10, 14, 0, 6 }, // NY New York - { 43, 45, -1, -1 }, // OH Ohio - { 73, 74, -1, -1 }, // OK Oklahoma - { 97, 97, -1, -1 }, // OR Oregon - { 15, 19, -1, -1 }, // PA Pennsylvania - { 6, 6, 0, 9 }, // PR Puerto Rico - { 96, 96, -1, -1 }, // PW Palau - { 2, 2, -1, -1 }, // RI Rhode Island - { 29, 29, -1, -1 }, // SC South Carolina - { 57, 57, -1, -1 }, // SD South Dakota - { 37, 38, -1, -1 }, // TN Tennessee - { 75, 79, 87, 88 }, // TX Texas - { 84, 84, -1, -1 }, // UT Utah - { 22, 24, 20, -1 }, // VA Virginia - { 6, 9, -1, -1 }, // VI Virgin Islands - { 5, 5, -1, -1 }, // VT Vermont - { 98, 99, -1, -1 }, // WA Washington - { 53, 54, -1, -1 }, // WI Wisconsin - { 24, 26, -1, -1 }, // WV West Virginia - { 82, 83, -1, -1 } // WY Wyoming - }; - - int zip = zipPtr[0] - '0'; - zip *= 10; - zip += zipPtr[1] - '0'; - int low = zipRange[stateIndex].mLow; - int high = zipRange[stateIndex].mHigh; - if (zip >= low && zip <= high) - return true; - if (zip == zipRange[stateIndex].mException1) - return true; - if (zip == zipRange[stateIndex].mException2) - return true; - return false; -} - -#define MAX_PLACE_NAME_LENGTH 25 // the longest allowable one word place name - -CacheBuilder::FoundState CacheBuilder::FindAddress(const UChar* chars, - unsigned length, int* start, int* end, bool caseInsensitive) -{ - FindState addressState; - FindReset(&addressState); - addressState.mWords[0] = addressState.mStarts[0] = chars; - addressState.mCaseInsensitive = caseInsensitive; - FoundState state = FindPartialAddress(chars, chars, length, &addressState); - if (state == FOUND_PARTIAL && addressState.mProgress == ZIP_CODE && - addressState.mNumberCount == 0) { - addressState.mProgress = FIND_STREET; - state = FindPartialAddress(NULL, NULL, 0, &addressState); - } - *start = addressState.mStartResult; - *end = addressState.mEndResult; - return state; -} - -CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars, - const UChar* chars, unsigned length, FindState* s) -{ - // lower case letters are optional; trailing asterisk is optional 's' - static char const* const longStreetNames[] = { - "\x04" "LleY" "\x04" "NneX" "\x05" "RCade" "\x05" "VEnue" "\x06" "LAMEDA", // A - "\x04" "aYoU" "\x04" "eaCH" "\x03" "eND" "\x05" "LuFf*" "\x05" "oTtoM" - "\x08" "ouLeVarD" "\x05" "Ranch" "\x05" "RidGe" "\x05" "RooK*" - "\x04" "urG*" "\x05" "YPass" "\x07" "roadWAY", // B - "\x05" "AMINO" - "\x03" "amP" "\x05" "anYoN" "\x03" "aPE" "\x07" "auSeWaY" "\x06" "enTeR*" - "\x06" "IRcle*" "\x05" "LiFf*" "\x03" "LuB" "\x05" "oMmoN" "\x06" "ORner*" - "\x05" "ouRSE" "\x05" "ourT*" "\x04" "oVe*" "\x04" "ReeK" "\x07" "REScent" - "\x04" "ReST" "\x07" "ROSSING" "\x08" "ROSSROAD" "\x04" "URVe" - "\x05" "AMINO" "\x06" "IRCULO" "\x07" "REScent", // C - "\x03" "aLe" "\x02" "aM" "\x05" "iVide" "\x05" "Rive*", // D - "\x06" "STate*" "\x09" "XPresswaY" "\x09" "XTension*", // E - "\x04" "ALL*" "\x04" "eRrY" "\x05" "ieLD*" "\x04" "LaT*" "\x04" "oRD*" - "\x05" "oReST" "\x05" "oRGe*" "\x04" "oRK*" "\x03" "orT" "\x06" "reeWaY", // F - "\x06" "arDeN*" "\x06" "aTeWaY" "\x04" "LeN*" "\x05" "ReeN*" "\x05" "RoVe*", // G - "\x06" "arBoR*" "\x04" "aVeN" "\x06" "eighTS" "\x06" "ighWaY" "\x04" "iLl*" - "\x05" "OLloW", // H - "\x04" "NLeT" "\x06" "Sland*" "\x03" "SLE", // I - "\x08" "unCTion*", // J - "\x03" "eY*" "\x05" "NoLl*", // K - "\x04" "aKe*" "\x03" "AND" "\x06" "aNDinG" "\x03" "aNe" "\x05" "iGhT*" - "\x03" "oaF" "\x04" "oCK*" "\x04" "oDGe" "\x03" "OOP", // L - "\x03" "ALL" "\x05" "aNoR*" "\x06" "eaDoW*" "\x03" "EWS" "\x04" "iLl*" - "\x06" "iSsioN" "\x07" "oTorWaY" "\x04" "ounT" "\x08" "ounTaiN*", // M - "\x03" "eCK", // N - "\x06" "RCHard" "\x03" "VAL" "\x07" "verPASs", // O - "\x04" "ARK*" "\x07" "arKWaY*" "\x03" "ASS" "\x06" "aSsaGE" "\x03" "ATH" - "\x03" "IKE" "\x04" "iNE*" "\x04" "Lace" "\x05" "LaiN*" "\x04" "LaZa" - "\x05" "oinT*" "\x04" "oRT*" "\x06" "Rairie" "\x06" "RIVADA", // P - NULL, - "\x05" "ADiaL" "\x03" "AMP" "\x04" "aNCH" "\x05" "aPiD*" - "\x03" "eST" - "\x05" "iDGe*" "\x04" "IVer" "\x04" "oaD*" "\x04" "ouTE" "\x02" "OW" - "\x02" "UE" "\x02" "UN", // R - "\x05" "HoaL*" "\x05" "HoRe*" "\x05" "KyWaY" "\x06" "PrinG*" "\x04" "PUR*" - "\x06" "Quare*" "\x06" "TAtion" "\x08" "TRAvenue" "\x05" "TReaM" - "\x06" "Treet*" "\x05" "uMmiT" "\x07" "PeeDWaY", // S - "\x06" "ERrace" "\x09" "hRoughWaY" "\x04" "RaCE" "\x04" "RAcK" "\x09" "RaFficwaY" - "\x04" "RaiL" "\x05" "UNneL" "\x07" "urnPiKE", // T - "\x08" "nderPASs" "\x05" "Nion*", // U - "\x06" "aLleY*" "\x06" "IAduct" "\x04" "ieW*" "\x07" "iLlaGe*" "\x04" "iLle" - "\x04" "ISta", // V - "\x04" "ALK*" "\x03" "ALL" "\x03" "AY*" "\x04" "eLl*", // W - "\x03" "ING" "\x02" "RD", // X - }; - - static char const* const longStateNames[] = { - "\x8e" "la" "\x85" "bama" "\x02" "\x84" "ska" "\x01" "\x8f" "merican Samoa" "\x04" - "\x91" "r" "\x86" "izona" "\x05" "\x87" "kansas" "\x03", - NULL, - "\x8b" "alifornia" "\x06" "\x95" "o" "\x87" "lorado" "\x07" "\x8a" "nnecticut" "\x08", - "\x89" "elaware" "\x0a" "\x95" "istrict of Columbia" "\x09", - NULL, - "\x9f" "ederated States of Micronesia" "\x0c" "\x88" "lorida" "\x0b", - "\x85" "uam" "\x0e" "\x88" "eorgia" "\x0d", - "\x87" "awaii" "\x0f", - "\x86" "daho" "\x11" "\x89" "llinois" "\x12" "\x88" "ndiana" "\x13" "\x85" - "owa" "\x10", - NULL, - "\x87" "ansas" "\x14" "\x89" "entucky" "\x15", - "\x8a" "ouisiana" "\x16", - "\x86" "aine" "\x19" "\x99" "ar" "\x8e" "shall Islands" "\x1a" "\x86" "yland" "\x18" - "\x8e" "assachusetts" "\x17" "\x93" "i" "\x87" "chigan" "\x1b" - "\x88" "nnesota" "\x1c" "\x93" "iss" "\x88" "issippi" "\x1f" "\x85" - "ouri" "\x1d" "\x88" "ontana" "\x20", - "\x90" "e" "\x87" "braska" "\x23" "\x85" "vada" "\x27" "\xa5" "ew " "\x8a" - "Hampshire" "\x24" "\x87" "Jersey" "\x25" "\x87" "Mexico" "\x26" - "\x85" "York" "\x28" "\x98" "orth " "\x89" "Carolina" "\x21" "\x87" - "Dakota" "\x22" "\x99" "orthern Mariana Islands" "\x1e", - "\x85" "hio" "\x29" "\x89" "klahoma" "\x2a" "\x87" "regon" "\x2b", - "\x86" "alau" "\x2e" "\x8d" "ennsylvania" "\x2c" "\x8c" "uerto Rico" "\x2d", - NULL, - "\x8d" "hode Island" "\x2f", - "\x98" "outh " "\x89" "Carolina" "\x30" "\x87" "Dakota" "\x31", - "\x90" "e" "\x88" "nnessee" "\x32" "\x84" "xas" "\x33", - "\x85" "tah" "\x34", - "\x88" "ermont" "\x37" "\x94" "irgin" "\x89" " Islands" "\x36" "\x83" "ia" "\x35", - "\x8b" "ashington" "\x38" "\x8e" "est Virginia" "\x3a" "\x8a" "isconsin" "\x39" - "\x88" "yoming" "\x3b" - }; - -#if 0 // DEBUG_NAV_UI - static char const* const progressNames[] = { - "NO_ADDRESS", - "SKIP_TO_SPACE", - "HOUSE_NUMBER", - "NUMBER_TRAILING_SPACE", - "ADDRESS_LINE", - "STATE_NAME", - "SECOND_HALF", - "ZIP_CODE", - "PLUS_4", - "FIND_STREET" - }; -#endif - // strategy: US only support at first - // look for a 1 - 5 digit number for a street number (no support for 'One Microsoft Way') - // ignore if preceded by '#', Suite, Ste, Rm - // look for two or more words (up to 5? North Frank Lloyd Wright Blvd) - // note: "The Circle at North Hills St." has six words, and a lower 'at' -- allow at, by, of, in, the, and, ... ? - // if a word starts with a lowercase letter, no match - // allow: , . - # / (for 1/2) ' " - // don't look for street name type yet - // look for one or two delimiters to represent possible 2nd addr line and city name - // look for either full state name, or state two letters, and/or zip code (5 or 9 digits) - // now look for street suffix, either in full or abbreviated form, with optional 's' if there's an asterisk - - s->mCurrentStart = chars; - s->mEnd = chars + length; - int candIndex = 0; - bool retryState; - bool mustBeAllUpper = false; - bool secondHalf = false; - chars -= 1; - UChar ch = s->mCurrent; - while (++chars <= s->mEnd) { - UChar prior = ch; - ch = chars < s->mEnd ? *chars : ' '; - switch (s->mProgress) { - case NO_ADDRESS: - if (WTF::isASCIIDigit(ch) == false) { - if (ch != 'O') // letter 'O', not zero - continue; - if (s->mEnd - chars < 3) - continue; - prior = *++chars; - ch = *++chars; - if ((prior != 'n' || ch != 'e') && (prior != 'N' || ch != 'E')) - continue; - if (isUnicodeSpace(*++chars) == false) - continue; - s->mProgress = ADDRESS_LINE; - s->mStartResult = chars - 3 - s->mCurrentStart; - continue; - } - if (isUnicodeSpace(prior) == false) { - s->mProgress = SKIP_TO_SPACE; - continue; - } - s->mNumberCount = 1; - s->mProgress = HOUSE_NUMBER; - s->mStartResult = chars - s->mCurrentStart; - continue; - case SKIP_TO_SPACE: - if (isUnicodeSpace(ch) == false) - continue; - break; - case HOUSE_NUMBER: - if (WTF::isASCIIDigit(ch)) { - if (++s->mNumberCount >= 6) - s->mProgress = SKIP_TO_SPACE; - continue; - } - if (WTF::isASCIIUpper(ch)) { // allow one letter after house number, e.g. 12A SKOLFIELD PL, HARPSWELL, ME 04079 - if (WTF::isASCIIDigit(prior) == false) - s->mProgress = SKIP_TO_SPACE; - continue; - } - if (ch == '-') { - if (s->mNumberCount > 0) { // permit 21-23 ELM ST - ++s->mNumberCount; - continue; - } - } - s->mNumberCount = 0; - s->mProgress = NUMBER_TRAILING_SPACE; - case NUMBER_TRAILING_SPACE: - if (isUnicodeSpace(ch)) - continue; - if (0 && WTF::isASCIIDigit(ch)) { - s->mNumberCount = 1; - s->mProgress = HOUSE_NUMBER; - s->mStartResult = chars - s->mCurrentStart; - continue; - } - if (WTF::isASCIIDigit(ch) == false && WTF::isASCIIUpper(ch) == false) - break; - s->mProgress = ADDRESS_LINE; - case ADDRESS_LINE: - if (WTF::isASCIIAlpha(ch) || ch == '\'' || ch == '-' || ch == '&' || ch == '(' || ch == ')') { - if (++s->mLetterCount > 1) { - s->mNumberWords &= ~(1 << s->mWordCount); - continue; - } - if (s->mNumberCount >= 5) - break; -// FIXME: the test below was added to give up on a non-address, but it -// incorrectly discards addresses where the house number is in one node -// and the street name is in the next; I don't recall what the failing case -// is that suggested this fix. -// if (s->mWordCount == 0 && s->mContinuationNode) -// return FOUND_NONE; - s->newWord(baseChars, chars); - if (WTF::isASCIILower(ch) && s->mNumberCount == 0) - s->mFirstLower = chars; - s->mNumberCount = 0; - if (WTF::isASCIILower(ch) || (WTF::isASCIIAlpha(ch) == false && ch != '-')) - s->mNumberWords &= ~(1 << s->mWordCount); - s->mUnparsed = true; - continue; - } else if (s->mLetterCount >= MAX_PLACE_NAME_LENGTH) { - break; - } else if (s->mFirstLower != NULL) { - if (s->mCaseInsensitive) - goto resetWord; - size_t length = chars - s->mFirstLower; - if (length > 3) - break; - if (length == 3 && strCharCmp("and" "the", s->mFirstLower, 3, 2) == false) - break; - if (length == 2 && strCharCmp("at" "by" "el" "in" "of", s->mFirstLower, 2, 5) == false) - break; - goto resetWord; - } - if (ch == ',' || ch == '*') { // delimits lines - // asterisk as delimiter: http://www.sa.sc.edu/wellness/members.html - if (++s->mLineCount > 5) - break; - goto lookForState; - } - if (isUnicodeSpace(ch) || prior == '-') { - lookForState: - if (s->mUnparsed == false) - continue; - const UChar* candidate = s->mWords[s->mWordCount]; - UChar firstLetter = candidate[0]; - if (WTF::isASCIIUpper(firstLetter) == false && WTF::isASCIIDigit(firstLetter) == false) - goto resetWord; - s->mWordCount++; - if ((s->mWordCount == 2 && s->mNumberWords == 3 && WTF::isASCIIDigit(s->mWords[1][1])) || // choose second of 8888 333 Main - (s->mWordCount >= sizeof(s->mWords) / sizeof(s->mWords[0]) - 1)) { // subtract 1 since state names may have two parts - // search for simple number already stored since first potential house # didn't pan out - if (s->mNumberWords == 0) - break; - int shift = 0; - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - s->mNumberWords >>= ++shift; - if (s->mBases[0] != s->mBases[shift]) // if we're past the original node, bail - break; - s->shiftWords(shift); - s->mStartResult = s->mWords[0] - s->mStarts[0]; - s->mWordCount -= shift; - // FIXME: need to adjust lineCount to account for discarded delimiters - } - if (s->mWordCount < 4) - goto resetWord; - firstLetter -= 'A'; - if (firstLetter > 'W' - 'A') - goto resetWord; - UChar secondLetter = candidate[1]; - if (prior == '-') - s->mLetterCount--; // trim trailing dashes, to accept CA-94043 - if (s->mLetterCount == 2) { - secondLetter -= 'A'; - if (secondLetter > 'Z' - 'A') - goto resetWord; - if ((stateTwoLetter[firstLetter] & 1 << secondLetter) != 0) { - // special case to ignore 'et al' - if (strCharCmp("ET", s->mWords[s->mWordCount - 2], 2, 1) == false) { - s->mStateWord = s->mWordCount - 1; - s->mZipHint = firstIndex[firstLetter] + - bitcount(stateTwoLetter[firstLetter] & ((1 << secondLetter) - 1)); - goto foundStateName; - } - } - goto resetWord; - } - s->mStates = longStateNames[firstLetter]; - if (s->mStates == NULL) - goto resetWord; - mustBeAllUpper = false; - s->mProgress = STATE_NAME; - unsigned char section = s->mStates[0]; - ASSERT(section > 0x80); - s->mSectionLength = section & 0x7f; - candIndex = 1; - secondHalf = false; - s->mStateWord = s->mWordCount - 1; - goto stateName; - } - if (WTF::isASCIIDigit(ch)) { - if (s->mLetterCount == 0) { - if (++s->mNumberCount > 1) - continue; - if (s->mWordCount == 0 && s->mContinuationNode) - return FOUND_NONE; - s->newWord(baseChars, chars); - s->mNumberWords |= 1 << s->mWordCount; - s->mUnparsed = true; - } - continue; - } - if (ch == '.') { // optionally can follow letters - if (s->mLetterCount == 0) - break; - if (s->mNumberCount > 0) - break; - continue; - } - if (ch == '/') // between numbers (1/2) between words (12 Main / Ste 4d) - goto resetWord; - if (ch == '#') // can precede numbers, allow it to appear randomly - goto resetWord; - if (ch == '"') // sometimes parts of addresses are quoted (FIXME: cite an example here) - continue; - break; - case SECOND_HALF: - if (WTF::isASCIIAlpha(ch)) { - if (s->mLetterCount == 0) { - s->newWord(baseChars, chars); - s->mWordCount++; - } - s->mLetterCount++; - continue; - } - if (WTF::isASCIIDigit(ch) == false) { - if (s->mLetterCount > 0) { - s->mProgress = STATE_NAME; - candIndex = 0; - secondHalf = true; - goto stateName; - } - continue; - } - s->mProgress = ADDRESS_LINE; - goto resetState; - case STATE_NAME: - stateName: - // pick up length of first section - do { - int stateIndex = 1; - int skip = 0; - int prefix = 0; - bool subStr = false; - do { - unsigned char match = s->mStates[stateIndex]; - if (match >= 0x80) { - if (stateIndex == s->mSectionLength) - break; - subStr = true; - // if (skip > 0) - // goto foundStateName; - prefix = candIndex; - skip = match & 0x7f; - match = s->mStates[++stateIndex]; - } - UChar candChar = s->mWords[s->mWordCount - 1][candIndex]; - if (mustBeAllUpper && WTF::isASCIILower(candChar)) - goto skipToNext; - if (match != candChar) { - if (match != WTF::toASCIILower(candChar)) { - skipToNext: - if (subStr == false) - break; - if (stateIndex == s->mSectionLength) { - if (secondHalf) { - s->mProgress = ADDRESS_LINE; - goto resetState; - } - break; - } - stateIndex += skip; - skip = 0; - candIndex = prefix; - continue; // try next substring - } - mustBeAllUpper = true; - } - int nextindex = stateIndex + 1; - if (++candIndex >= s->mLetterCount && s->mStates[nextindex] == ' ') { - s->mProgress = SECOND_HALF; - s->mStates += nextindex; - s->mSectionLength -= nextindex; - goto resetWord; - } - if (nextindex + 1 == s->mSectionLength || skip == 2) { - s->mZipHint = s->mStates[nextindex] - 1; - goto foundStateName; - } - stateIndex += 1; - skip -= 1; - } while (true); - s->mStates += s->mSectionLength; - ASSERT(s->mStates[0] == 0 || (unsigned) s->mStates[0] > 0x80); - s->mSectionLength = s->mStates[0] & 0x7f; - candIndex = 1; - subStr = false; - } while (s->mSectionLength != 0); - s->mProgress = ADDRESS_LINE; - goto resetState; - foundStateName: - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - s->mProgress = ZIP_CODE; - // a couple of delimiters is an indication that the state name is good - // or, a non-space / non-alpha-digit is also good - s->mZipDelimiter = s->mLineCount > 2 - || isUnicodeSpace(ch) == false - || chars == s->mEnd; - if (WTF::isASCIIDigit(ch)) - s->mZipStart = chars; - goto resetState; - case ZIP_CODE: - if (WTF::isASCIIDigit(ch)) { - int count = ++s->mNumberCount; - if (count == 1) { - if (WTF::isASCIIDigit(prior)) - ++s->mNumberCount; - else - s->mZipStart = chars; - } - if (count <= 9) - continue; - } else if (isUnicodeSpace(ch)) { - if (s->mNumberCount == 0) { - s->mZipDelimiter = true; // two spaces delimit state name - continue; - } - } else if (ch == '-') { - if (s->mNumberCount == 5 && validZip(s->mZipHint, s->mZipStart)) { - s->mNumberCount = 0; - s->mProgress = PLUS_4; - continue; - } - if (s->mNumberCount == 0) - s->mZipDelimiter = true; - } else if (WTF::isASCIIAlpha(ch) == false) - s->mZipDelimiter = true; - else { - if (s->mLetterCount == 0) { - s->newWord(baseChars, chars); - s->mUnparsed = true; - } - ++s->mLetterCount; - } - if (s->mNumberCount == 5 || s->mNumberCount == 9) { - if (validZip(s->mZipHint, s->mZipStart) == false) - goto noZipMatch; - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - } else if (s->mZipDelimiter == false) { - noZipMatch: - --chars; - s->mProgress = ADDRESS_LINE; - continue; - } - s->mProgress = FIND_STREET; - goto findStreet; - case PLUS_4: - if (WTF::isASCIIDigit(ch)) { - if (++s->mNumberCount <= 4) - continue; - } - if (isUnicodeSpace(ch)) { - if (s->mNumberCount == 0) - continue; - } - if (s->mNumberCount == 4) { - if (WTF::isASCIIAlpha(ch) == false) { - s->mEndResult = chars - s->mCurrentStart; - s->mEndWord = s->mWordCount - 1; - } - } else if (s->mNumberCount != 0) - break; - s->mProgress = FIND_STREET; - case FIND_STREET: - findStreet: - retryState = false; - for (int wordsIndex = s->mStateWord - 1; wordsIndex >= 0; --wordsIndex) { - const UChar* test = s->mWords[wordsIndex]; - UChar letter = test[0]; - letter -= 'A'; - if (letter > 'X' - 'A') - continue; - const char* names = longStreetNames[letter]; - if (names == NULL) - continue; - int offset; - while ((offset = *names++) != 0) { - int testIndex = 1; - bool abbr = false; - for (int idx = 0; idx < offset; idx++) { - char nameLetter = names[idx]; - char testUpper = WTF::toASCIIUpper(test[testIndex]); - if (nameLetter == '*') { - if (testUpper == 'S') - testIndex++; - break; - } - bool fullOnly = WTF::isASCIILower(nameLetter); - nameLetter = WTF::toASCIIUpper(nameLetter); - if (testUpper == nameLetter) { - if (abbr && fullOnly) - goto nextTest; - testIndex++; - continue; - } - if (fullOnly == false) - goto nextTest; - abbr = true; - } - letter = &test[testIndex] < s->mEnds[wordsIndex] ? - test[testIndex] : ' '; - if (WTF::isASCIIAlpha(letter) == false && WTF::isASCIIDigit(letter) == false) { - if (s->mNumberWords != 0) { - int shift = 0; - int wordReduction = -1; - do { - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - if (shift > wordsIndex) - break; - wordReduction = shift; - } while (s->mNumberWords >> ++shift != 0); - if (wordReduction >= 0) { - if (s->mContinuationNode) { - if (retryState) - break; - return FOUND_NONE; - } - s->mStartResult = s->mWords[wordReduction] - s->mStarts[wordReduction]; - } - } - if (wordsIndex != s->mStateWord - 1) - return FOUND_COMPLETE; - retryState = true; - } - nextTest: - names += offset; - } - } - if (retryState) { - s->mProgress = ADDRESS_LINE; - s->mStates = NULL; - continue; - } - if (s->mNumberWords != 0) { - unsigned shift = 0; - while ((s->mNumberWords & (1 << shift)) == 0) - shift++; - s->mNumberWords >>= ++shift; - if (s->mBases[0] != s->mBases[shift]) - return FOUND_NONE; - s->shiftWords(shift); - s->mStartResult = s->mWords[0] - s->mStarts[0]; - s->mWordCount -= shift; - s->mProgress = ADDRESS_LINE; - --chars; - continue; - } - break; - } - if (s->mContinuationNode) - return FOUND_NONE; - s->mProgress = NO_ADDRESS; - s->mWordCount = s->mLineCount = 0; - s->mNumberWords = 0; - resetState: - s->mStates = NULL; - resetWord: - s->mNumberCount = s->mLetterCount = 0; - s->mFirstLower = NULL; - s->mUnparsed = false; - } - s->mCurrent = ch; - return s->mProgress == NO_ADDRESS ? FOUND_NONE : FOUND_PARTIAL; -} - -// Recogize common email patterns only. Currently has lots of state, walks text forwards and backwards -- will be -// a real challenge to adapt to walk text across multiple nodes, I imagine -// FIXME: it's too hard for the caller to call these incrementally -- it's probably best for this to -// either walk the node tree directly or make a callout to get the next or previous node, if there is one -// walking directly will avoid adding logic in caller to track the multiple partial or full nodes that compose this -// text pattern. -CacheBuilder::FoundState CacheBuilder::FindPartialEMail(const UChar* chars, unsigned length, - FindState* s) -{ - // the following tables were generated by tests/browser/focusNavigation/BrowserDebug.cpp - // hand-edit at your own risk - static const int domainTwoLetter[] = { - 0x02df797c, // a followed by: [cdefgilmnoqrstuwxz] - 0x036e73fb, // b followed by: [abdefghijmnorstvwyz] - 0x03b67ded, // c followed by: [acdfghiklmnorsuvxyz] - 0x02005610, // d followed by: [ejkmoz] - 0x001e00d4, // e followed by: [ceghrstu] - 0x00025700, // f followed by: [ijkmor] - 0x015fb9fb, // g followed by: [abdefghilmnpqrstuwy] - 0x001a3400, // h followed by: [kmnrtu] - 0x000f7818, // i followed by: [delmnoqrst] - 0x0000d010, // j followed by: [emop] - 0x0342b1d0, // k followed by: [eghimnprwyz] - 0x013e0507, // l followed by: [abcikrstuvy] - 0x03fffccd, // m followed by: [acdghklmnopqrstuvwxyz] - 0x0212c975, // n followed by: [acefgilopruz] - 0x00001000, // o followed by: [m] - 0x014e3cf1, // p followed by: [aefghklmnrstwy] - 0x00000001, // q followed by: [a] - 0x00504010, // r followed by: [eouw] - 0x032a7fdf, // s followed by: [abcdeghijklmnortvyz] - 0x026afeec, // t followed by: [cdfghjklmnoprtvwz] - 0x03041441, // u followed by: [agkmsyz] - 0x00102155, // v followed by: [aceginu] - 0x00040020, // w followed by: [fs] - 0x00000000, // x - 0x00180010, // y followed by: [etu] - 0x00401001, // z followed by: [amw] - }; - - static char const* const longDomainNames[] = { - "\x03" "ero" "\x03" "rpa", // aero, arpa - "\x02" "iz", // biz - "\x02" "at" "\x02" "om" "\x03" "oop", // cat, com, coop - NULL, // d - "\x02" "du", // edu - NULL, // f - "\x02" "ov", // gov - NULL, // h - "\x03" "nfo" "\x02" "nt", // info, int - "\x03" "obs", // jobs - NULL, // k - NULL, // l - "\x02" "il" "\x03" "obi" "\x05" "useum", // mil, mobi, museum - "\x03" "ame" "\x02" "et", // name, net - "\x02" "rg", // , org - "\x02" "ro", // pro - NULL, // q - NULL, // r - NULL, // s - "\x05" "ravel", // travel - NULL, // u - NULL, // v - NULL, // w - NULL, // x - NULL, // y - NULL, // z - }; - - const UChar* start = chars; - const UChar* end = chars + length; - while (chars < end) { - UChar ch = *chars++; - if (ch != '@') - continue; - const UChar* atLocation = chars - 1; - // search for domain - ch = *chars++ | 0x20; // convert uppercase to lower - if (ch < 'a' || ch > 'z') - continue; - while (chars < end) { - ch = *chars++; - if (IsDomainChar(ch) == false) - goto nextAt; - if (ch != '.') - continue; - UChar firstLetter = *chars++ | 0x20; // first letter of the domain - if (chars >= end) - return FOUND_NONE; // only one letter; must be at least two - firstLetter -= 'a'; - if (firstLetter > 'z' - 'a') - continue; // non-letter followed '.' - int secondLetterMask = domainTwoLetter[firstLetter]; - ch = *chars | 0x20; // second letter of the domain - ch -= 'a'; - if (ch >= 'z' - 'a') - continue; - bool secondMatch = (secondLetterMask & 1 << ch) != 0; - const char* wordMatch = longDomainNames[firstLetter]; - int wordIndex = 0; - while (wordMatch != NULL) { - int len = *wordMatch++; - char match; - do { - match = wordMatch[wordIndex]; - if (match < 0x20) - goto foundDomainStart; - if (chars[wordIndex] != match) - break; - wordIndex++; - } while (true); - wordMatch += len; - if (*wordMatch == '\0') - break; - wordIndex = 0; - } - if (secondMatch) { - wordIndex = 1; - foundDomainStart: - chars += wordIndex; - if (chars < end) { - ch = *chars; - if (ch != '.') { - if (IsDomainChar(ch)) - goto nextDot; - } else if (chars + 1 < end && IsDomainChar(chars[1])) - goto nextDot; - } - // found domain. Search backwards from '@' for beginning of email address - s->mEndResult = chars - start; - chars = atLocation; - if (chars <= start) - goto nextAt; - ch = *--chars; - if (ch == '.') - goto nextAt; // mailbox can't end in period - do { - if (IsMailboxChar(ch) == false) { - chars++; - break; - } - if (chars == start) - break; - ch = *--chars; - } while (true); - UChar firstChar = *chars; - if (firstChar == '.' || firstChar == '@') // mailbox can't start with period or be empty - goto nextAt; - s->mStartResult = chars - start; - return FOUND_COMPLETE; - } - nextDot: - ; - } -nextAt: - chars = atLocation + 1; - } - return FOUND_NONE; -} - -#define PHONE_PATTERN "(200) /-.\\ 100 -. 0000" // poor man's regex: parens optional, any one of punct, digit smallest allowed - -CacheBuilder::FoundState CacheBuilder::FindPartialNumber(const UChar* chars, unsigned length, - FindState* s) -{ - char* pattern = s->mPattern; - UChar* store = s->mStorePtr; - const UChar* start = chars; - const UChar* end = chars + length; - const UChar* lastDigit = NULL; - do { - bool initialized = s->mInitialized; - while (chars < end) { - if (initialized == false) { - s->mBackTwo = s->mBackOne; - s->mBackOne = s->mCurrent; - } - UChar ch = s->mCurrent = *chars; - do { - char patternChar = *pattern; - switch (patternChar) { - case '2': - if (initialized == false) { - s->mStartResult = chars - start; - initialized = true; - } - case '0': - case '1': - if (ch < patternChar || ch > '9') - goto resetPattern; - *store++ = ch; - pattern++; - lastDigit = chars; - goto nextChar; - case '\0': - if (WTF::isASCIIDigit(ch) == false) { - *store = '\0'; - goto checkMatch; - } - goto resetPattern; - case ' ': - if (ch == patternChar) - goto nextChar; - break; - case '(': - if (ch == patternChar) { - s->mStartResult = chars - start; - initialized = true; - s->mOpenParen = true; - } - goto commonPunctuation; - case ')': - if ((ch == patternChar) ^ s->mOpenParen) - goto resetPattern; - default: - commonPunctuation: - if (ch == patternChar) { - pattern++; - goto nextChar; - } - } - } while (++pattern); // never false - nextChar: - chars++; - } - break; -resetPattern: - if (s->mContinuationNode) - return FOUND_NONE; - FindResetNumber(s); - pattern = s->mPattern; - store = s->mStorePtr; - } while (++chars < end); -checkMatch: - if (WTF::isASCIIDigit(s->mBackOne != '1' ? s->mBackOne : s->mBackTwo)) - return FOUND_NONE; - *store = '\0'; - s->mStorePtr = store; - s->mPattern = pattern; - s->mEndResult = lastDigit - start + 1; - char pState = pattern[0]; - return pState == '\0' ? FOUND_COMPLETE : pState == '(' || (WTF::isASCIIDigit(pState) && WTF::isASCIIDigit(pattern[-1])) ? - FOUND_NONE : FOUND_PARTIAL; -} - -CacheBuilder::FoundState CacheBuilder::FindPhoneNumber(const UChar* chars, unsigned length, - int* start, int* end) -{ - FindState state; - FindReset(&state); - FoundState result = FindPartialNumber(chars, length, &state); - *start = state.mStartResult; - *end = state.mEndResult; - return result; -} - -void CacheBuilder::FindReset(FindState* state) -{ - memset(state, 0, sizeof(FindState)); - state->mCurrent = ' '; - FindResetNumber(state); -} - -void CacheBuilder::FindResetNumber(FindState* state) -{ - state->mOpenParen = false; - state->mPattern = (char*) PHONE_PATTERN; - state->mStorePtr = state->mStore; -} - -IntRect CacheBuilder::getAreaRect(const HTMLAreaElement* area) -{ - Node* node = area->document(); - while ((node = node->traverseNextNode()) != NULL) { - RenderObject* renderer = node->renderer(); - if (renderer && renderer->isRenderImage()) { - RenderImage* image = static_cast<RenderImage*>(renderer); - HTMLMapElement* map = image->imageMap(); - if (map) { - Node* n; - for (n = map->firstChild(); n; - n = n->traverseNextNode(map)) { - if (n == area) { - if (area->isDefault()) - return image->absoluteBoundingBoxRect(); - return area->getRect(image); - } - } - } - } - } - return IntRect(); -} - -void CacheBuilder::GetGlobalOffset(Node* node, int* x, int * y) -{ - GetGlobalOffset(node->document()->frame(), x, y); -} - -void CacheBuilder::GetGlobalOffset(Frame* frame, int* x, int* y) -{ -// TIMER_PROBE(__FUNCTION__); - ASSERT(x); - ASSERT(y); - *x = 0; - *y = 0; - if (!frame->view()) - return; - Frame* parent; - while ((parent = frame->tree()->parent()) != NULL) { - const WebCore::IntRect& rect = frame->view()->platformWidget()->getBounds(); - *x += rect.x(); - *y += rect.y(); - frame = parent; - } - // TIMER_PROBE_END(); -} - -Frame* CacheBuilder::HasFrame(Node* node) -{ - RenderObject* renderer = node->renderer(); - if (renderer == NULL) - return NULL; - if (renderer->isWidget() == false) - return NULL; - Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); - if (widget == NULL) - return NULL; - if (widget->isFrameView() == false) - return NULL; - return static_cast<FrameView*>(widget)->frame(); -} - -bool CacheBuilder::HasOverOrOut(Node* node) -{ - // eventNames are thread-local data, I avoid using 'static' variable here. - AtomicString eventTypes[2] = { - eventNames().mouseoverEvent, - eventNames().mouseoutEvent - }; - - return NodeHasEventListeners(node, eventTypes, 2); -} - -bool CacheBuilder::HasTriggerEvent(Node* node) -{ - AtomicString eventTypes[5] = { - eventNames().clickEvent, - eventNames().mousedownEvent, - eventNames().mouseupEvent, - eventNames().keydownEvent, - eventNames().keyupEvent - }; - - return NodeHasEventListeners(node, eventTypes, 5); -} - -// #define EMAIL_PATTERN "x@y.d" // where 'x' is letters, numbers, and '-', '.', '_' ; 'y' is 'x' without the underscore, and 'd' is a valid domain -// - 0x2D . 0x2E 0-9 0x30-39 A-Z 0x41-5A _ 0x5F a-z 0x61-7A - -bool CacheBuilder::IsDomainChar(UChar ch) -{ - static const unsigned body[] = {0x03ff6000, 0x07fffffe, 0x07fffffe}; // 0-9 . - A-Z a-z - ch -= 0x20; - if (ch > 'z' - 0x20) - return false; - return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0; -} - -bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node, - CachedNodeType* type, String* exported) const -{ - Text* textNode = static_cast<Text*>(node); - StringImpl* string = textNode->dataImpl(); - const UChar* baseChars = string->characters(); -// const UChar* originalBase = baseChars; - int length = string->length(); - int index = 0; - while (index < length && isUnicodeSpace(baseChars[index])) - index++; - if (index >= length) - return false; - if (more == false) { - walk->mStart = 0; - walk->mEnd = 0; - walk->mFinalNode = node; - walk->mLastInline = NULL; - } - // starting with this node, search forward for email, phone number, and address - // if any of the three is found, track it so that the remaining can be looked for later - FoundState state = FOUND_NONE; - RenderText* renderer = (RenderText*) node->renderer(); - bool foundBetter = false; - InlineTextBox* baseInline = walk->mLastInline != NULL ? walk->mLastInline : - renderer->firstTextBox(); - if (baseInline == NULL) - return false; - int start = walk->mEnd; - InlineTextBox* saveInline; - int baseStart, firstStart = start; - saveInline = baseInline; - baseStart = start; - for (CachedNodeType checkType = ADDRESS_CACHEDNODETYPE; - checkType <= PHONE_CACHEDNODETYPE; - checkType = static_cast<CachedNodeType>(checkType + 1)) - { - if ((1 << (checkType - 1) & mAllowableTypes) == 0) - continue; - InlineTextBox* inlineTextBox = baseInline; - FindState findState; - FindReset(&findState); - start = baseStart; - if (checkType == ADDRESS_CACHEDNODETYPE) { - findState.mBases[0] = baseChars; - findState.mWords[0] = baseChars + start; - findState.mStarts[0] = baseChars + start; - } - Node* lastPartialNode = NULL; - int lastPartialEnd = -1; - bool lastPartialMore = false; - bool firstPartial = true; - InlineTextBox* lastPartialInline = NULL; - do { - do { - const UChar* chars = baseChars + start; - length = inlineTextBox == NULL ? 0 : - inlineTextBox->end() - start + 1; - bool wasInitialized = findState.mInitialized; - switch (checkType) { - case ADDRESS_CACHEDNODETYPE: - state = FindPartialAddress(baseChars, chars, length, &findState); - break; - case EMAIL_CACHEDNODETYPE: - state = FindPartialEMail(chars, length, &findState); - break; - case PHONE_CACHEDNODETYPE: - state = FindPartialNumber(chars, length, &findState); - break; - default: - ASSERT(0); - } - findState.mInitialized = state != FOUND_NONE; - if (wasInitialized != findState.mInitialized) - firstStart = start; - if (state == FOUND_PARTIAL) { - lastPartialNode = node; - lastPartialEnd = findState.mEndResult + start; - lastPartialMore = firstPartial && - lastPartialEnd < (int) string->length(); - firstPartial = false; - lastPartialInline = inlineTextBox; - findState.mContinuationNode = true; - } else if (state == FOUND_COMPLETE) { - if (foundBetter == false || walk->mStart > findState.mStartResult) { - walk->mStart = findState.mStartResult + firstStart; - if (findState.mEndResult > 0) { - walk->mFinalNode = node; - walk->mEnd = findState.mEndResult + start; - walk->mMore = node == textNode && - walk->mEnd < (int) string->length(); - walk->mLastInline = inlineTextBox; - } else { - walk->mFinalNode = lastPartialNode; - walk->mEnd = lastPartialEnd; - walk->mMore = lastPartialMore; - walk->mLastInline = lastPartialInline; - } - *type = checkType; - if (checkType == PHONE_CACHEDNODETYPE) { - const UChar* store = findState.mStore; - *exported = String(store); - } else { - Node* temp = textNode; - length = 1; - start = walk->mStart; - exported->truncate(0); - do { - Text* tempText = static_cast<Text*>(temp); - StringImpl* string = tempText->dataImpl(); - int end = tempText == walk->mFinalNode ? - walk->mEnd : string->length(); - exported->append(String(string->substring( - start, end - start))); - ASSERT(end > start); - length += end - start + 1; - if (temp == walk->mFinalNode) - break; - start = 0; - do { - temp = temp->traverseNextNode(); - ASSERT(temp); - } while (temp->isTextNode() == false); - // add a space in between text nodes to avoid - // words collapsing together - exported->append(" "); - } while (true); - } - foundBetter = true; - } - goto tryNextCheckType; - } else if (findState.mContinuationNode) - break; - if (inlineTextBox == NULL) - break; - inlineTextBox = inlineTextBox->nextTextBox(); - if (inlineTextBox == NULL) - break; - start = inlineTextBox->start(); - if (state == FOUND_PARTIAL && node == textNode) - findState.mContinuationNode = false; - } while (true); - if (state == FOUND_NONE) - break; - // search for next text node, if any - Text* nextNode; - do { - do { - do { - if (node) - node = node->traverseNextNode(); - if (node == NULL || node->hasTagName(HTMLNames::aTag) - || node->hasTagName(HTMLNames::inputTag) - || node->hasTagName(HTMLNames::textareaTag)) { - if (state == FOUND_PARTIAL && - checkType == ADDRESS_CACHEDNODETYPE && - findState.mProgress == ZIP_CODE && - findState.mNumberCount == 0) { - baseChars = NULL; - inlineTextBox = NULL; - start = 0; - findState.mProgress = FIND_STREET; - goto finalNode; - } - goto tryNextCheckType; - } - } while (node->isTextNode() == false); - nextNode = static_cast<Text*>(node); - renderer = (RenderText*) nextNode->renderer(); - } while (renderer == NULL); - baseInline = renderer->firstTextBox(); - } while (baseInline == NULL); - string = nextNode->dataImpl(); - baseChars = string->characters(); - inlineTextBox = baseInline; - start = inlineTextBox->start(); - finalNode: - findState.mEndResult = 0; - } while (true); -tryNextCheckType: - node = textNode; - baseInline = saveInline; - string = textNode->dataImpl(); - baseChars = string->characters(); - } - if (foundBetter) { - CachedNodeType temp = *type; - switch (temp) { - case ADDRESS_CACHEDNODETYPE: { - static const char geoString[] = "geo:0,0?q="; - exported->insert(String(geoString), 0); - int index = sizeof(geoString) - 1; - String escapedComma("%2C"); - while ((index = exported->find(',', index)) >= 0) - exported->replace(index, 1, escapedComma); - } break; - case EMAIL_CACHEDNODETYPE: { - String encoded = WebCore::encodeWithURLEscapeSequences(*exported); - exported->swap(encoded); - exported->insert(WTF::String("mailto:"), 0); - } break; - case PHONE_CACHEDNODETYPE: - exported->insert(WTF::String("tel:"), 0); - break; - default: - break; - } - return true; - } -noTextMatch: - walk->reset(); - return false; -} - -bool CacheBuilder::IsMailboxChar(UChar ch) -{ - // According to http://en.wikipedia.org/wiki/Email_address - // ! # $ % & ' * + - . / 0-9 = ? - // A-Z ^ _ - // ` a-z { | } ~ - static const unsigned body[] = {0xa3ffecfa, 0xc7fffffe, 0x7fffffff}; - ch -= 0x20; - if (ch > '~' - 0x20) - return false; - return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0; -} - -bool CacheBuilder::setData(CachedFrame* cachedFrame) -{ - Frame* frame = FrameAnd(this); - Document* doc = frame->document(); - if (doc == NULL) - return false; - RenderObject* renderer = doc->renderer(); - if (renderer == NULL) - return false; - RenderLayer* layer = renderer->enclosingLayer(); - if (layer == NULL) - return false; - if (layer->width() == 0 || layer->height() == 0) - return false; - if (!frame->view()) - return false; - int x, y; - GetGlobalOffset(frame, &x, &y); - WebCore::IntRect viewBounds = frame->view()->platformWidget()->getBounds(); - if ((x | y) != 0) - viewBounds.setLocation(WebCore::IntPoint(x, y)); - cachedFrame->setLocalViewBounds(viewBounds); - cachedFrame->setContentsSize(layer->width(), layer->height()); - if (cachedFrame->childCount() == 0) - return true; - CachedFrame* lastCachedFrame = cachedFrame->lastChild(); - cachedFrame = cachedFrame->firstChild(); - do { - CacheBuilder* cacheBuilder = Builder((Frame* )cachedFrame->framePointer()); - cacheBuilder->setData(cachedFrame); - } while (cachedFrame++ != lastCachedFrame); - return true; -} - -#if USE(ACCELERATED_COMPOSITING) -void CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker, - RenderObject* nodeRenderer, Node* lastChild, int offsetX, int offsetY) -{ - RenderLayer* layer = nodeRenderer->enclosingLayer(); - RenderLayerBacking* back = layer->backing(); - if (!back) - return; - GraphicsLayer* grLayer = back->graphicsLayer(); - if (back->hasContentsLayer()) - grLayer = back->foregroundLayer(); - if (!grLayer) - return; - LayerAndroid* aLayer = grLayer->platformLayer(); - if (!aLayer) - return; - IntPoint scroll(layer->scrollXOffset(), layer->scrollYOffset()); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - // If this is an overflow element, track the content layer. - if (layer->hasOverflowScroll() && aLayer->getChild(0)) - aLayer = aLayer->getChild(0)->getChild(0); - if (!aLayer) - return; - // Prevent a crash when scrolling a layer that does not have a parent. - if (layer->stackingContext()) - layer->scrollToOffset(0, 0, false, false); -#endif - layerTracker.grow(layerTracker.size() + 1); - LayerTracker& indexTracker = layerTracker.last(); - indexTracker.mLayer = aLayer; - indexTracker.mRenderLayer = layer; - indexTracker.mBounds = enclosingIntRect(aLayer->bounds()); - // Use the absolute location of the layer as the bounds location. This - // provides the original offset of nodes in the layer so that we can - // translate nodes between their original location and the layer's new - // location. - indexTracker.mBounds.setLocation(layer->absoluteBoundingBox().location()); - indexTracker.mBounds.move(offsetX, offsetY); - indexTracker.mScroll = scroll; - indexTracker.mLastChild = OneAfter(lastChild); - DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer, - aLayer->uniqueId(), indexTracker.mBounds.x(), indexTracker.mBounds.y(), - indexTracker.mBounds.width(), indexTracker.mBounds.height()); -} -#endif - -bool CacheBuilder::validNode(Frame* startFrame, void* matchFrame, - void* matchNode) -{ - if (matchFrame == startFrame) { - if (matchNode == NULL) - return true; - Node* node = startFrame->document(); - while (node != NULL) { - if (node == matchNode) { - const IntRect& rect = node->hasTagName(HTMLNames::areaTag) ? - getAreaRect(static_cast<HTMLAreaElement*>(node)) : node->getRect(); - // Consider nodes with empty rects that are not at the origin - // to be valid, since news.google.com has valid nodes like this - if (rect.x() == 0 && rect.y() == 0 && rect.isEmpty()) - return false; - return true; - } - node = node->traverseNextNode(); - } - DBG_NAV_LOGD("frame=%p valid node=%p invalid\n", matchFrame, matchNode); - return false; - } - Frame* child = startFrame->tree()->firstChild(); - while (child) { - bool result = validNode(child, matchFrame, matchNode); - if (result) - return result; - child = child->tree()->nextSibling(); - } -#if DEBUG_NAV_UI - if (startFrame->tree()->parent() == NULL) - DBG_NAV_LOGD("frame=%p node=%p false\n", matchFrame, matchNode); -#endif - return false; -} - -static int Area(const IntRect& rect) -{ - return rect.width() * rect.height(); -} - -bool CacheBuilder::AddPartRect(IntRect& bounds, int x, int y, - WTF::Vector<IntRect>* result, IntRect* focusBounds) -{ - if (bounds.isEmpty()) - return true; - bounds.move(x, y); - if (bounds.right() <= 0 || bounds.bottom() <= 0) - return true; - IntRect* work = result->begin() - 1; - IntRect* end = result->end(); - while (++work < end) { - if (work->contains(bounds)) - return true; - if (bounds.contains(*work)) { - *work = bounds; - focusBounds->unite(bounds); - return true; - } - if ((bounds.x() != work->x() || bounds.width() != work->width()) && - (bounds.y() != work->y() || bounds.height() != work->height())) - continue; - IntRect test = *work; - test.unite(bounds); - if (Area(test) > Area(*work) + Area(bounds)) - continue; - *work = test; - focusBounds->unite(bounds); - return true; - } - if (result->size() >= MAXIMUM_FOCUS_RING_COUNT) - return false; - result->append(bounds); - if (focusBounds->isEmpty()) - *focusBounds = bounds; - else - focusBounds->unite(bounds); - return true; -} - -bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds, - IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result, - int* imageCountPtr) -{ - WTF::Vector<ClipColumnTracker> clipTracker(1); - ClipColumnTracker* baseTracker = clipTracker.data(); // sentinel - bzero(baseTracker, sizeof(ClipColumnTracker)); - if (node->hasChildNodes() && node->hasTagName(HTMLNames::buttonTag) == false - && node->hasTagName(HTMLNames::selectTag) == false) { - // collect all text rects from first to last child - Node* test = node->firstChild(); - Node* last = NULL; - Node* prior = node; - while ((prior = prior->lastChild()) != NULL) - last = prior; - ASSERT(last != NULL); - bool nodeIsAnchor = node->hasTagName(HTMLNames::aTag); - do { - do { - const ClipColumnTracker* lastClip = &clipTracker.last(); - if (test != lastClip->mLastChild) - break; - clipTracker.removeLast(); - } while (true); - RenderObject* renderer = test->renderer(); - if (renderer == NULL) - continue; - EVisibility vis = renderer->style()->visibility(); - if (vis == HIDDEN) - continue; - bool hasClip = renderer->hasOverflowClip(); - size_t clipIndex = clipTracker.size(); - IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX); - if (hasClip || --clipIndex > 0) { - clipBounds = hasClip ? renderer->absoluteBoundingBoxRect() : - clipTracker.at(clipIndex).mBounds; // x, y fixup done by ConstructTextRect - } - if (test->isTextNode()) { - RenderText* renderText = (RenderText*) renderer; - InlineTextBox *textBox = renderText->firstTextBox(); - if (textBox == NULL) - continue; - if (ConstructTextRect((Text*) test, textBox, 0, INT_MAX, - x, y, focusBounds, clipBounds, result) == false) { - return false; - } - continue; - } - if (test->hasTagName(HTMLNames::imgTag)) { - IntRect bounds = test->getRect(); - bounds.intersect(clipBounds); - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - *imageCountPtr += 1; - continue; - } - if (hasClip == false) { - if (nodeIsAnchor && test->hasTagName(HTMLNames::divTag)) { - IntRect bounds = renderer->absoluteBoundingBoxRect(); // x, y fixup done by AddPartRect - int left = bounds.x() + ((RenderBox*)renderer)->paddingLeft() - + ((RenderBox*)renderer)->borderLeft(); - int top = bounds.y() + ((RenderBox*)renderer)->paddingTop() - + ((RenderBox*)renderer)->borderTop(); - int right = bounds.right() - ((RenderBox*)renderer)->paddingRight() - - ((RenderBox*)renderer)->borderRight(); - int bottom = bounds.bottom() - ((RenderBox*)renderer)->paddingBottom() - - ((RenderBox*)renderer)->borderBottom(); - if (left >= right || top >= bottom) - continue; - bounds = IntRect(left, top, right - left, bottom - top); - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - } - continue; - } - Node* lastChild = test->lastChild(); - if (lastChild == NULL) - continue; - clipTracker.grow(clipTracker.size() + 1); - ClipColumnTracker& clip = clipTracker.last(); - clip.mBounds = renderer->absoluteBoundingBoxRect(); // x, y fixup done by ConstructTextRect - clip.mLastChild = OneAfter(lastChild); - clip.mNode = test; - } while (test != last && (test = test->traverseNextNode()) != NULL); - } - if (result->size() == 0 || focusBounds->width() < MINIMUM_FOCUSABLE_WIDTH - || focusBounds->height() < MINIMUM_FOCUSABLE_HEIGHT) { - if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH) - return false; - if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) - return false; - result->append(bounds); - *focusBounds = bounds; - } - return true; -} - -static inline bool isNotSpace(UChar c) -{ - return c <= 0xA0 ? isUnicodeSpace(c) == false : - WTF::Unicode::direction(c) != WTF::Unicode::WhiteSpaceNeutral; -} - -bool CacheBuilder::ConstructTextRect(Text* textNode, - InlineTextBox* textBox, int start, int relEnd, int x, int y, - IntRect* focusBounds, const IntRect& clipBounds, WTF::Vector<IntRect>* result) -{ - RenderText* renderText = (RenderText*) textNode->renderer(); - EVisibility vis = renderText->style()->visibility(); - StringImpl* string = textNode->dataImpl(); - const UChar* chars = string->characters(); - FloatPoint pt = renderText->localToAbsolute(); - do { - int textBoxStart = textBox->start(); - int textBoxEnd = textBoxStart + textBox->len(); - if (textBoxEnd <= start) - continue; - if (textBoxEnd > relEnd) - textBoxEnd = relEnd; - IntRect bounds = textBox->selectionRect((int) pt.x(), (int) pt.y(), - start, textBoxEnd); - bounds.intersect(clipBounds); - if (bounds.isEmpty()) - continue; - bool drawable = false; - for (int index = start; index < textBoxEnd; index++) - if ((drawable |= isNotSpace(chars[index])) != false) - break; - if (drawable && vis != HIDDEN) { - if (AddPartRect(bounds, x, y, result, focusBounds) == false) - return false; - } - if (textBoxEnd == relEnd) - break; - } while ((textBox = textBox->nextTextBox()) != NULL); - return true; -} - -bool CacheBuilder::ConstructTextRects(Text* node, int start, - Text* last, int end, int x, int y, IntRect* focusBounds, - const IntRect& clipBounds, WTF::Vector<IntRect>* result) -{ - result->clear(); - *focusBounds = IntRect(0, 0, 0, 0); - do { - RenderText* renderText = (RenderText*) node->renderer(); - int relEnd = node == last ? end : renderText->textLength(); - InlineTextBox *textBox = renderText->firstTextBox(); - if (textBox != NULL) { - do { - if ((int) textBox->end() >= start) - break; - } while ((textBox = textBox->nextTextBox()) != NULL); - if (textBox && ConstructTextRect(node, textBox, start, relEnd, - x, y, focusBounds, clipBounds, result) == false) - return false; - } - start = 0; - do { - if (node == last) - return true; - node = (Text*) node->traverseNextNode(); - ASSERT(node != NULL); - } while (node->isTextNode() == false || node->renderer() == NULL); - } while (true); -} - -} diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h deleted file mode 100644 index d48a045..0000000 --- a/WebKit/android/nav/CacheBuilder.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2006, 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 CacheBuilder_H -#define CacheBuilder_H - -#include "CachedDebug.h" -#include "CachedNodeType.h" -#include "IntRect.h" -#include "PlatformString.h" -#include "TextDirection.h" -#include <wtf/Forward.h> -#include <wtf/Vector.h> - -#define NAVIGATION_MAX_PHONE_LENGTH 14 - -using namespace WebCore; - -namespace WebCore { - -class ColumnInfo; -class Document; -class Frame; -class HTMLAreaElement; -class InlineTextBox; -class LayerAndroid; -class Node; -class PlatformGraphicsContext; -class RenderBlock; -class RenderFlow; -class RenderLayer; -class RenderObject; -class Text; - -} - -namespace android { - -class CachedFrame; -class CachedNode; -class CachedRoot; - -class CacheBuilder { -public: - enum Direction { - UNINITIALIZED = -1, - LEFT, - RIGHT, - UP, - DOWN, - DIRECTION_COUNT, - UP_DOWN = UP & DOWN, // mask and result - RIGHT_DOWN = RIGHT & DOWN, // mask and result - }; - enum FoundState { - FOUND_NONE, - FOUND_PARTIAL, - FOUND_COMPLETE - }; - CacheBuilder(); - void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODE_BITS; } - void buildCache(CachedRoot* root); - static bool ConstructPartRects(Node* node, const IntRect& bounds, - IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result, - int* imageCountPtr); - Node* currentFocus() const; - void disallowAddressDetection() { mAllowableTypes = (CachedNodeBits) ( - mAllowableTypes & ~ADDRESS_CACHEDNODE_BIT); } - void disallowEmailDetection() { mAllowableTypes = (CachedNodeBits) ( - mAllowableTypes & ~EMAIL_CACHEDNODE_BIT); } - void disallowPhoneDetection() { mAllowableTypes = (CachedNodeBits) ( - mAllowableTypes & ~PHONE_CACHEDNODE_BIT); } - static FoundState FindAddress(const UChar* , unsigned length, int* start, - int* end, bool caseInsensitive); - static IntRect getAreaRect(const HTMLAreaElement* area); - static void GetGlobalOffset(Frame* , int* x, int * y); - static void GetGlobalOffset(Node* , int* x, int * y); - bool pictureSetDisabled() { return mPictureSetDisabled; } - static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr); -private: - enum AddressProgress { - NO_ADDRESS, - SKIP_TO_SPACE, - HOUSE_NUMBER, - NUMBER_TRAILING_SPACE, - ADDRESS_LINE, - STATE_NAME, - SECOND_HALF, - ZIP_CODE, - PLUS_4, - FIND_STREET - }; - struct NodeWalk { - NodeWalk() { reset(); } - int mStart; - int mEnd; - Node* mFinalNode; - InlineTextBox* mLastInline; - bool mMore; - void reset() { mMore = false; } - }; - struct BoundsPart { - IntRect mRect; - int mStart; - int mEnd; - }; - struct Bounds { - typedef bool (*FindText)(BoundsPart* result, InlineTextBox* , const String& match); - IntRect mNodeBounds; - BoundsPart mPart; - WTF::Vector<BoundsPart> mParts; - char mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; - int mPartIndex; - Node* mNode; - Node* mFinalNode; - void reset() { mNode = NULL; } - }; - struct FindState { - int mStartResult; - int mEndResult; - const UChar* mCurrentStart; - const UChar* mEnd; - AddressProgress mProgress; - int mNumberCount; - int mLetterCount; - unsigned mWordCount; - int mLineCount; - const UChar* mFirstLower; - const UChar* mZipStart; - const UChar* mBases[16]; // FIXME: random guess, maybe too small, maybe too big - const UChar* mWords[16]; - const UChar* mEnds[16]; - const UChar* mStarts[16]; // text is not necessarily contiguous - const char* mStates; - int mEndWord; - int mStateWord; - int mZipHint; - int mSectionLength; - unsigned mNumberWords; // must contain as many bits as mWords contains elements - char* mPattern; - UChar mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; - UChar* mStorePtr; - UChar mBackOne; - UChar mBackTwo; - UChar mCurrent; - bool mUnparsed; - bool mZipDelimiter; - bool mOpenParen; - bool mInitialized; - bool mContinuationNode; - bool mCaseInsensitive; - void shiftWords(int shift) { - memmove(mBases, &mBases[shift], (sizeof(mBases) / - sizeof(mBases[0]) - shift) * sizeof(mBases[0])); - memmove(mWords, &mWords[shift], (sizeof(mWords) / - sizeof(mWords[0]) - shift) * sizeof(mWords[0])); - memmove(mEnds, &mEnds[shift], (sizeof(mEnds) / - sizeof(mEnds[0]) - shift) * sizeof(mEnds[0])); - memmove(mStarts, &mStarts[shift], (sizeof(mStarts) / - sizeof(mStarts[0]) - shift) * sizeof(mStarts[0])); - } - void newWord(const UChar* baseChars, const UChar* chars) { - mBases[mWordCount] = baseChars; - mWords[mWordCount] = chars; - mEnds[mWordCount] = mEnd; - mStarts[mWordCount] = mCurrentStart; - } - }; - struct Tracker { - Node* mLastChild; - }; - struct ClipColumnTracker : Tracker { - Node* mNode; - IntRect mBounds; - ColumnInfo* mColumnInfo; - int mColumnGap; - TextDirection mDirection; - bool mHasClip; - }; - struct LayerTracker : Tracker { - LayerAndroid* mLayer; - RenderLayer* mRenderLayer; - IntRect mBounds; - IntPoint mScroll; - ~LayerTracker(); - }; - struct TabIndexTracker : Tracker { - int mTabIndex; - }; - struct FocusTracker : TabIndexTracker { - int mCachedNodeIndex; - bool mSomeParentTakesFocus; - }; - void adjustForColumns(const ClipColumnTracker& track, - CachedNode* node, IntRect* bounds, RenderBlock*); - static bool AddPartRect(IntRect& bounds, int x, int y, - WTF::Vector<IntRect>* result, IntRect* focusBounds); - static bool AnyIsClick(Node* node); - static bool AnyChildIsClick(Node* node); - static bool NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length); - void BuildFrame(Frame* root, Frame* frame, - CachedRoot* cachedRoot, CachedFrame* cachedFrame); - bool CleanUpContainedNodes(CachedRoot* cachedRoot, CachedFrame* cachedFrame, - const FocusTracker* last, int lastChildIndex); - static bool ConstructTextRect(Text* textNode, - InlineTextBox* textBox, int start, int relEnd, int x, int y, - IntRect* focusBounds, const IntRect& clip, WTF::Vector<IntRect>* result); - static bool ConstructTextRects(Text* node, int start, - Text* last, int end, int x, int y, IntRect* focusBounds, - const IntRect& clip, WTF::Vector<IntRect>* result); - static FoundState FindPartialAddress(const UChar* , const UChar* , unsigned length, FindState* ); - static FoundState FindPartialEMail(const UChar* , unsigned length, FindState* ); - static FoundState FindPartialNumber(const UChar* , unsigned length, FindState* ); - static FoundState FindPhoneNumber(const UChar* chars, unsigned length, int* start, int* end); - static void FindReset(FindState* ); - static void FindResetNumber(FindState* ); - static Frame* FrameAnd(CacheBuilder* focusNav); - static Frame* FrameAnd(const CacheBuilder* focusNav); - static CacheBuilder* Builder(Frame* ); - static Frame* HasFrame(Node* ); - static bool HasOverOrOut(Node* ); - static bool HasTriggerEvent(Node* ); - static bool IsDomainChar(UChar ch); - bool isFocusableText(NodeWalk* , bool oldMore, Node* , CachedNodeType* type, - String* exported) const; //returns true if it is focusable - static bool IsMailboxChar(UChar ch); - static bool IsRealNode(Frame* , Node* ); - int overlap(int left, int right); // returns distance scale factor as 16.16 scalar - bool setData(CachedFrame* ); -#if USE(ACCELERATED_COMPOSITING) - void TrackLayer(WTF::Vector<LayerTracker>& layerTracker, - RenderObject* nodeRenderer, Node* lastChild, int offsetX, int offsetY); -#endif - Node* tryFocus(Direction direction); - Node* trySegment(Direction direction, int mainStart, int mainEnd); - CachedNodeBits mAllowableTypes; - bool mPictureSetDisabled; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - void frameName(char*& namePtr, const char* max) const; - void init(char* buffer, size_t size); - static int ParentIndex(Node* node, int count, Node* parent); - void print() { frames(); } - void print(const char* name); - void wideString(const String& str); -private: - void attr(const AtomicString& name, const AtomicString& value); - void comma(const char* str); - void flush(); - Frame* frameAnd() const; - void frames(); - void groups(); - bool isFocusable(Node* node); - void localName(Node* node); - void newLine(int indent = 0); - void print(const char* name, unsigned len); - void setIndent(int ); - void uChar(const UChar* name, unsigned len, bool hex); - void validateFrame(); - void validateStringData(); - void wideString(const UChar* chars, int length, bool hex); - char* mBuffer; - size_t mBufferSize; - int mIndex; - const char* mPrefix; - int mMinPrefix; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedColor.cpp b/WebKit/android/nav/CachedColor.cpp deleted file mode 100644 index c610022..0000000 --- a/WebKit/android/nav/CachedColor.cpp +++ /dev/null @@ -1,58 +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. - */ - -#include "CachedPrefix.h" -#include "CachedColor.h" - -namespace android { - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_COLOR(field) \ - DUMP_NAV_LOGD("// SkColor " #field "=0x%08x;\n", b->field) - -CachedColor* CachedColor::Debug::base() const { - CachedColor* nav = (CachedColor*) ((char*) this - OFFSETOF(CachedColor, mDebug)); - return nav; -} - -void CachedColor::Debug::print() const -{ - CachedColor* b = base(); - DEBUG_PRINT_COLOR(mFillColor); - DUMP_NAV_LOGD("// int mInnerWidth=%d;\n", b->mInnerWidth); - DUMP_NAV_LOGD("// int mOuterWidth=%d;\n", b->mOuterWidth); - DUMP_NAV_LOGD("// int mOutset=%d;\n", b->mOutset); - DEBUG_PRINT_COLOR(mPressedInnerColor); - DEBUG_PRINT_COLOR(mPressedOuterColor); - DUMP_NAV_LOGD("// int mRadius=%d;\n", b->mRadius); - DEBUG_PRINT_COLOR(mSelectedInnerColor); - DEBUG_PRINT_COLOR(mSelectedOuterColor); -} - -#endif - -} - diff --git a/WebKit/android/nav/CachedColor.h b/WebKit/android/nav/CachedColor.h deleted file mode 100644 index 4b39810..0000000 --- a/WebKit/android/nav/CachedColor.h +++ /dev/null @@ -1,87 +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 CachedColor_H -#define CachedColor_H - -#include "CachedDebug.h" -#include "Color.h" -#include "Length.h" -#include "SkColor.h" - -using namespace WebCore; - -namespace android { - -class CachedColor { -public: - CachedColor() { - // Initiaized to 0 in its array, so nothing to do in the - // constructor - } - bool operator==(const CachedColor& o) const { - return memcmp(&o, this, sizeof(this)) == 0; } - SkColor fillColor() const { return mFillColor; } - void init(); - int innerWidth() const { return mInnerWidth; } - int outerWidth() const { return mOuterWidth; } - int outset() const { return mOutset; } - SkColor pressedInnerColor() const { return mPressedInnerColor; } - SkColor pressedOuterColor() const { return mPressedOuterColor; } - int radius() const { return mRadius; } - SkColor selectedInnerColor() const { return mSelectedInnerColor; } - SkColor selectedOuterColor() const { return mSelectedOuterColor; } - void setFillColor(const Color& c) { mFillColor = c.rgb(); } - void setInnerWidth(Length l) { mInnerWidth = l.value(); } - void setOuterWidth(Length l) { mOuterWidth = l.value(); } - void setOutset(Length l) { mOutset = l.value(); } - void setPressedInnerColor(const Color& c) { mPressedInnerColor = c.rgb(); } - void setPressedOuterColor(const Color& c) { mPressedOuterColor = c.rgb(); } - void setRadius(Length l) { mRadius = l.value(); } - void setSelectedInnerColor(const Color& c) { mSelectedInnerColor = c.rgb(); } - void setSelectedOuterColor(const Color& c) { mSelectedOuterColor = c.rgb(); } -private: - SkColor mFillColor; - int mInnerWidth; - int mOuterWidth; - int mOutset; - SkColor mPressedInnerColor; - SkColor mPressedOuterColor; - int mRadius; - SkColor mSelectedInnerColor; - SkColor mSelectedOuterColor; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedColor* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedDebug.h b/WebKit/android/nav/CachedDebug.h deleted file mode 100644 index 3d9e012..0000000 --- a/WebKit/android/nav/CachedDebug.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007, 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 CachedDebug_H -#define CachedDebug_H - -#define DUMP_NAV_CACHE 0 -#define DEBUG_NAV_UI 0 -#define DEBUG_NAV_UI_VERBOSE 0 - -#if DEBUG_NAV_UI -#define DBG_NAV_LOG(message) LOGD("%s %s", __FUNCTION__, message) -#define DBG_NAV_LOGD(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#define DEBUG_NAV_UI_LOGD(...) LOGD(__VA_ARGS__) -#else -#define DBG_NAV_LOG(message) ((void)0) -#define DBG_NAV_LOGD(format, ...) ((void)0) -#define DEBUG_NAV_UI_LOGD(...) ((void)0) -#endif - -#if DEBUG_NAV_UI_VERBOSE -#define DBG_NAV_LOGV(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#else -#define DBG_NAV_LOGV(format, ...) ((void)0) -#endif - -#if DUMP_NAV_CACHE != 0 && !defined DUMP_NAV_CACHE_USING_PRINTF && defined NDEBUG -#define DUMP_NAV_CACHE_USING_PRINTF -#endif - -#if DUMP_NAV_CACHE -#ifdef DUMP_NAV_CACHE_USING_PRINTF -#include <stdio.h> -extern FILE* gNavCacheLogFile; -#define NAV_CACHE_LOG_FILE "/data/data/com.android.browser/navlog" -#define DUMP_NAV_LOGD(...) do { if (gNavCacheLogFile) \ - fprintf(gNavCacheLogFile, __VA_ARGS__); else LOGD(__VA_ARGS__); } while (false) -#define DUMP_NAV_LOGX(format, ...) do { if (gNavCacheLogFile) \ - fprintf(gNavCacheLogFile, format, __VA_ARGS__); \ - else LOGD("%s " format, __FUNCTION__, __VA_ARGS__); } while (false) -#else -#define DUMP_NAV_LOGD(...) LOGD(__VA_ARGS__) -#define DUMP_NAV_LOGX(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#endif -#else -#define DUMP_NAV_LOGD(...) ((void)0) -#define DUMP_NAV_LOGX(...) ((void)0) -#endif - -#endif diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp deleted file mode 100644 index b26e24b..0000000 --- a/WebKit/android/nav/CachedFrame.cpp +++ /dev/null @@ -1,1494 +0,0 @@ -/* - * Copyright 2007, 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 "CachedPrefix.h" -#include "CachedHistory.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "LayerAndroid.h" - -#include "CachedFrame.h" - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#define MIN_OVERLAP 3 // if rects overlap by 2 pixels or fewer, treat them as non-intersecting - -namespace android { - -WebCore::IntRect CachedFrame::adjustBounds(const CachedNode* node, - const WebCore::IntRect& rect) const -{ - DBG_NAV_LOGV("node=%p [%d] rect=(%d,%d,w=%d,h=%d) view=(%d,%d,w=%d,h=%d)" - " local=(%d,%d,w=%d,h=%d) root=(%d,%d,w=%d,h=%d)", - node, node->index(), rect.x(), rect.y(), rect.width(), rect.height(), - mViewBounds.x(), mViewBounds.y(), - mViewBounds.width(), mViewBounds.height(), - mLocalViewBounds.x(), mLocalViewBounds.y(), - mLocalViewBounds.width(), mLocalViewBounds.height(), - mRoot->mViewBounds.x(), mRoot->mViewBounds.y(), - mRoot->mViewBounds.width(), mRoot->mViewBounds.height()); -#if USE(ACCELERATED_COMPOSITING) - if (!mRoot) - return rect; - - const CachedLayer* cachedLayer = layer(node); - if (!cachedLayer) - return rect; - - const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer(); - const LayerAndroid* aLayer = cachedLayer->layer(rootLayer); - if (aLayer) - return cachedLayer->adjustBounds(rootLayer, rect); -#endif - return rect; -} - -bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result) -{ - int left, top, width, height; - if (direction & UP_DOWN) { - top = direction == UP ? bestRect.bottom() : prior.bottom(); - int bottom = direction == UP ? prior.y() : bestRect.y(); - height = bottom - top; - if (height < 0) - return false; - left = prior.x(); - int testLeft = bestRect.x(); - if (left > testLeft) - left = testLeft; - int right = prior.right(); - int testRight = bestRect.right(); - if (right < testRight) - right = testRight; - width = right - left; - } else { - left = direction == LEFT ? bestRect.right() : prior.right(); - int right = direction == LEFT ? prior.x() : bestRect.x(); - width = right - left; - if (width < 0) - return false; - top = prior.y(); - int testTop = bestRect.y(); - if (top > testTop) - top = testTop; - int bottom = prior.bottom(); - int testBottom = bestRect.bottom(); - if (bottom < testBottom) - bottom = testBottom; - height = bottom - top; - } - *result = WebCore::IntRect(left, top, width, height); - return true; -} - -bool CachedFrame::checkBetween(BestData* best, Direction direction) -{ - const WebCore::IntRect& bestRect = best->bounds(); - BestData test; - test.mDistance = INT_MAX; - test.mNode = NULL; - int index = direction; - int limit = index + DIRECTION_COUNT; - do { - WebCore::IntRect edges; - Direction check = (Direction) (index & DIRECTION_MASK); - if (CheckBetween(check, bestRect, - history()->priorBounds(), &edges) == false) - continue; - WebCore::IntRect clip = mRoot->scrolledBounds(); - clip.intersect(edges); - if (clip.isEmpty()) - continue; - findClosest(&test, direction, check, &clip); - if (test.mNode == NULL) - continue; - if (direction == check) - break; - } while (++index < limit); - if (test.mNode == NULL) - return false; - *best = test; - return true; -} - -bool CachedFrame::checkRings(const CachedNode* node, - const WebCore::IntRect& testBounds) const -{ - return mRoot->checkRings(picture(node), node, testBounds); -} - -bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const -{ - return history()->checkVisited(node, direction); -} - -void CachedFrame::clearCursor() -{ - DBG_NAV_LOGD("mCursorIndex=%d", mCursorIndex); - if (mCursorIndex < CURSOR_SET) - return; - CachedNode& cursor = mCachedNodes[mCursorIndex]; - cursor.clearCursor(this); - mCursorIndex = CURSOR_CLEARED; // initialized and explicitly cleared -} - -// returns 0 if test is preferable to best, 1 if not preferable, or -1 if unknown -int CachedFrame::compare(BestData& testData, const BestData& bestData) const -{ - if (testData.mNode->tabIndex() != bestData.mNode->tabIndex()) { - if (testData.mNode->tabIndex() < bestData.mNode->tabIndex() - || (mRoot->mCursor && mRoot->mCursor->tabIndex() < bestData.mNode->tabIndex())) { - testData.mNode->setCondition(CachedNode::HIGHER_TAB_INDEX); - return REJECT_TEST; - } - return TEST_IS_BEST; - } - // if the test minor axis line intersects the line segment between cursor - // center and best center, choose it - // give more weight to exact major axis alignment (rows, columns) - if (testData.mInNav != bestData.mInNav) { - if (bestData.mInNav) { - testData.mNode->setCondition(CachedNode::IN_CURSOR); - return REJECT_TEST; - } - return TEST_IS_BEST; - } - if (testData.mInNav) { - if (bestData.mMajorDelta < testData.mMajorDelta) { - testData.mNode->setCondition(CachedNode::CLOSER_IN_CURSOR); - return REJECT_TEST; - } - if (testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - } - if (testData.mMajorDelta < 0 && bestData.mMajorDelta >= 0) { - testData.mNode->setCondition(CachedNode::FURTHER); - return REJECT_TEST; - } - if ((testData.mMajorDelta ^ bestData.mMajorDelta) < 0) // one above, one below (or one left, one right) - return TEST_IS_BEST; - bool bestInWorking = bestData.inOrSubsumesWorking(); - bool testInWorking = testData.inOrSubsumesWorking(); - if (bestInWorking && testData.mWorkingOutside && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_WORKING); - return REJECT_TEST; - } - if (testInWorking && bestData.mWorkingOutside && bestData.mNavOutside) - return TEST_IS_BEST; - bool bestInNav = directionChange() && bestData.inOrSubsumesNav(); - bool testInNav = directionChange() && testData.inOrSubsumesNav(); - if (bestInWorking == false && testInWorking == false) { - if (bestInNav && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_UMBRA); - return REJECT_TEST; - } - if (testInNav && bestData.mNavOutside) - return TEST_IS_BEST; - } -#if 01 // hopefully butt test will remove need for this - if (testData.mCursorChild != bestData.mCursorChild) { - if (bestData.mCursorChild) { - testData.mNode->setCondition(CachedNode::IN_CURSOR_CHILDREN); - return REJECT_TEST; - } - return TEST_IS_BEST; - } -#endif - bool bestTestIn = (bestInWorking || bestInNav) && (testInWorking || testInNav); - bool testOverlap = bestTestIn || (testData.mWorkingOverlap != 0 && bestData.mWorkingOverlap == 0); - bool bestOverlap = bestTestIn || (testData.mWorkingOverlap == 0 && bestData.mWorkingOverlap != 0); -#if 01 // this isn't working? - if (testOverlap == bestOverlap) { - if (bestData.mMajorButt < 10 && testData.mMajorButt >= 40) { - testData.mNode->setCondition(CachedNode::BUTTED_UP); - return REJECT_TEST; - } - if (testData.mMajorButt < 10 && bestData.mMajorButt >= 40) - return TEST_IS_BEST; - } -#endif - if (bestOverlap && bestData.mMajorDelta < testData.mMajorDelta) { // choose closest major axis center - testData.mNode->setCondition(CachedNode::CLOSER); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - if (bestOverlap && bestData.mMajorDelta2 < testData.mMajorDelta2) { - testData.mNode->setCondition(CachedNode::CLOSER_TOP); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta2 < bestData.mMajorDelta2) - return TEST_IS_BEST; -#if 01 - if (bestOverlap && ((bestData.mSideDistance <= 0 && testData.mSideDistance > 0) || - abs(bestData.mSideDistance) < abs(testData.mSideDistance))) { - testData.mNode->setCondition(CachedNode::LEFTMOST); - return REJECT_TEST; - } - if (testOverlap && ((testData.mSideDistance <= 0 && bestData.mSideDistance > 0) || - abs(testData.mSideDistance) < abs(bestData.mSideDistance))) - return TEST_IS_BEST; -// fix me : the following ASSERT fires -- not sure if this case should be handled or not -// ASSERT(bestOverlap == false && testOverlap == false); -#endif - SkFixed testMultiplier = testData.mWorkingOverlap > testData.mNavOverlap ? - testData.mWorkingOverlap : testData.mNavOverlap; - SkFixed bestMultiplier = bestData.mWorkingOverlap > bestData.mNavOverlap ? - bestData.mWorkingOverlap : bestData.mNavOverlap; - int testDistance = testData.mDistance; - int bestDistance = bestData.mDistance; -// start here; - // this fails if they're off by 1 - // try once again to implement sliding scale so that off by 1 is nearly like zero, - // and off by a lot causes sideDistance to have little or no effect - // try elliptical distance -- lengthen side contribution - // these ASSERTs should not fire, but do fire on mail.google.com - // can't debug yet, won't reproduce - ASSERT(testDistance >= 0); - ASSERT(bestDistance >= 0); - testDistance += testDistance; // multiply by 2 - testDistance *= testDistance; - bestDistance += bestDistance; // multiply by 2 - bestDistance *= bestDistance; - int side = testData.mSideDistance; - int negative = side < 0 && bestData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - testDistance += side; - side = bestData.mSideDistance; - negative = side < 0 && testData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - bestDistance += side; - if (testMultiplier > (SK_Fixed1 >> 1) || bestMultiplier > (SK_Fixed1 >> 1)) { // considerable working overlap? - testDistance = SkFixedMul(testDistance, bestMultiplier); - bestDistance = SkFixedMul(bestDistance, testMultiplier); - } - if (bestDistance < testDistance) { - testData.mNode->setCondition(CachedNode::CLOSER_OVERLAP); - return REJECT_TEST; - } - if (testDistance < bestDistance) - return TEST_IS_BEST; -#if 0 - int distance = testData.mDistance + testData.mSideDistance; - int best = bestData.mDistance + bestData.mSideDistance; - if (distance > best) { - testData.mNode->setCondition(CachedNode::CLOSER_RAW_DISTANCE); - return REJECT_TEST; - } - else if (distance < best) - return TEST_IS_BEST; - best = bestData.mSideDistance; - if (testData.mSideDistance > best) { - testData.mNode->setCondition(CachedNode::SIDE_DISTANCE); - return REJECT_TEST; - } - if (testData.mSideDistance < best) - return TEST_IS_BEST; -#endif - if (testData.mPreferred < bestData.mPreferred) { - testData.mNode->setCondition(CachedNode::PREFERRED); - return REJECT_TEST; - } - if (testData.mPreferred > bestData.mPreferred) - return TEST_IS_BEST; - return UNDECIDED; -} - -const CachedNode* CachedFrame::currentCursor(const CachedFrame** framePtr) const -{ - if (framePtr) - *framePtr = this; - if (mCursorIndex < CURSOR_SET) - return NULL; - const CachedNode* result = &mCachedNodes[mCursorIndex]; - const CachedFrame* frame = hasFrame(result); - if (frame != NULL) - return frame->currentCursor(framePtr); - (const_cast<CachedNode*>(result))->fixUpCursorRects(this); - return result; -} - -const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const -{ - if (framePtr) - *framePtr = this; - if (mFocusIndex < 0) - return NULL; - const CachedNode* result = &mCachedNodes[mFocusIndex]; - const CachedFrame* frame = hasFrame(result); - if (frame != NULL) - return frame->currentFocus(framePtr); - return result; -} - -bool CachedFrame::directionChange() const -{ - return history()->directionChange(); -} - -#ifdef BROWSER_DEBUG -CachedNode* CachedFrame::find(WebCore::Node* node) // !!! probably debugging only -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - if (node == test->webCoreNode()) - return test; - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - CachedNode* result = frame->find(node); - if (result != NULL) - return result; - } - return NULL; -} -#endif - -const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, - int* best, bool* inside, const CachedNode** directHit, - const CachedFrame** directHitFramePtr, - const CachedFrame** framePtr, int* x, int* y, - bool checkForHiddenStart) const -{ - const CachedNode* result = NULL; - int rectWidth = rect.width(); - WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1), - rect.y() + (rect.height() >> 1)); - mRoot->setupScrolledBounds(); - for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { - if (test->disabled()) - continue; - size_t parts = test->navableRects(); - BestData testData; - testData.mNode = test; - testData.mFrame = this; - WebCore::IntRect bounds = test->bounds(this); - testData.setMouseBounds(bounds); - testData.setNodeBounds(bounds); - bool checkForHidden = checkForHiddenStart; - for (size_t part = 0; part < parts; part++) { - WebCore::IntRect testRect = test->ring(this, part); - if (testRect.intersects(rect)) { -#if DEBUG_NAV_UI - if (test->isInLayer()) { - DBG_NAV_LOGD("[%d] intersects=%s testRect=(%d,%d,w=%d,h=%d)" - " rect=(%d,%d,w=%d,h=%d)", test->index(), - testRect.intersects(rect) ? "true" : "false", - testRect.x(), testRect.y(), - testRect.width(), testRect.height(), - rect.x(), rect.y(), rect.width(), rect.height()); - } -#endif - if (checkForHidden && mRoot->maskIfHidden(&testData) == true) { - DBG_NAV_LOGD("hidden [%d]", test->index()); - break; - } - checkForHidden = false; - testRect.intersect(testData.mouseBounds()); - if (testRect.contains(center)) { - // We have a direct hit. - if (*directHit == NULL) { - DBG_NAV_LOGD("direct hit 1 [%d]", test->index()); - *directHit = test; - *directHitFramePtr = this; - IntRect r(center, IntSize(0, 0)); - *x = r.x(); - *y = r.y(); - } else { - DBG_NAV_LOGD("direct hit 2 [%d]", test->index()); - // We have hit another one before - const CachedNode* d = *directHit; - if (d->bounds(this).contains(testRect)) { - // This rectangle is inside the other one, so it is - // the best one. - *directHit = test; - *directHitFramePtr = this; - } - } - } - if (NULL != *directHit) { - // If we have a direct hit already, there is no need to - // calculate the distances, or check the other parts - break; - } - DBG_NAV_LOGD("indirect hit [%d]", test->index()); - WebCore::IntRect both = rect; - int smaller = testRect.width() < testRect.height() ? - testRect.width() : testRect.height(); - smaller -= rectWidth; - int inset = smaller < rectWidth ? smaller : rectWidth; - inset >>= 1; // inflate doubles the width decrease - if (inset > 1) - both.inflate(1 - inset); - both.intersect(testRect); - if (both.isEmpty()) - continue; - bool testInside = testRect.contains(center); - if (*inside && !testInside) - continue; - WebCore::IntPoint testCenter = WebCore::IntPoint(testRect.x() + - (testRect.width() >> 1), testRect.y() + (testRect.height() >> 1)); - int dx = testCenter.x() - center.x(); - int dy = testCenter.y() - center.y(); - int distance = dx * dx + dy * dy; - if ((!*inside && testInside) || *best >= distance) { - *best = distance; - *inside = testInside; - result = test; - *framePtr = this; - *x = both.x() + (both.width() >> 1); - *y = both.y() + (both.height() >> 1); - } - } - } - } - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedNode* frameResult = frame->findBestAt(rect, best, inside, - directHit, directHitFramePtr, framePtr, x, y, checkForHiddenStart); - if (NULL != frameResult) - result = frameResult; - } - if (NULL != *directHit) { - result = *directHit; - *framePtr = *directHitFramePtr; - } - return result; -} - -const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const -{ - if (mLocalViewBounds.contains(x, y) == false) - return NULL; - const CachedFrame* result = this; - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedFrame* frameResult = frame->findBestFrameAt(x, y); - if (NULL != frameResult) - result = frameResult; - } - return result; -} - -const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* x, int* y) const -{ - mRoot->setupScrolledBounds(); - for (const CachedFrame* frame = mCachedFrames.end() - 1; - frame != mCachedFrames.begin() - 1; frame--) { - const CachedNode* frameResult = frame->findBestHitAt(rect, - framePtr, x, y); - if (NULL != frameResult) - return frameResult; - } - for (const CachedNode* test = mCachedNodes.end() - 1; - test != mCachedNodes.begin() - 1; test--) { - if (test->disabled()) - continue; - WebCore::IntRect testRect = test->hitBounds(this); - if (testRect.intersects(rect) == false) - continue; - BestData testData; - testData.mNode = test; - testData.mFrame = this; - testData.setMouseBounds(testRect); - testData.setNodeBounds(testRect); - if (mRoot->maskIfHidden(&testData) == true) - continue; - DBG_NAV_LOGD("candidate %d rect=(%d,%d,r=%d,b=%d)" - " testRect=(%d,%d,r=%d,b=%d)", - test->index(), rect.x(), rect.y(), rect.right(), rect.bottom(), - testRect.x(), testRect.y(), testRect.right(), testRect.bottom()); - for (int i = 0; i < test->navableRects(); i++) { - WebCore::IntRect cursorRect = test->ring(this, i); - DBG_NAV_LOGD("candidate %d cursorRect=(%d,%d,r=%d,b=%d)", - i, cursorRect.x(), cursorRect.y(), cursorRect.right(), - cursorRect.bottom()); - if (cursorRect.intersects(rect)) { - WebCore::IntRect intersection(cursorRect); - intersection.intersect(rect); - *x = intersection.x() + (intersection.width() >> 1); - *y = intersection.y() + (intersection.height() >> 1); - *framePtr = this; - return test; - } - } - testRect.intersect(rect); - *x = testRect.x() + (testRect.width() >> 1); - *y = testRect.y() + (testRect.height() >> 1); - *framePtr = this; - return test; - } - return NULL; -} - -void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, - Direction direction, WebCore::IntRect* clip) const -{ - const CachedNode* test = mCachedNodes.begin(); - while ((test = test->traverseNextNode()) != NULL) { - const CachedFrame* child = hasFrame(test); - if (child != NULL) { - const CachedNode* childDoc = child->validDocument(); - if (childDoc == NULL) - continue; - child->findClosest(bestData, originalDirection, direction, clip); - } - if (test->noSecondChance()) - continue; - if (test->isNavable(this, *clip) == false) - continue; - if (checkVisited(test, originalDirection) == false) - continue; - size_t partMax = test->navableRects(); - for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->ring(this, part); - if (clip->intersects(testBounds) == false) - continue; - if (clip->contains(testBounds) == false) { - if (direction & UP_DOWN) { -// if (testBounds.x() > clip->x() || testBounds.right() < clip->right()) -// continue; - testBounds.setX(clip->x()); - testBounds.setWidth(clip->width()); - } else { -// if (testBounds.y() > clip->y() || testBounds.bottom() < clip->bottom()) -// continue; - testBounds.setY(clip->y()); - testBounds.setHeight(clip->height()); - } - if (clip->contains(testBounds) == false) - continue; - } - int distance; - // seems like distance for UP for instance needs to be 'test top closest to - // clip bottom' -- keep the old code but try this instead - switch (direction) { -#if 0 - case LEFT: distance = testBounds.x() - clip->x(); break; - case RIGHT: distance = clip->right() - testBounds.right(); break; - case UP: distance = testBounds.y() - clip->y(); break; - case DOWN: distance = clip->bottom() - testBounds.bottom(); break; -#else - case LEFT: distance = clip->right() - testBounds.x(); break; - case RIGHT: distance = testBounds.right() - clip->x(); break; - case UP: distance = clip->bottom() - testBounds.y(); break; - case DOWN: distance = testBounds.bottom() - clip->y(); break; -#endif - default: - distance = 0; ASSERT(0); - } - if (distance < bestData->mDistance) { - bestData->mNode = test; - bestData->mFrame = this; - bestData->mDistance = distance; - WebCore::IntRect rect = test->ring(this, part); - bestData->setMouseBounds(rect); - bestData->setNodeBounds(rect); - CachedHistory* cachedHistory = history(); - switch (direction) { - case LEFT: - bestData->setLeftDirection(cachedHistory); - break; - case RIGHT: - bestData->setRightDirection(cachedHistory); - break; - case UP: - bestData->setUpDirection(cachedHistory); - break; - case DOWN: - bestData->setDownDirection(cachedHistory); - break; - default: - ASSERT(0); - } - } - } - } -} - -void CachedFrame::finishInit() -{ - CachedNode* lastCached = lastNode(); - lastCached->setLast(); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->mParent = this; - child->finishInit(); - child++; - } - CachedFrame* frameParent; - if (mFocusIndex >= 0 && (frameParent = parent())) - frameParent->setFocusIndex(indexInParent()); -} - -const CachedNode* CachedFrame::frameDown(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameDown, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, DOWN) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setDownDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameDown(document(), test, &innerData); - if (checkVisited(innerData.mNode, DOWN)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, DOWN)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - // does the best contain something (or, is it contained by an area which is not the cursor?) - // if so, is the conainer/containee should have been chosen, but wasn't -- so there's a better choice - // in the doc list prior to this choice - // - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameLeft(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameLeft, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, LEFT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setLeftDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameLeft(document(), test, &innerData); - if (checkVisited(innerData.mNode, LEFT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, LEFT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, - BestData* bestData, BestData* originalData) const -{ - testData.mFrame = this; - testData.mNode = test; - test->clearCondition(); - if (test->disabled()) { - testData.mNode->setCondition(CachedNode::DISABLED); - return REJECT_TEST; - } - WebCore::IntRect bounds = test->bounds(this); - if (bounds.isEmpty()) { - testData.mNode->setCondition(CachedNode::NAVABLE); - return REJECT_TEST; - } - if (mRoot->scrolledBounds().intersects(bounds) == false) { - testData.mNode->setCondition(CachedNode::NAVABLE); - return REJECT_TEST; - } - if (mRoot->rootLayer() && !test->isInLayer() - && !mRoot->baseUncovered().intersects(bounds)) { - testData.mNode->setCondition(CachedNode::UNDER_LAYER); - return REJECT_TEST; - } -// if (isNavable(test, &testData.mNodeBounds, walk) == false) { -// testData.mNode->setCondition(CachedNode::NAVABLE); -// return REJECT_TEST; -// } -// - if (test == mRoot->mCursor) { - testData.mNode->setCondition(CachedNode::NOT_CURSOR_NODE); - return REJECT_TEST; - } -// if (test->bounds().contains(mRoot->mCursorBounds)) { -// testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); -// return REJECT_TEST; -// } - void* par = mRoot->mCursor ? mRoot->mCursor->parentGroup() : NULL; - testData.mCursorChild = par ? test->parentGroup() == par : false; - if (bestData->mNode == NULL) - return TEST_IS_BEST; - if (mRoot->mCursor && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { - int cursorParentIndex = mRoot->mCursor->parentIndex(); - if (cursorParentIndex >= 0) { - if (bestData->mNode->parentIndex() == cursorParentIndex) - return REJECT_TEST; - if (testData.mNode->parentIndex() == cursorParentIndex) - return TEST_IS_BEST; - } - } - if (testData.mNode->parent() == bestData->mNode) { - testData.mNode->setCondition(CachedNode::CHILD); - return REJECT_TEST; - } - if (testData.mNode == bestData->mNode->parent()) - return TEST_IS_BEST; - int testInBest = testData.isContainer(bestData); /* -1 pick best over test, 0 no containership, 1 pick test over best */ - if (testInBest == 1) { - if (test->isArea() || bestData->mNode->isArea()) - return UNDECIDED; - bestData->mNode = NULL; // force part tests to be ignored, yet still set up remaining test data for later comparisons - return TEST_IS_BEST; - } - if (testInBest == -1) { - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_BEST); - return REJECT_TEST; - } - if (originalData->mNode != NULL) { // test is best case - testInBest = testData.isContainer(originalData); - if (testInBest == -1) { /* test is inside best */ - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_ORIGINAL); - return REJECT_TEST; - } - } - return UNDECIDED; -} - -int CachedFrame::framePartCommon(BestData& testData, - const CachedNode* test, BestData* bestData) const -{ - if (mRoot->mCursor - && testData.bounds().contains(mRoot->mCursorBounds) - && !test->wantsKeyEvents()) { - testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - testData.setDistances(); - if (bestData->mNode != NULL) { - int compared = compare(testData, *bestData); - if (compared == 0 && test->isArea() == false && bestData->mNode->isArea() == false) - goto pickTest; - if (compared >= 0) - return compared; - } -pickTest: - return -1; // pick test -} - -const CachedNode* CachedFrame::frameRight(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameRight, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, RIGHT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setRightDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameRight(document(), test, &innerData); - if (checkVisited(innerData.mNode, RIGHT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, RIGHT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameUp(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameUp, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, UP) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setUpDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameUp(document(), test, &innerData); - if (checkVisited(innerData.mNode, UP)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, UP)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -CachedFrame* CachedFrame::hasFrame(const CachedNode* node) -{ - return node->isFrame() ? &mCachedFrames[node->childFrameIndex()] : NULL; -} - -void CachedFrame::hideCursor() -{ - DBG_NAV_LOGD("mCursorIndex=%d", mCursorIndex); - if (mCursorIndex < CURSOR_SET) - return; - CachedNode& cursor = mCachedNodes[mCursorIndex]; - cursor.hideCursor(this); -} - -CachedHistory* CachedFrame::history() const -{ - return mRoot->rootHistory(); -} - -void CachedFrame::init(const CachedRoot* root, int childFrameIndex, - WebCore::Frame* frame) -{ - mContents = WebCore::IntRect(0, 0, 0, 0); // fixed up for real in setData() - mLocalViewBounds = WebCore::IntRect(0, 0, 0, 0); - mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mRoot = root; - mCursorIndex = CURSOR_UNINITIALIZED; // not explicitly cleared - mFocusIndex = -1; - mFrame = frame; - mParent = NULL; // set up parents after stretchy arrays are set up - mIndexInParent = childFrameIndex; -} - -#if USE(ACCELERATED_COMPOSITING) -const CachedLayer* CachedFrame::layer(const CachedNode* node) const -{ - if (!node->isInLayer()) - return 0; - CachedLayer test; - test.setCachedNodeIndex(node->index()); - return std::lower_bound(mCachedLayers.begin(), mCachedLayers.end(), test); -} -#endif - -WebCore::IntRect CachedFrame::localBounds(const CachedNode* node, - const WebCore::IntRect& rect) const -{ - DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)", - node, node->index(), rect.x(), rect.y(), rect.width(), rect.height()); -#if USE(ACCELERATED_COMPOSITING) - return layer(node)->localBounds(mRoot->rootLayer(), rect); -#else - return rect; -#endif -} - -int CachedFrame::minWorkingHorizontal() const -{ - return history()->minWorkingHorizontal(); -} - -int CachedFrame::minWorkingVertical() const -{ - return history()->minWorkingVertical(); -} - -int CachedFrame::maxWorkingHorizontal() const -{ - return history()->maxWorkingHorizontal(); -} - -int CachedFrame::maxWorkingVertical() const -{ - return history()->maxWorkingVertical(); -} - -const CachedNode* CachedFrame::nextTextField(const CachedNode* start, - const CachedFrame** framePtr, bool* startFound) const -{ - const CachedNode* test = mCachedNodes.begin(); - while ((test = test->traverseNextNode())) { - const CachedFrame* frame = hasFrame(test); - if (frame) { - if (!frame->validDocument()) - continue; - const CachedNode* node - = frame->nextTextField(start, framePtr, startFound); - if (node) - return node; - } else if (test->isTextInput()) { - if (test == start) - *startFound = true; - else if (*startFound) { - if (framePtr) - *framePtr = this; - return test; - } - } - } - return 0; -} - -bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, - const CachedNode* test, BestData* bestData) const -{ - const CachedFrame* frame = hasFrame(test); - if (frame == NULL) - return false; // if it's not a frame, let the caller have another swing at it - const CachedNode* childDoc = frame->validDocument(); - if (childDoc == NULL) - return true; - (frame->*moveInDirection)(childDoc, NULL, bestData); - return true; -} - -const WebCore::IntRect& CachedFrame::_navBounds() const -{ - return history()->navBounds(); -} - -SkPicture* CachedFrame::picture(const CachedNode* node) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer()) - return layer(node)->picture(mRoot->rootLayer()); -#endif - return mRoot->mPicture; -} - -SkPicture* CachedFrame::picture(const CachedNode* node, int* xPtr, int* yPtr) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer()) { - const CachedLayer* cachedLayer = layer(node); - const LayerAndroid* rootLayer = mRoot->rootLayer(); - cachedLayer->toLocal(rootLayer, xPtr, yPtr); - return cachedLayer->picture(rootLayer); - } -#endif - return mRoot->mPicture; -} - -void CachedFrame::resetClippedOut() -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - { - if (test->clippedOut()) { - test->setDisabled(false); - test->setClippedOut(false); - } - } - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - frame->resetClippedOut(); - } -} - -void CachedFrame::resetLayers() -{ -#if USE(ACCELERATED_COMPOSITING) - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - frame->resetLayers(); - } -#endif -} - -bool CachedFrame::sameFrame(const CachedFrame* test) const -{ - ASSERT(test); - if (mIndexInParent != test->mIndexInParent) - return false; - if (mIndexInParent == -1) // index within parent's array of children, or -1 if root - return true; - return mParent->sameFrame(test->mParent); -} - -void CachedFrame::setData() -{ - if (this != mRoot) { - mViewBounds = mLocalViewBounds; - mViewBounds.intersect(mRoot->mViewBounds); - } - int x, y; - if (parent() == NULL) - x = y = 0; - else { - x = mLocalViewBounds.x(); - y = mLocalViewBounds.y(); - } - mContents.setX(x); - mContents.setY(y); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->setData(); - child++; - } -} - -bool CachedFrame::setCursor(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) -{ - if (NULL == node) { - const_cast<CachedRoot*>(mRoot)->setCursor(NULL, NULL); - return true; - } - if (mFrame != frame) { - for (CachedFrame* testF = mCachedFrames.begin(); testF != mCachedFrames.end(); - testF++) { - if (testF->setCursor(frame, node, x, y)) - return true; - } - DBG_NAV_LOGD("no frame frame=%p node=%p", frame, node); - return false; - } - bool first = true; - CachedNode const * const end = mCachedNodes.end(); - do { - for (CachedNode* test = mCachedNodes.begin(); test != end; test++) { - if (test->nodePointer() != node && first) - continue; - size_t partMax = test->navableRects(); - for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->ring(this, part); - if (testBounds.contains(x, y) == false) - continue; - if (test->isCursor()) { - DBG_NAV_LOGD("already set? test=%d frame=%p node=%p x=%d y=%d", - test->index(), frame, node, x, y); - return false; - } - const_cast<CachedRoot*>(mRoot)->setCursor(this, test); - return true; - } - } - DBG_NAV_LOGD("moved? frame=%p node=%p x=%d y=%d", frame, node, x, y); - } while ((first ^= true) == false); -failed: - DBG_NAV_LOGD("no match frame=%p node=%p", frame, node); - return false; -} - -const CachedNode* CachedFrame::validDocument() const -{ - const CachedNode* doc = document(); - return doc != NULL && mViewBounds.isEmpty() == false ? doc : NULL; -} - -bool CachedFrame::BestData::canBeReachedByAnotherDirection() -{ - if (mMajorButt > -MIN_OVERLAP) - return false; - mMajorButt = -mMajorButt; - return mNavOutside; -} - -int CachedFrame::BestData::isContainer(CachedFrame::BestData* other) -{ - int _x = x(); - int otherRight = other->right(); - if (_x >= otherRight) - return 0; // does not intersect - int _y = y(); - int otherBottom = other->bottom(); - if (_y >= otherBottom) - return 0; // does not intersect - int _right = right(); - int otherX = other->x(); - if (otherX >= _right) - return 0; // does not intersect - int _bottom = bottom(); - int otherY = other->y(); - if (otherY >= _bottom) - return 0; // does not intersect - int intoX = otherX - _x; - int intoY = otherY - _y; - int intoRight = otherRight - _right; - int intoBottom = otherBottom - _bottom; - bool contains = intoX >= 0 && intoY >= 0 && intoRight <= 0 && intoBottom <= 0; - if (contains && mNode->partRectsContains(other->mNode)) { -// if (mIsArea == false && hasMouseOver()) -// other->mMouseOver = mNode; - return mNode->isArea() ? 1 : -1; - } - bool containedBy = intoX <= 0 && intoY <= 0 && intoRight >= 0 && intoBottom >= 0; - if (containedBy && other->mNode->partRectsContains(mNode)) { -// if (other->mIsArea == false && other->hasMouseOver()) -// mMouseOver = other->mNode; - return other->mNode->isArea() ? -1 : 1; - } - return 0; -} - -// distance scale factor factor as a 16.16 scalar -SkFixed CachedFrame::BestData::Overlap(int span, int left, int right) -{ - unsigned result; - if (left > 0 && left < span && right > span) - result = (unsigned) left; - else if (right > 0 && right < span && left > span) - result = (unsigned) right; - else if (left > 0 && right > 0) - return SK_Fixed1; - else - return 0; - result = (result << 16) / (unsigned) span; // linear proportion, always less than fixed 1 - return (SkFixed) result; -// !!! experiment with weight -- enable if overlaps are preferred too much -// or reverse weighting if overlaps are preferred to little -// return (SkFixed) (result * result >> 16); // but fall off with square -} - -void CachedFrame::BestData::setDistances() -{ - mDistance = abs(mMajorDelta); - int sideDistance = mWorkingDelta; - if (mWorkingOverlap < SK_Fixed1) { - if (mPreferred > 0) - sideDistance = mWorkingDelta2; - } else if (sideDistance >= 0 && mWorkingDelta2 >=- 0) - sideDistance = 0; - else { - ASSERT(sideDistance <= 0 && mWorkingDelta2 <= 0); - if (sideDistance < mWorkingDelta2) - sideDistance = mWorkingDelta2; - } - // if overlap, smaller abs mWorkingDelta is better, smaller abs majorDelta is better - // if not overlap, positive mWorkingDelta is better - mSideDistance = sideDistance; -} - -bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.y() - navBounds.bottom(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - mMajorDelta2 = inNavTop; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.height() - - navBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move up or sideways - return REJECT_TEST; - } - int inNavBottom = navBounds.bottom() - mNodeBounds.bottom(); - setNavInclusion(testRight - navBounds.right(), navBounds.x() - testX); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, maxV - testX, testRight - minV); - setWorkingInclusion(testRight - maxV, minV - testX); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavBottom >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; - return false; -} - -bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.x() - mNodeBounds.right(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavRight = navBounds.right() - mNodeBounds.right(); - mMajorDelta2 = inNavRight; - mMajorDelta = mMajorDelta2 - ((navBounds.width() - - mNodeBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move right or sideways - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - setNavInclusion(navBounds.y() - testY, testBottom - navBounds.bottom()); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, maxH - testY, testBottom - minH); - setWorkingInclusion(minH - testY, testBottom - maxH); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavLeft >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.x() - navBounds.right(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - mMajorDelta2 = inNavLeft; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.width() - - navBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move left or sideways - return REJECT_TEST; - } - int inNavRight = navBounds.right() - mNodeBounds.right(); - setNavInclusion(testBottom - navBounds.bottom(), navBounds.y() - testY); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, testBottom - minH, maxH - testY); - setWorkingInclusion(testBottom - maxH, minH - testY); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavRight >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.y() - mNodeBounds.bottom(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavBottom = navBounds.bottom() - mNodeBounds.bottom(); - mMajorDelta2 = inNavBottom; - mMajorDelta = mMajorDelta2 - ((navBounds.height() - - mNodeBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move down or sideways - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - setNavInclusion(navBounds.x() - testX, testRight - navBounds.right()); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, testRight - minV, maxV - testX); - setWorkingInclusion(minV - testX, testRight - maxV); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavTop >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; /* both L/R in or out */ - return false; -} - -void CachedFrame::BestData::setNavInclusion(int left, int right) -{ - // if left and right <= 0, test node is completely in umbra of cursor - // prefer leftmost center - // if left and right > 0, test node subsumes cursor - mNavDelta = left; - mNavDelta2 = right; -} - -void CachedFrame::BestData::setNavOverlap(int span, int left, int right) -{ - // if left or right < 0, test node is not in umbra of cursor - mNavOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; - mNavOverlap = Overlap(span, left, right); // prefer smallest negative left -} - -void CachedFrame::BestData::setWorkingInclusion(int left, int right) -{ - mWorkingDelta = left; - mWorkingDelta2 = right; -} - -// distance scale factor factor as a 16.16 scalar -void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) -{ - // if left or right < 0, test node is not in umbra of cursor - mWorkingOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; - mWorkingOverlap = Overlap(span, left, right); - mPreferred = left <= 0 ? 0 : left; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_RECT(prefix, debugName, field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("%s DebugTestRect TEST%s_" #debugName "={%d, %d, %d, %d}; //" #field "\n", \ - prefix, mFrameName, r.x(), r.y(), r.width(), r.height()); } - -CachedFrame* CachedFrame::Debug::base() const { - CachedFrame* nav = (CachedFrame*) ((char*) this - OFFSETOF(CachedFrame, mDebug)); - return nav; -} - -void CachedFrame::Debug::print() const -{ - CachedFrame* b = base(); - DEBUG_PRINT_RECT("//", CONTENTS, mContents); - DEBUG_PRINT_RECT("", BOUNDS, mLocalViewBounds); - DEBUG_PRINT_RECT("//", VIEW, mViewBounds); - - DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size()); - for (CachedNode* node = b->mCachedNodes.begin(); - node != b->mCachedNodes.end(); node++) { - node->mDebug.print(); - const CachedInput* input = b->textInput(node); - if (input) - input->mDebug.print(); - DUMP_NAV_LOGD("\n"); - } - DUMP_NAV_LOGD("// }; // end of nodes\n"); -#if USE(ACCELERATED_COMPOSITING) - DUMP_NAV_LOGD("// CachedLayer mCachedLayers={ // count=%d\n", b->mCachedLayers.size()); - for (CachedLayer* layer = b->mCachedLayers.begin(); - layer != b->mCachedLayers.end(); layer++) { - layer->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of layers\n"); -#endif // USE(ACCELERATED_COMPOSITING) - DUMP_NAV_LOGD("// CachedColor mCachedColors={ // count=%d\n", b->mCachedColors.size()); - for (CachedColor* color = b->mCachedColors.begin(); - color != b->mCachedColors.end(); color++) { - color->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of colors\n"); - DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size()); - for (CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - { - child->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of child frames\n"); - DUMP_NAV_LOGD("// void* mFrame=(void*) %p;\n", b->mFrame); - DUMP_NAV_LOGD("// CachedFrame* mParent=%p;\n", b->mParent); - DUMP_NAV_LOGD("// int mIndexInParent=%d;\n", b->mIndexInParent); - DUMP_NAV_LOGD("// const CachedRoot* mRoot=%p;\n", b->mRoot); - DUMP_NAV_LOGD("// int mCursorIndex=%d;\n", b->mCursorIndex); - DUMP_NAV_LOGD("// int mFocusIndex=%d;\n", b->mFocusIndex); -} - -bool CachedFrame::Debug::validate(const CachedNode* node) const -{ - const CachedFrame* b = base(); - if (b->mCachedNodes.size() == 0) - return false; - if (node >= b->mCachedNodes.begin() && node < b->mCachedNodes.end()) - return true; - for (const CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - if (child->mDebug.validate(node)) - return true; - return false; -} - -#undef DEBUG_PRINT_RECT - -#endif - -} diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h deleted file mode 100644 index 039a0ee..0000000 --- a/WebKit/android/nav/CachedFrame.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2007, 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 CachedFrame_H -#define CachedFrame_H - -#include "CachedColor.h" -#include "CachedInput.h" -#include "CachedLayer.h" -#include "CachedNode.h" -#include "IntRect.h" -#include "SkFixed.h" -#include "wtf/Vector.h" - -class SkPicture; - -namespace WebCore { - class Frame; - class Node; -} - -namespace android { - -class CachedHistory; -class CachedRoot; - - // first node referenced by cache is always document -class CachedFrame { -public: - enum Direction { - UNINITIALIZED = -1, - LEFT, - RIGHT, - UP, - DOWN, - DIRECTION_COUNT, - DIRECTION_MASK = DIRECTION_COUNT - 1, - UP_DOWN = UP & DOWN, // mask and result - RIGHT_DOWN = RIGHT & DOWN, // mask and result - }; - enum Compare { - UNDECIDED = -1, - TEST_IS_BEST, - REJECT_TEST - }; - enum CursorInit { - CURSOR_UNINITIALIZED = -2, - CURSOR_CLEARED = -1, - CURSOR_SET = 0 - }; - CachedFrame() {} - void add(CachedColor& color) { mCachedColors.append(color); } - void add(CachedInput& input) { mCachedTextInputs.append(input); } -#if USE(ACCELERATED_COMPOSITING) - void add(CachedLayer& layer) { mCachedLayers.append(layer); } -#endif - void add(CachedNode& node) { mCachedNodes.append(node); } - void addFrame(CachedFrame& child) { mCachedFrames.append(child); } - WebCore::IntRect adjustBounds(const CachedNode* , - const WebCore::IntRect& ) const; - bool checkRings(const CachedNode* node, - const WebCore::IntRect& testBounds) const; - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - size_t childCount() { return mCachedFrames.size(); } - void clearCursor(); - const CachedColor& color(const CachedNode* node) const { - return mCachedColors[node->colorIndex()]; - } - const CachedNode* currentCursor() const { return currentCursor(NULL); } - const CachedNode* currentCursor(const CachedFrame** ) const; - const CachedNode* currentFocus() const { return currentFocus(NULL); } - const CachedNode* currentFocus(const CachedFrame** ) const; - bool directionChange() const; - const CachedNode* document() const { return mCachedNodes.begin(); } - bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc - const CachedNode* findBestAt(const WebCore::IntRect& , int* best, - bool* inside, const CachedNode** , const CachedFrame** directFrame, - const CachedFrame** resultFrame, int* x, - int* y, bool checkForHidden) const; - const CachedFrame* findBestFrameAt(int x, int y) const; - const CachedNode* findBestHitAt(const WebCore::IntRect& , - const CachedFrame** , int* x, int* y) const; - void finishInit(); - CachedFrame* firstChild() { return mCachedFrames.begin(); } - const CachedFrame* firstChild() const { return mCachedFrames.begin(); } - void* framePointer() const { return mFrame; } - CachedNode* getIndex(int index) { return index >= 0 ? - &mCachedNodes[index] : NULL; } - const CachedFrame* hasFrame(const CachedNode* node) const { - return const_cast<CachedFrame*>(this)->hasFrame(node); - } - CachedFrame* hasFrame(const CachedNode* node); - void hideCursor(); - int indexInParent() const { return mIndexInParent; } - void init(const CachedRoot* root, int index, WebCore::Frame* frame); - const CachedFrame* lastChild() const { return &mCachedFrames.last(); } -#if USE(ACCELERATED_COMPOSITING) - const CachedLayer* lastLayer() const { return &mCachedLayers.last(); } -#endif - CachedNode* lastNode() { return &mCachedNodes.last(); } - CachedFrame* lastChild() { return &mCachedFrames.last(); } -#if USE(ACCELERATED_COMPOSITING) - const CachedLayer* layer(const CachedNode* ) const; - size_t layerCount() const { return mCachedLayers.size(); } -#endif - WebCore::IntRect localBounds(const CachedNode* , - const WebCore::IntRect& ) const; - const CachedFrame* parent() const { return mParent; } - CachedFrame* parent() { return mParent; } - SkPicture* picture(const CachedNode* ) const; - SkPicture* picture(const CachedNode* , int* xPtr, int* yPtr) const; - void resetLayers(); - bool sameFrame(const CachedFrame* ) const; - void removeLast() { mCachedNodes.removeLast(); } - void resetClippedOut(); - void setContentsSize(int width, int height) { mContents.setWidth(width); - mContents.setHeight(height); } - bool setCursor(WebCore::Frame* , WebCore::Node* , int x, int y); - void setCursorIndex(int index) { mCursorIndex = index; } - void setData(); - bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y); - void setFocusIndex(int index) { mFocusIndex = index; } - void setIndexInParent(int index) { mIndexInParent = index; } - void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; } - int size() { return mCachedNodes.size(); } - const CachedInput* textInput(const CachedNode* node) const { - return node->isTextInput() ? &mCachedTextInputs[node->textInputIndex()] - : 0; - } - const CachedNode* validDocument() const; -protected: - const CachedNode* nextTextField(const CachedNode* start, - const CachedFrame** framePtr, bool* found) const; - struct BestData { - int mDistance; - int mSideDistance; - int mMajorDelta; // difference of center of object - // used only when leading and trailing edges contain another set of edges - int mMajorDelta2; // difference of leading edge (only used when center is same) - int mMajorButt; // checks for next cell butting up against or close to previous one - int mWorkingDelta; - int mWorkingDelta2; - int mNavDelta; - int mNavDelta2; - const CachedFrame* mFrame; - const CachedNode* mNode; - SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools - SkFixed mNavOverlap; - SkFixed mPreferred; - bool mCursorChild; - bool mInNav; - bool mNavOutside; - bool mWorkingOutside; - int bottom() const { return bounds().bottom(); } - const WebCore::IntRect& bounds() const { return mNodeBounds; } - bool canBeReachedByAnotherDirection(); - int height() const { return bounds().height(); } - bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; } - bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; } - int isContainer(BestData* ); - const WebCore::IntRect& mouseBounds() const { return mMouseBounds; } - static SkFixed Overlap(int span, int left, int right); - void reset() { mNode = NULL; } - int right() const { return bounds().right(); } - void setMouseBounds(const WebCore::IntRect& b) { mMouseBounds = b; } - void setNodeBounds(const WebCore::IntRect& b) { mNodeBounds = b; } - void setDistances(); - bool setDownDirection(const CachedHistory* ); - bool setLeftDirection(const CachedHistory* ); - bool setRightDirection(const CachedHistory* ); - bool setUpDirection(const CachedHistory* ); - void setNavInclusion(int left, int right); - void setNavOverlap(int span, int left, int right); - void setWorkingInclusion(int left, int right); - void setWorkingOverlap(int span, int left, int right); - int width() const { return bounds().width(); } - int x() const { return bounds().x(); } - int y() const { return bounds().y(); } -private: // since computing these is complicated, protect them so that the - // are only written by appropriate helpers - WebCore::IntRect mMouseBounds; - WebCore::IntRect mNodeBounds; - }; - typedef const CachedNode* (CachedFrame::*MoveInDirection)( - const CachedNode* test, const CachedNode* limit, BestData* ) const; - void adjustToTextColumn(int* delta) const; - static bool CheckBetween(Direction , const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result); - bool checkBetween(BestData* , Direction ); - int compare(BestData& testData, const BestData& bestData) const; - void findClosest(BestData* , Direction original, Direction test, - WebCore::IntRect* clip) const; - int frameNodeCommon(BestData& testData, const CachedNode* test, - BestData* bestData, BestData* originalData) const; - int framePartCommon(BestData& testData, const CachedNode* test, - BestData* ) const; - const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - int minWorkingHorizontal() const; - int minWorkingVertical() const; - int maxWorkingHorizontal() const; - int maxWorkingVertical() const; - bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* ) const; - const WebCore::IntRect& _navBounds() const; - WebCore::IntRect mContents; - WebCore::IntRect mLocalViewBounds; - WebCore::IntRect mViewBounds; - WTF::Vector<CachedColor> mCachedColors; - WTF::Vector<CachedNode> mCachedNodes; - WTF::Vector<CachedFrame> mCachedFrames; - WTF::Vector<CachedInput> mCachedTextInputs; -#if USE(ACCELERATED_COMPOSITING) - WTF::Vector<CachedLayer> mCachedLayers; -#endif - void* mFrame; // WebCore::Frame*, used only to compare pointers - CachedFrame* mParent; - int mCursorIndex; - int mFocusIndex; - int mIndexInParent; // index within parent's array of children, or -1 if root - const CachedRoot* mRoot; -private: - CachedHistory* history() const; -#ifdef BROWSER_DEBUG -public: - CachedNode* find(WebCore::Node* ); // !!! probably debugging only - int mDebugIndex; - int mDebugLoopbackOffset; -#endif -#if !defined NDEBUG || DUMP_NAV_CACHE -public: - class Debug { -public: - Debug() { -#if DUMP_NAV_CACHE - mFrameName[0] = '\0'; -#endif -#if !defined NDEBUG - mInUse = true; -#endif - } -#if !defined NDEBUG - ~Debug() { mInUse = false; } - bool mInUse; -#endif -#if DUMP_NAV_CACHE - CachedFrame* base() const; - void print() const; - bool validate(const CachedNode* ) const; - char mFrameName[256]; -#endif - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedHistory.cpp b/WebKit/android/nav/CachedHistory.cpp deleted file mode 100644 index 9066412..0000000 --- a/WebKit/android/nav/CachedHistory.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2007, 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 "CachedPrefix.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#if DUMP_NAV_CACHE -#include "CachedRoot.h" -#endif - -#include "CachedHistory.h" - -namespace android { - -CachedHistory::CachedHistory() { - memset(this, 0, sizeof(CachedHistory)); // this assume the class has no virtuals - mLastMove = CachedFrame::UNINITIALIZED; - mPriorMove = CachedFrame::UNINITIALIZED; -} - - -void CachedHistory::addToVisited(const CachedNode* node, CachedFrame::Direction direction) -{ - memmove(&mVisited[1], &mVisited[0], sizeof(mVisited) - sizeof(mVisited[0])); - mVisited[0].mNode = node; - mVisited[0].mDirection = direction; -} - -bool CachedHistory::checkVisited(const CachedNode* node, CachedFrame::Direction direction) const -{ - // if the direction is unchanged and we've already visited this node, don't visit it again - int index = 0; - while (index < NAVIGATION_VISIT_DEPTH - 1) { - if (direction != mVisited[index].mDirection) - break; - index++; // compare with last direction, previous to last node (where the arrow took us from) - if (node == mVisited[index].mNode) - return false; - } - return true; -} - -void CachedHistory::pinMaxMin(const WebCore::IntRect& viewBounds) -{ - if (mMinWorkingHorizontal < viewBounds.y() || - mMinWorkingHorizontal >= viewBounds.bottom()) - mMinWorkingHorizontal = viewBounds.y(); - if (mMaxWorkingHorizontal > viewBounds.bottom() || - mMaxWorkingHorizontal <= viewBounds.y()) - mMaxWorkingHorizontal = viewBounds.bottom(); - if (mMinWorkingVertical < viewBounds.x() || - mMinWorkingVertical >= viewBounds.right()) - mMinWorkingVertical = viewBounds.x(); - if (mMaxWorkingVertical > viewBounds.right() || - mMaxWorkingVertical <= viewBounds.x()) - mMaxWorkingVertical = viewBounds.right(); -} - -void CachedHistory::reset() -{ - memset(mVisited, 0, sizeof(mVisited)); -// mLastScroll = 0; - mPriorBounds = WebCore::IntRect(0, 0, 0, 0); - mDirectionChange = false; - mDidFirstLayout = false; - mPriorMove = mLastMove = CachedFrame::UNINITIALIZED; - mMinWorkingHorizontal = mMinWorkingVertical = INT_MIN; - mMaxWorkingHorizontal = mMaxWorkingVertical = INT_MAX; -} - -void CachedHistory::setWorking(CachedFrame::Direction newMove, - const CachedFrame* cursorFrame, const CachedNode* cursor, - const WebCore::IntRect& viewBounds) -{ - CachedFrame::Direction lastAxis = (CachedFrame::Direction) (mLastMove & ~CachedFrame::RIGHT_DOWN); // up, left or uninitialized - CachedFrame::Direction newAxis = (CachedFrame::Direction) (newMove & ~CachedFrame::RIGHT_DOWN); - bool change = newAxis != lastAxis; - mDirectionChange = change && mLastMove != CachedFrame::UNINITIALIZED; - if (cursor != NULL || mLastMove != CachedFrame::UNINITIALIZED) { - mPriorMove = mLastMove; - mLastMove = newMove; - } - const WebCore::IntRect* navBounds = &mNavBounds; - if (cursor != NULL) { - WebCore::IntRect cursorBounds = cursor->bounds(cursorFrame); - if (cursorBounds.isEmpty() == false) - mNavBounds = cursorBounds; - } - if (change) { // uninitialized or change in direction - if (lastAxis != CachedFrame::LEFT && navBounds->height() > 0) { - mMinWorkingHorizontal = navBounds->y(); - mMaxWorkingHorizontal = navBounds->bottom(); - } - if (lastAxis != CachedFrame::UP && navBounds->width() > 0) { - mMinWorkingVertical = navBounds->x(); - mMaxWorkingVertical = navBounds->right(); - } - } - pinMaxMin(viewBounds); -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedHistory* CachedHistory::Debug::base() const { - CachedHistory* nav = (CachedHistory*) ((char*) this - OFFSETOF(CachedHistory, mDebug)); - return nav; -} - -const char* CachedHistory::Debug::direction(CachedFrame::Direction d) const -{ - switch (d) { - case CachedFrame::LEFT: return "LEFT"; break; - case CachedFrame::RIGHT: return "RIGHT"; break; - case CachedFrame::UP: return "UP"; break; - case CachedFrame::DOWN: return "DOWN"; break; - default: return "UNINITIALIZED"; - } -} - -void CachedHistory::Debug::print(CachedRoot* root) const -{ - CachedHistory* b = base(); - DUMP_NAV_LOGD("// Visited mVisited[]={\n"); - for (size_t i = 0; i < NAVIGATION_VISIT_DEPTH; i++) { - const Visited& visit = b->mVisited[i]; - const CachedNode* node = visit.mNode; - int index = root != NULL && root->CachedFrame::mDebug.validate(node) ? - node->index() : -1; - DUMP_NAV_LOGD(" // { 0x%p (%d), %s },\n", node, index, direction(visit.mDirection)); - } - DUMP_NAV_LOGD("// };\n"); -// DUMP_NAV_LOGD("// int mLastScroll=%d;\n", b->mLastScroll); - DEBUG_PRINT_RECT(mMouseBounds); - DEBUG_PRINT_RECT(mNavBounds); - DEBUG_PRINT_RECT(mPriorBounds); - DEBUG_PRINT_BOOL(mDirectionChange); - DEBUG_PRINT_BOOL(mDidFirstLayout); - DUMP_NAV_LOGD("// CachedFrame::Direction mLastMove=%s, mPriorMove=%s;\n", - direction(b->mLastMove), direction(b->mPriorMove)); - int max = b->mMaxWorkingHorizontal; - DUMP_NAV_LOGD("static int TEST_MAX_H = %d;\n", max); - int min = b->mMinWorkingHorizontal; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_H = %d;\n", min); - max = b->mMaxWorkingVertical; - DUMP_NAV_LOGD("static int TEST_MAX_V = %d;\n", max); - min = b->mMinWorkingVertical; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_V = %d;\n", min); - DUMP_NAV_LOGD("\n"); -} - -#endif - -} diff --git a/WebKit/android/nav/CachedHistory.h b/WebKit/android/nav/CachedHistory.h deleted file mode 100644 index e8c1ad9..0000000 --- a/WebKit/android/nav/CachedHistory.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2007, 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 CachedHistory_H -#define CachedHistory_H - -#include "CachedFrame.h" - -#define NAVIGATION_VISIT_DEPTH 8 // the number of nodes last visited -- used to detect ping-ponging (number should be tuned) - -namespace android { - -class CachedRoot; - -// CachedHistory is maintained even if DOM is rebuilt by running script. -// It uses blind pointers for comparison in the previously visited nodes. -class CachedHistory { -public: - CachedHistory(); - void addToVisited(const CachedNode* , CachedFrame::Direction ); - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - bool didFirstLayout() const { return mDidFirstLayout; } - bool directionChange() const { return mDirectionChange; } - int minWorkingHorizontal() const { return mMinWorkingHorizontal; } - int minWorkingVertical() const { return mMinWorkingVertical; } - int maxWorkingHorizontal() const { return mMaxWorkingHorizontal; } - int maxWorkingVertical() const { return mMaxWorkingVertical; } - const WebCore::IntRect& navBounds() const { return mNavBounds; } - const WebCore::IntRect& priorBounds() const { return mPriorBounds; } - void setDidFirstLayout(bool did) { mDidFirstLayout = did; } - void setMouseBounds(const WebCore::IntRect& loc) { mMouseBounds = loc; } - void setNavBounds(const WebCore::IntRect& loc) { mNavBounds = loc; } - void setWorking(CachedFrame::Direction , const CachedFrame* , - const CachedNode* , const WebCore::IntRect& viewBounds); - void reset(); -private: - void pinMaxMin(const WebCore::IntRect& viewBounds); - struct Visited { - const CachedNode* mNode; - CachedFrame::Direction mDirection; - } mVisited[NAVIGATION_VISIT_DEPTH]; - WebCore::IntRect mMouseBounds; // constricted bounds, if cursor ring is partially visible - WebCore::IntRect mNavBounds; // cursor ring bounds plus optional keystroke movement - WebCore::IntRect mPriorBounds; // prior chosen cursor ring (for reversing narrowing) - bool mDirectionChange; - bool mDidFirstLayout; // set true when page is newly laid out - CachedFrame::Direction mLastMove; - CachedFrame::Direction mPriorMove; - int mMinWorkingHorizontal; - int mMaxWorkingHorizontal; - int mMinWorkingVertical; - int mMaxWorkingVertical; - friend class CachedRoot; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedHistory* base() const; - const char* direction(CachedFrame::Direction d) const; - void print(CachedRoot* ) const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp deleted file mode 100644 index a6a57ef..0000000 --- a/WebKit/android/nav/CachedInput.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "CachedPrefix.h" -#include "CachedInput.h" - -namespace android { - -void CachedInput::init() { - bzero(this, sizeof(CachedInput)); - mName = WTF::String(); -} - -void CachedInput::setTypeFromElement(WebCore::HTMLInputElement* element) -{ - ASSERT(element); - - if (element->isPasswordField()) - mType = PASSWORD; - else if (element->isSearchField()) - mType = SEARCH; - else if (element->isEmailField()) - mType = EMAIL; - else if (element->isNumberField()) - mType = NUMBER; - else if (element->isTelephoneField()) - mType = TELEPHONE; - else if (element->isURLField()) - mType = URL; - else - mType = NORMAL_TEXT_FIELD; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -CachedInput* CachedInput::Debug::base() const { - CachedInput* nav = (CachedInput*) ((char*) this - OFFSETOF(CachedInput, mDebug)); - return nav; -} - -static void printWebCoreString(const char* label, - const WTF::String& string) { - char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), label); - const UChar* ch = string.characters(); - while (ch && *ch && index < sizeof(scratch)) { - UChar c = *ch++; - if (c < ' ' || c >= 0x7f) c = ' '; - scratch[index++] = c; - } - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); -} - -void CachedInput::Debug::print() const -{ - CachedInput* b = base(); - DEBUG_PRINT_BOOL(mAutoComplete); - DUMP_NAV_LOGD("// void* mForm=%p;\n", b->mForm); - printWebCoreString("// char* mName=\"", b->mName); - DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength); - DUMP_NAV_LOGD("// int mPaddingLeft=%d;\n", b->mPaddingLeft); - DUMP_NAV_LOGD("// int mPaddingTop=%d;\n", b->mPaddingTop); - DUMP_NAV_LOGD("// int mPaddingRight=%d;\n", b->mPaddingRight); - DUMP_NAV_LOGD("// int mPaddingBottom=%d;\n", b->mPaddingBottom); - DUMP_NAV_LOGD("// float mTextSize=%f;\n", b->mTextSize); - DUMP_NAV_LOGD("// int mLineHeight=%d;\n", b->mLineHeight); - DUMP_NAV_LOGD("// Type mType=%d;\n", b->mType); - DEBUG_PRINT_BOOL(mIsRtlText); - DEBUG_PRINT_BOOL(mIsTextField); - DEBUG_PRINT_BOOL(mIsTextArea); -} - -#endif - -} diff --git a/WebKit/android/nav/CachedInput.h b/WebKit/android/nav/CachedInput.h deleted file mode 100644 index f7f9eea..0000000 --- a/WebKit/android/nav/CachedInput.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 CachedInput_H -#define CachedInput_H - -#include "CachedDebug.h" -#include "HTMLInputElement.h" -#include "PlatformString.h" - -namespace android { - -class CachedInput { -public: - CachedInput() { - // Initiaized to 0 in its array, so nothing to do in the - // constructor - } - - enum Type { - NONE = -1, - NORMAL_TEXT_FIELD = 0, - TEXT_AREA = 1, - PASSWORD = 2, - SEARCH = 3, - EMAIL = 4, - NUMBER = 5, - TELEPHONE = 6, - URL = 7 - }; - - bool autoComplete() const { return mAutoComplete; } - void* formPointer() const { return mForm; } - void init(); - void setTypeFromElement(WebCore::HTMLInputElement*); - Type getType() const { return mType; } - bool isRtlText() const { return mIsRtlText; } - bool isTextField() const { return mIsTextField; } - bool isTextArea() const { return mIsTextArea; } - int lineHeight() const { return mLineHeight; } - int maxLength() const { return mMaxLength; }; - const WTF::String& name() const { return mName; } - int paddingBottom() const { return mPaddingBottom; } - int paddingLeft() const { return mPaddingLeft; } - int paddingRight() const { return mPaddingRight; } - int paddingTop() const { return mPaddingTop; } - void setAutoComplete(bool autoComplete) { mAutoComplete = autoComplete; } - void setFormPointer(void* form) { mForm = form; } - void setIsRtlText(bool isRtlText) { mIsRtlText = isRtlText; } - void setIsTextField(bool isTextField) { mIsTextField = isTextField; } - void setIsTextArea(bool isTextArea) { mIsTextArea = isTextArea; } - void setLineHeight(int height) { mLineHeight = height; } - void setMaxLength(int maxLength) { mMaxLength = maxLength; } - void setName(const WTF::String& name) { mName = name; } - void setPaddingBottom(int bottom) { mPaddingBottom = bottom; } - void setPaddingLeft(int left) { mPaddingLeft = left; } - void setPaddingRight(int right) { mPaddingRight = right; } - void setPaddingTop(int top) { mPaddingTop = top; } - void setTextSize(float textSize) { mTextSize = textSize; } - float textSize() const { return mTextSize; } - -private: - - void* mForm; - int mLineHeight; - int mMaxLength; - WTF::String mName; - int mPaddingBottom; - int mPaddingLeft; - int mPaddingRight; - int mPaddingTop; - float mTextSize; - Type mType; - bool mAutoComplete : 1; - bool mIsRtlText : 1; - bool mIsTextField : 1; - bool mIsTextArea : 1; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedInput* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp deleted file mode 100644 index 299f2d1..0000000 --- a/WebKit/android/nav/CachedLayer.cpp +++ /dev/null @@ -1,221 +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. - */ - -#include "CachedPrefix.h" - -#include "CachedLayer.h" -#include "FloatRect.h" -#include "LayerAndroid.h" - -namespace android { - -#if USE(ACCELERATED_COMPOSITING) - -IntRect CachedLayer::adjustBounds(const LayerAndroid* root, - const IntRect& bounds) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) { - DBG_NAV_LOGD("no layer in root=%p uniqueId=%d", root, mUniqueId); -#if DUMP_NAV_CACHE - if (root) - mDebug.printRootLayerAndroid(root); -#endif - return bounds; - } - FloatRect temp = bounds; - // First, remove the original offset from the bounds. - temp.move(-mOffset.x(), -mOffset.y()); - - // Next, add in the new position of the layer (could be different due to a - // fixed position layer). - FloatPoint position = getGlobalPosition(aLayer); - temp.move(position.x(), position.y()); - - // Add in any layer translation. - // FIXME: Should use bounds() and apply the entire transformation matrix. - const FloatPoint& translation = aLayer->translation(); - temp.move(translation.x(), translation.y()); - - SkRect clip; - aLayer->bounds(&clip); - - // Do not try to traverse the parent chain if this is the root as the parent - // will not be a LayerAndroid. - if (aLayer != root) { - LayerAndroid* parent = static_cast<LayerAndroid*>(aLayer->getParent()); - while (parent) { - SkRect pClip; - parent->bounds(&pClip); - - // Move our position into our parent's coordinate space. - clip.offset(pClip.fLeft, pClip.fTop); - // Clip our visible rectangle to the parent. - clip.intersect(pClip); - - // Stop at the root. - if (parent == root) - break; - parent = static_cast<LayerAndroid*>(parent->getParent()); - } - } - - // Intersect the result with the visible clip. - temp.intersect(clip); - - IntRect result = enclosingIntRect(temp); - - DBG_NAV_LOGV("root=%p aLayer=%p [%d]" - " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g) pos=(%f,%f)" - " offset=(%d,%d)" - " result=(%d,%d,w=%d,h=%d)", - root, aLayer, aLayer->uniqueId(), - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - translation.x(), translation.y(), position.x(), position.y(), - mOffset.x(), mOffset.y(), - result.x(), result.y(), result.width(), result.height()); - return result; -} - -FloatPoint CachedLayer::getGlobalPosition(const LayerAndroid* aLayer) const -{ - SkPoint result = aLayer->getPosition(); - const SkLayer* parent = aLayer->getParent(); - while (parent) { - result += parent->getPosition(); - DBG_NAV_LOGV("result=(%g,%g) parent=%p [%d]", result.fX, result.fY, - parent, ((LayerAndroid*) parent)->uniqueId()); - parent = parent->getParent(); - } - return result; -} - -const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const -{ - if (!root) - return 0; - return root->findById(mUniqueId); -} - -// return bounds relative to the layer as recorded when walking the dom -IntRect CachedLayer::localBounds(const LayerAndroid* root, - const IntRect& bounds) const -{ - IntRect temp = bounds; - // Remove the original offset from the bounds. - temp.move(-mOffset.x(), -mOffset.y()); - -#if DEBUG_NAV_UI - const LayerAndroid* aLayer = layer(root); - DBG_NAV_LOGD("aLayer=%p [%d] bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)" - " result=(%d,%d,w=%d,h=%d)", - aLayer, aLayer ? aLayer->uniqueId() : 0, - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - mOffset.x(), mOffset.y(), - temp.x(), temp.y(), temp.width(), temp.height()); -#endif - - return temp; -} - -SkPicture* CachedLayer::picture(const LayerAndroid* root) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) - return 0; - DBG_NAV_LOGD("root=%p aLayer=%p [%d] picture=%p", - root, aLayer, aLayer->uniqueId(), aLayer->picture()); - return aLayer->picture(); -} - -void CachedLayer::toLocal(const LayerAndroid* root, int* xPtr, int* yPtr) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) - return; - DBG_NAV_LOGD("root=%p aLayer=%p [%d]", root, aLayer, aLayer->uniqueId()); - SkRect localBounds; - aLayer->bounds(&localBounds); - *xPtr -= localBounds.fLeft; - *yPtr -= localBounds.fTop; -} - -#if DUMP_NAV_CACHE - -CachedLayer* CachedLayer::Debug::base() const { - return (CachedLayer*) ((char*) this - OFFSETOF(CachedLayer, mDebug)); -} - -void CachedLayer::Debug::print() const -{ - CachedLayer* b = base(); - DUMP_NAV_LOGD(" // int mCachedNodeIndex=%d;\n", b->mCachedNodeIndex); - DUMP_NAV_LOGD(" // int mOffset=(%d, %d);\n", - b->mOffset.x(), b->mOffset.y()); - DUMP_NAV_LOGD(" // int mUniqueId=%p;\n", b->mUniqueId); - DUMP_NAV_LOGD("%s\n", ""); -} - -#endif - -#if DUMP_NAV_CACHE - -int CachedLayer::Debug::spaces; - -void CachedLayer::Debug::printLayerAndroid(const LayerAndroid* layer) -{ - ++spaces; - SkRect bounds; - layer->bounds(&bounds); - DBG_NAV_LOGD("%.*s layer=%p [%d] (%g,%g,%g,%g)" - " position=(%g,%g) translation=(%g,%g) anchor=(%g,%g)" - " matrix=(%g,%g) childMatrix=(%g,%g) picture=%p clipped=%s" - " scrollable=%s\n", - spaces, " ", layer, layer->uniqueId(), - bounds.fLeft, bounds.fTop, bounds.width(), bounds.height(), - layer->getPosition().fX, layer->getPosition().fY, - layer->translation().x(), layer->translation().y(), - layer->getAnchorPoint().fX, layer->getAnchorPoint().fY, - layer->getMatrix().getTranslateX(), layer->getMatrix().getTranslateY(), - layer->getChildrenMatrix().getTranslateX(), - layer->getChildrenMatrix().getTranslateY(), - layer->picture(), layer->m_haveClip ? "true" : "false", - layer->contentIsScrollable() ? "true" : "false"); - for (int i = 0; i < layer->countChildren(); i++) - printLayerAndroid(layer->getChild(i)); - --spaces; -} - -void CachedLayer::Debug::printRootLayerAndroid(const LayerAndroid* layer) -{ - spaces = 0; - printLayerAndroid(layer); -} -#endif - -#endif // USE(ACCELERATED_COMPOSITING) - -} - diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h deleted file mode 100644 index 3d963e0..0000000 --- a/WebKit/android/nav/CachedLayer.h +++ /dev/null @@ -1,86 +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 CachedLayer_H -#define CachedLayer_H - -#include "CachedDebug.h" -#include "IntRect.h" - -class SkPicture; - -namespace WebCore { - class FloatPoint; - class LayerAndroid; -} - -using namespace WebCore; - -namespace android { - -class CachedLayer { -public: -#if USE(ACCELERATED_COMPOSITING) - bool operator<(const CachedLayer& l) const { - return mCachedNodeIndex < l.mCachedNodeIndex; - } - // FIXME: adjustBounds should be renamed globalBounds or toGlobal - IntRect adjustBounds(const LayerAndroid* root, const IntRect& bounds) const; - int cachedNodeIndex() const { return mCachedNodeIndex; } - FloatPoint getGlobalPosition(const LayerAndroid* ) const; - const LayerAndroid* layer(const LayerAndroid* root) const; - IntRect localBounds(const LayerAndroid* root, const IntRect& bounds) const; - SkPicture* picture(const LayerAndroid* root) const; - void toLocal(const LayerAndroid* root, int* xPtr, int* yPtr) const; - void setCachedNodeIndex(int index) { mCachedNodeIndex = index; } - // Set the global position of the layer. This is recorded by the nav cache - // and corresponds to RenderLayer::absoluteBoundingBox() which is in - // document coordinates. This can be different from the global position of - // the layer if the layer is fixed positioned or scrollable. - void setOffset(const IntPoint& offset) { mOffset = offset; } - void setUniqueId(int uniqueId) { mUniqueId = uniqueId; } - int uniqueId() const { return mUniqueId; } -private: - int mCachedNodeIndex; - IntPoint mOffset; - int mUniqueId; - -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedLayer* base() const; - void print() const; - static void printLayerAndroid(const LayerAndroid* ); - static void printRootLayerAndroid(const LayerAndroid* ); - static int spaces; - } mDebug; -#endif -#endif // USE(ACCELERATED_COMPOSITING) -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp deleted file mode 100644 index e3ba34d..0000000 --- a/WebKit/android/nav/CachedNode.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 2007, 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 "CachedPrefix.h" -#include "android_graphics.h" -#include "CachedFrame.h" -#include "CachedHistory.h" -#include "Node.h" -#include "PlatformString.h" - -#include "CachedNode.h" - -namespace android { - -WebCore::IntRect CachedNode::bounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->adjustBounds(this, mBounds) : mBounds; -} - -void CachedNode::clearCursor(CachedFrame* parent) -{ - if (isFrame()) { - CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->clearCursor(); - } - mIsCursor = false; -} - -bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings) -{ - if (outer.contains(*inner)) - return true; -// DBG_NAV_LOGD("outer:{%d,%d,%d,%d} does not contain inner:{%d,%d,%d,%d}", -// outer.x(), outer.y(), outer.width(), outer.height(), -// inner->x(), inner->y(), inner->width(), inner->height()); - bool intersects = outer.intersects(*inner); - size_t size = intersects ? rings->size() : 0; - *inner = WebCore::IntRect(0, 0, 0, 0); - if (intersects) { - WebCore::IntRect * const start = rings->begin(); - WebCore::IntRect* ring = start + size - 1; - do { - ring->intersect(outer); - if (ring->isEmpty()) { - if ((size_t) (ring - start) != --size) - *ring = start[size]; - } else - inner->unite(*ring); - } while (ring-- != start); - } - rings->shrink(size); -// DBG_NAV_LOGD("size:%d", size); - return size != 0; -} - -bool CachedNode::clip(const WebCore::IntRect& bounds) -{ - return Clip(bounds, &mBounds, &mCursorRing); -} - - -void CachedNode::cursorRings(const CachedFrame* frame, - WTF::Vector<WebCore::IntRect>* rings) const -{ - rings->clear(); - for (unsigned index = 0; index < mCursorRing.size(); index++) - rings->append(ring(frame, index)); -} - -WebCore::IntRect CachedNode::cursorRingBounds(const CachedFrame* frame) const -{ - int partMax = mNavableRects; - ASSERT(partMax > 0); - WebCore::IntRect bounds = mCursorRing[0]; - for (int partIndex = 1; partIndex < partMax; partIndex++) - bounds.unite(mCursorRing[partIndex]); - bounds.inflate(CURSOR_RING_HIT_TEST_RADIUS); - return mIsInLayer ? frame->adjustBounds(this, bounds) : bounds; -} - -#define OVERLAP 3 - -void CachedNode::fixUpCursorRects(const CachedFrame* frame) -{ - if (mFixedUpCursorRects) - return; - mFixedUpCursorRects = true; - // if the hit-test rect doesn't intersect any other rect, use it - if (mHitBounds != mBounds && mHitBounds.contains(mBounds) && - frame->checkRings(this, mHitBounds)) { - DBG_NAV_LOGD("use mHitBounds (%d,%d,%d,%d)", mHitBounds.x(), - mHitBounds.y(), mHitBounds.width(), mHitBounds.height()); - mUseHitBounds = true; - return; - } - if (mNavableRects <= 1) - return; - // if there is more than 1 rect, and the bounds doesn't intersect - // any other cursor ring bounds, use it - IntRect sloppyBounds = mBounds; - sloppyBounds.inflate(2); // give it a couple of extra pixels - if (frame->checkRings(this, sloppyBounds)) { - DBG_NAV_LOGD("use mBounds (%d,%d,%d,%d)", mBounds.x(), - mBounds.y(), mBounds.width(), mBounds.height()); - mUseBounds = true; - return; - } -#if DEBUG_NAV_UI - { - WebCore::IntRect* boundsPtr = mCursorRing.begin() - 1; - const WebCore::IntRect* const boundsEnd = mCursorRing.begin() + mCursorRing.size(); - while (++boundsPtr < boundsEnd) - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mCursorRing.begin(), - boundsPtr->x(), boundsPtr->y(), boundsPtr->width(), boundsPtr->height()); - } -#endif - // q: need to know when rects are for drawing and hit-testing, but not mouse down calcs? - bool again; - do { - again = false; - size_t size = mCursorRing.size(); - WebCore::IntRect* unitBoundsPtr = mCursorRing.begin() - 1; - const WebCore::IntRect* const unitBoundsEnd = mCursorRing.begin() + size; - while (++unitBoundsPtr < unitBoundsEnd) { - // any other unitBounds to the left or right of this one? - int unitTop = unitBoundsPtr->y(); - int unitBottom = unitBoundsPtr->bottom(); - int unitLeft = unitBoundsPtr->x(); - int unitRight = unitBoundsPtr->right(); - WebCore::IntRect* testBoundsPtr = mCursorRing.begin() - 1; - while (++testBoundsPtr < unitBoundsEnd) { - if (unitBoundsPtr == testBoundsPtr) - continue; - int testTop = testBoundsPtr->y(); - int testBottom = testBoundsPtr->bottom(); - int testLeft = testBoundsPtr->x(); - int testRight = testBoundsPtr->right(); - int candidateTop = unitTop > testTop ? unitTop : testTop; - int candidateBottom = unitBottom < testBottom ? unitBottom : testBottom; - int candidateLeft = unitRight < testLeft ? unitRight : testRight; - int candidateRight = unitRight > testLeft ? unitLeft : testLeft; - bool leftRight = true; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) { - candidateTop = unitBottom < testTop ? unitBottom : testBottom; - candidateBottom = unitBottom > testTop ? unitTop : testTop; - candidateLeft = unitLeft > testLeft ? unitLeft : testLeft; - candidateRight = unitRight < testRight ? unitRight : testRight; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) - continue; - leftRight = false; - } - // construct candidate to add - WebCore::IntRect candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - // does a different unit bounds intersect the candidate? if so, don't add - WebCore::IntRect* checkBoundsPtr = mCursorRing.begin() - 1; - while (++checkBoundsPtr < unitBoundsEnd) { - if (checkBoundsPtr->intersects(candidate) == false) - continue; - if (leftRight) { - if (candidateTop >= checkBoundsPtr->y() && - candidateBottom > checkBoundsPtr->bottom()) - candidateTop = checkBoundsPtr->bottom(); - else if (candidateTop < checkBoundsPtr->y() && - candidateBottom <= checkBoundsPtr->bottom()) - candidateBottom = checkBoundsPtr->y(); - else - goto nextCheck; - } else { - if (candidateLeft >= checkBoundsPtr->x() && - candidateRight > checkBoundsPtr->right()) - candidateLeft = checkBoundsPtr->right(); - else if (candidateLeft < checkBoundsPtr->x() && - candidateRight <= checkBoundsPtr->right()) - candidateRight = checkBoundsPtr->x(); - else - goto nextCheck; - } - } - candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - ASSERT(candidate.isEmpty() == false); -#if DEBUG_NAV_UI - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mCursorRing.size(), - candidate.x(), candidate.y(), candidate.width(), candidate.height()); -#endif - mCursorRing.append(candidate); - again = true; - goto tryAgain; - nextCheck: - continue; - } - } -tryAgain: - ; - } while (again); -} - - -void CachedNode::hideCursor(CachedFrame* parent) -{ - if (isFrame()) { - CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->hideCursor(); - } - mIsHidden = true; -} - -WebCore::IntRect CachedNode::hitBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->adjustBounds(this, mHitBounds) : mHitBounds; -} - -void CachedNode::init(WebCore::Node* node) -{ - bzero(this, sizeof(CachedNode)); - mExport = WTF::String(); - mNode = node; - mParentIndex = mDataIndex = -1; - mType = android::NORMAL_CACHEDNODETYPE; -} - -bool CachedNode::isTextField(const CachedFrame* frame) const -{ - const CachedInput* input = frame->textInput(this); - return input ? input->isTextField() : false; -} - -void CachedNode::localCursorRings(const CachedFrame* frame, - WTF::Vector<WebCore::IntRect>* rings) const -{ - rings->clear(); - for (unsigned index = 0; index < mCursorRing.size(); index++) - rings->append(localRing(frame, index)); -} - -WebCore::IntRect CachedNode::localBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->localBounds(this, mBounds) : mBounds; -} - -WebCore::IntRect CachedNode::localHitBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->localBounds(this, mHitBounds) : mHitBounds; -} - -WebCore::IntRect CachedNode::localRing(const CachedFrame* frame, - size_t part) const -{ - const WebCore::IntRect& rect = mCursorRing.at(part); - return mIsInLayer ? frame->localBounds(this, rect) : rect; -} - -void CachedNode::move(int x, int y) -{ - mBounds.move(x, y); - // mHitTestBounds will be moved by caller - WebCore::IntRect* first = mCursorRing.begin(); - WebCore::IntRect* last = first + mCursorRing.size(); - --first; - while (++first != last) - first->move(x, y); -} - -bool CachedNode::partRectsContains(const CachedNode* other) const -{ - int outerIndex = 0; - int outerMax = mNavableRects; - int innerMax = other->mNavableRects; - do { - const WebCore::IntRect& outerBounds = mCursorRing[outerIndex]; - int innerIndex = 0; - do { - const WebCore::IntRect& innerBounds = other->mCursorRing[innerIndex]; - if (innerBounds.contains(outerBounds)) - return true; - } while (++innerIndex < innerMax); - } while (++outerIndex < outerMax); - return false; -} - -WebCore::IntRect CachedNode::ring(const CachedFrame* frame, size_t part) const -{ - const WebCore::IntRect& rect = mCursorRing.at(part); - return mIsInLayer ? frame->adjustBounds(this, rect) : rect; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedNode* CachedNode::Debug::base() const { - CachedNode* nav = (CachedNode*) ((char*) this - OFFSETOF(CachedNode, mDebug)); - return nav; -} - -const char* CachedNode::Debug::condition(Condition t) const -{ - switch (t) { - case NOT_REJECTED: return "NOT_REJECTED"; break; - case BUTTED_UP: return "BUTTED_UP"; break; - case CENTER_FURTHER: return "CENTER_FURTHER"; break; - case CLOSER: return "CLOSER"; break; - case CLOSER_IN_CURSOR: return "CLOSER_IN_CURSOR"; break; - case CLOSER_OVERLAP: return "CLOSER_OVERLAP"; break; - case CLOSER_TOP: return "CLOSER_TOP"; break; - case NAVABLE: return "NAVABLE"; break; - case FURTHER: return "FURTHER"; break; - case IN_UMBRA: return "IN_UMBRA"; break; - case IN_WORKING: return "IN_WORKING"; break; - case LEFTMOST: return "LEFTMOST"; break; - case OVERLAP_OR_EDGE_FURTHER: return "OVERLAP_OR_EDGE_FURTHER"; break; - case PREFERRED: return "PREFERRED"; break; - case ANCHOR_IN_ANCHOR: return "ANCHOR_IN_ANCHOR"; break; - case BEST_DIRECTION: return "BEST_DIRECTION"; break; - case CHILD: return "CHILD"; break; - case DISABLED: return "DISABLED"; break; - case HIGHER_TAB_INDEX: return "HIGHER_TAB_INDEX"; break; - case IN_CURSOR: return "IN_CURSOR"; break; - case IN_CURSOR_CHILDREN: return "IN_CURSOR_CHILDREN"; break; - case NOT_ENCLOSING_CURSOR: return "NOT_ENCLOSING_CURSOR"; break; - case NOT_CURSOR_NODE: return "NOT_CURSOR_NODE"; break; - case OUTSIDE_OF_BEST: return "OUTSIDE_OF_BEST"; break; - case OUTSIDE_OF_ORIGINAL: return "OUTSIDE_OF_ORIGINAL"; break; - default: return "???"; - } -} - -const char* CachedNode::Debug::type(android::CachedNodeType t) const -{ - switch (t) { - case NORMAL_CACHEDNODETYPE: return "NORMAL"; break; - case ADDRESS_CACHEDNODETYPE: return "ADDRESS"; break; - case EMAIL_CACHEDNODETYPE: return "EMAIL"; break; - case PHONE_CACHEDNODETYPE: return "PHONE"; break; - case ANCHOR_CACHEDNODETYPE: return "ANCHOR"; break; - case AREA_CACHEDNODETYPE: return "AREA"; break; - case FRAME_CACHEDNODETYPE: return "FRAME"; break; - case PLUGIN_CACHEDNODETYPE: return "PLUGIN"; break; - case TEXT_INPUT_CACHEDNODETYPE: return "INPUT"; break; - case SELECT_CACHEDNODETYPE: return "SELECT"; break; - case CONTENT_EDITABLE_CACHEDNODETYPE: return "CONTENT_EDITABLE"; break; - default: return "???"; - } -} - -void CachedNode::Debug::print() const -{ - CachedNode* b = base(); - char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), "// char* mExport=\""); - const UChar* ch = b->mExport.characters(); - while (ch && *ch && index < sizeof(scratch)) { - UChar c = *ch++; - if (c < ' ' || c >= 0x7f) c = ' '; - scratch[index++] = c; - } - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); - DEBUG_PRINT_RECT(mBounds); - DEBUG_PRINT_RECT(mHitBounds); - DEBUG_PRINT_RECT(mOriginalAbsoluteBounds); - const WTF::Vector<WebCore::IntRect>* rects = &b->mCursorRing; - size_t size = rects->size(); - DUMP_NAV_LOGD("// IntRect cursorRings={ // size=%d\n", size); - for (size_t i = 0; i < size; i++) { - const WebCore::IntRect& rect = (*rects)[i]; - DUMP_NAV_LOGD(" // {%d, %d, %d, %d}, // %d\n", rect.x(), rect.y(), - rect.width(), rect.height(), i); - } - DUMP_NAV_LOGD("// };\n"); - DUMP_NAV_LOGD("// void* mNode=%p; // (%d) \n", b->mNode, mNodeIndex); - DUMP_NAV_LOGD("// void* mParentGroup=%p; // (%d) \n", b->mParentGroup, mParentGroupIndex); - DUMP_NAV_LOGD("// int mDataIndex=%d;\n", b->mDataIndex); - DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); - DUMP_NAV_LOGD("// int mNavableRects=%d;\n", b->mNavableRects); - DUMP_NAV_LOGD("// int mParentIndex=%d;\n", b->mParentIndex); - DUMP_NAV_LOGD("// int mTabIndex=%d;\n", b->mTabIndex); - DUMP_NAV_LOGD("// int mColorIndex=%d;\n", b->mColorIndex); - DUMP_NAV_LOGD("// Condition mCondition=%s;\n", condition(b->mCondition)); - DUMP_NAV_LOGD("// Type mType=%s;\n", type(b->mType)); - DEBUG_PRINT_BOOL(mClippedOut); - DEBUG_PRINT_BOOL(mDisabled); - DEBUG_PRINT_BOOL(mFixedUpCursorRects); - DEBUG_PRINT_BOOL(mHasCursorRing); - DEBUG_PRINT_BOOL(mHasMouseOver); - DEBUG_PRINT_BOOL(mIsCursor); - DEBUG_PRINT_BOOL(mIsFocus); - DEBUG_PRINT_BOOL(mIsHidden); - DEBUG_PRINT_BOOL(mIsInLayer); - DEBUG_PRINT_BOOL(mIsParentAnchor); - DEBUG_PRINT_BOOL(mIsTransparent); - DEBUG_PRINT_BOOL(mIsUnclipped); - DEBUG_PRINT_BOOL(mLast); - DEBUG_PRINT_BOOL(mUseBounds); - DEBUG_PRINT_BOOL(mUseHitBounds); - DEBUG_PRINT_BOOL(mSingleImage); -} - -#endif - -} diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h deleted file mode 100644 index f9bcbed..0000000 --- a/WebKit/android/nav/CachedNode.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2007, 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 CachedNode_H -#define CachedNode_H - -#include "CachedDebug.h" -#include "CachedNodeType.h" -#include "IntRect.h" -#include "PlatformString.h" - -#include <wtf/Vector.h> -#include <wtf/text/AtomicString.h> - -class SkPicture; - -namespace WebCore { - class Node; -} - -namespace android { - -class CachedFrame; -class CachedRoot; - -class CachedNode { -public: -// Nodes are rejected because either they are spacially not the best (first set) -// or because they have the wrong DOM attribute (in focus, a focused child, etc) -// findClosest() gives only spacially rejected nodes a second chance - enum Condition { // if bigger than 32, increase bitfield size below - // rejections that get a second chance - NOT_REJECTED = 0, - SECOND_CHANCE_START = NOT_REJECTED, // must be first in list - BUTTED_UP, - CENTER_FURTHER, - CLOSER, - CLOSER_IN_CURSOR, - CLOSER_OVERLAP, - CLOSER_TOP, - NAVABLE, - FURTHER, - IN_UMBRA, - IN_WORKING, - LEFTMOST, - NOT_ENCLOSING_CURSOR, - OVERLAP_OR_EDGE_FURTHER, - PREFERRED, // better overlap measure - SECOND_CHANCE_END = PREFERRED, // must be last in list - // rejections that don't get a second chance - ANCHOR_IN_ANCHOR, - BEST_DIRECTION, // can be reached by another direction - CHILD, - DISABLED, - HIGHER_TAB_INDEX, - IN_CURSOR, - IN_CURSOR_CHILDREN, - NOT_CURSOR_NODE, - OUTSIDE_OF_BEST, // containership - OUTSIDE_OF_ORIGINAL, // containership - UNDER_LAYER, - CONDITION_SIZE // FIXME: test that CONDITION_SIZE fits in mCondition - }; - CachedNode() { - // The node is initiaized to 0 in its array, so nothing to do in the - // constructor - } - - WebCore::IntRect bounds(const CachedFrame* ) const; - int childFrameIndex() const { return isFrame() ? mDataIndex : -1; } - void clearCondition() const { mCondition = NOT_REJECTED; } - void clearCursor(CachedFrame* ); - static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings); - bool clip(const WebCore::IntRect& ); - bool clippedOut() { return mClippedOut; } - int colorIndex() const { return mColorIndex; } - WebCore::IntRect cursorRingBounds(const CachedFrame* ) const; - void cursorRings(const CachedFrame* , WTF::Vector<WebCore::IntRect>* ) const; - bool disabled() const { return mDisabled; } - const CachedNode* document() const { return &this[-mIndex]; } - void fixUpCursorRects(const CachedFrame* frame); - const WTF::String& getExport() const { return mExport; } - bool hasCursorRing() const { return mHasCursorRing; } - bool hasMouseOver() const { return mHasMouseOver; } - void hideCursor(CachedFrame* ); - WebCore::IntRect hitBounds(const CachedFrame* ) const; - int index() const { return mIndex; } - void init(WebCore::Node* node); - bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; } - bool isContentEditable() const { return mType == CONTENT_EDITABLE_CACHEDNODETYPE; } - bool isCursor() const { return mIsCursor; } - bool isArea() const { return mType == AREA_CACHEDNODETYPE; } - bool isFocus() const { return mIsFocus; } - bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; } - bool isHidden() const { return mIsHidden; } - bool isInLayer() const { return mIsInLayer; } - bool isNavable(const CachedFrame* frame, const WebCore::IntRect& clip) const { - return clip.intersects(bounds(frame)); - } - bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; } - bool isSelect() const { return mType == SELECT_CACHEDNODETYPE; } - bool isSyntheticLink() const { - return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE; - } - bool isTextField(const CachedFrame*) const; - bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; } - bool isTransparent() const { return mIsTransparent; } - bool isUnclipped() const { return mIsUnclipped; } - // localXXX functions are used only for drawing cursor rings - WebCore::IntRect localBounds(const CachedFrame* ) const; - void localCursorRings(const CachedFrame* , - WTF::Vector<WebCore::IntRect>* ) const; - WebCore::IntRect localHitBounds(const CachedFrame* ) const; - WebCore::IntRect localRing(const CachedFrame* , size_t part) const; - void move(int x, int y); - int navableRects() const { return mNavableRects; } - void* nodePointer() const { return mNode; } - bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; } - const WebCore::IntRect& originalAbsoluteBounds() const { - return mOriginalAbsoluteBounds; } - const CachedNode* parent() const { return document() + mParentIndex; } - void* parentGroup() const { return mParentGroup; } - int parentIndex() const { return mParentIndex; } - bool partRectsContains(const CachedNode* other) const; - const WebCore::IntRect& rawBounds() const { return mBounds; } - void reset(); - WebCore::IntRect ring(const CachedFrame* , size_t part) const; - const WTF::Vector<WebCore::IntRect>& rings() const { return mCursorRing; } - void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; } - void setClippedOut(bool clipped) { mClippedOut = clipped; } - void setColorIndex(int index) { mColorIndex = index; } - void setCondition(Condition condition) const { mCondition = condition; } - void setDataIndex(int index) { mDataIndex = index; } - void setDisabled(bool disabled) { mDisabled = disabled; } - void setExport(const WTF::String& exported) { mExport = exported; } - void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; } - void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; } - void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; } - void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) { - mOriginalAbsoluteBounds = bounds; } - void setIndex(int index) { mIndex = index; } - void setIsCursor(bool isCursor) { mIsCursor = isCursor; } - void setIsFocus(bool isFocus) { mIsFocus = isFocus; } - void setIsInLayer(bool isInLayer) { mIsInLayer = isInLayer; } - void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; } - void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; } - void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; } - void setLast() { mLast = true; } - void setNavableRects() { mNavableRects = mCursorRing.size(); } - void setParentGroup(void* group) { mParentGroup = group; } - void setParentIndex(int parent) { mParentIndex = parent; } - void setSingleImage(bool single) { mSingleImage = single; } - void setTabIndex(int index) { mTabIndex = index; } - void setType(CachedNodeType type) { mType = type; } - void show() { mIsHidden = false; } - bool singleImage() const { return mSingleImage; } - int tabIndex() const { return mTabIndex; } - int textInputIndex() const { return isTextInput() ? mDataIndex : -1; } - const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } - bool useBounds() const { return mUseBounds; } - bool useHitBounds() const { return mUseHitBounds; } - bool wantsKeyEvents() const { return isTextInput() || isPlugin() - || isContentEditable() || isFrame(); } -private: - friend class CacheBuilder; - WTF::String mExport; - WebCore::IntRect mBounds; - WebCore::IntRect mHitBounds; - WebCore::IntRect mOriginalAbsoluteBounds; - WTF::Vector<WebCore::IntRect> mCursorRing; - void* mNode; // WebCore::Node*, only used to match pointers - void* mParentGroup; // WebCore::Node*, only used to match pointers - int mDataIndex; // child frame if a frame; input data index; or -1 - int mIndex; // index of itself, to find first in array (document) - int mNavableRects; // FIXME: could be bitfield once I limit max number of rects - int mParentIndex; - int mTabIndex; - int mColorIndex; // index to ring color and other stylable properties - mutable Condition mCondition : 5; // why the node was not chosen on the first pass - CachedNodeType mType : 4; - bool mClippedOut : 1; - bool mDisabled : 1; - bool mFixedUpCursorRects : 1; - bool mHasCursorRing : 1; - bool mHasMouseOver : 1; - bool mIsCursor : 1; - bool mIsFocus : 1; - bool mIsHidden : 1; - bool mIsInLayer : 1; - bool mIsParentAnchor : 1; - bool mIsTransparent : 1; - bool mIsUnclipped : 1; - bool mLast : 1; // true if this is the last node in a group - bool mSingleImage : 1; - bool mUseBounds : 1; - bool mUseHitBounds : 1; -#ifdef BROWSER_DEBUG -public: - WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; } - bool mDisplayMeasure; - mutable bool mInCompare; - int mSideDistance; - int mSecondSide; -#endif -#if DEBUG_NAV_UI || DUMP_NAV_CACHE -public: - class Debug { -public: - CachedNode* base() const; - const char* condition(Condition t) const; - void print() const; - const char* type(CachedNodeType t) const; -#if DUMP_NAV_CACHE - int mNodeIndex; - int mParentGroupIndex; -#endif - } mDebug; - friend class CachedNode::Debug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedNodeType.h b/WebKit/android/nav/CachedNodeType.h deleted file mode 100644 index 8bc9328..0000000 --- a/WebKit/android/nav/CachedNodeType.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2007, 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 CachedNodeType_H -#define CachedNodeType_H - -namespace android { - -enum CachedNodeType { - NORMAL_CACHEDNODETYPE, - ADDRESS_CACHEDNODETYPE, - EMAIL_CACHEDNODETYPE, - PHONE_CACHEDNODETYPE, - ANCHOR_CACHEDNODETYPE, - AREA_CACHEDNODETYPE, - FRAME_CACHEDNODETYPE, - PLUGIN_CACHEDNODETYPE, - TEXT_INPUT_CACHEDNODETYPE, - SELECT_CACHEDNODETYPE, - CONTENT_EDITABLE_CACHEDNODETYPE -}; - -enum CachedNodeBits { - NORMAL_CACHEDNODE_BITS = 0, - ADDRESS_CACHEDNODE_BIT = 1 << (ADDRESS_CACHEDNODETYPE - 1), - EMAIL_CACHEDNODE_BIT = 1 << (EMAIL_CACHEDNODETYPE - 1), - PHONE_CACHEDNODE_BIT = 1 << (PHONE_CACHEDNODETYPE - 1), - ALL_CACHEDNODE_BITS = ADDRESS_CACHEDNODE_BIT | EMAIL_CACHEDNODE_BIT - | PHONE_CACHEDNODE_BIT -}; - -} - -#endif diff --git a/WebKit/android/nav/CachedPrefix.h b/WebKit/android/nav/CachedPrefix.h deleted file mode 100644 index 73a5c2c..0000000 --- a/WebKit/android/nav/CachedPrefix.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2007, 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 CachedPrefix_H -#define CachedPrefix_H - -#ifndef LOG_TAG -#define LOG_TAG "navcache" -#endif - -#include "config.h" -#include "CachedDebug.h" - -#ifndef _LIBS_CUTILS_LOG_H - #ifdef LOG - #undef LOG - #endif - - #include <utils/Log.h> -#endif - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#ifndef BZERO_DEFINED -#define BZERO_DEFINED -// http://www.opengroup.org/onlinepubs/000095399/functions/bzero.html -// For maximum portability, it is recommended to replace the function call to bzero() as follows: -#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) -#endif - -#endif diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp deleted file mode 100644 index 64bf19a..0000000 --- a/WebKit/android/nav/CachedRoot.cpp +++ /dev/null @@ -1,1813 +0,0 @@ -/* - * Copyright 2007, 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 "CachedPrefix.h" -#include "android_graphics.h" -#include "CachedHistory.h" -#include "CachedInput.h" -#include "CachedLayer.h" -#include "CachedNode.h" -#include "FindCanvas.h" -#include "FloatRect.h" -#include "LayerAndroid.h" -#include "ParseCanvas.h" -#include "SkBitmap.h" -#include "SkBounder.h" -#include "SkPixelRef.h" -#include "SkRegion.h" - -#include "CachedRoot.h" - -#if DEBUG_NAV_UI -#include "wtf/text/CString.h" -#endif - -#define DONT_CENTER_IF_ALREADY_VISIBLE - -using std::min; -using std::max; - -#ifdef DUMP_NAV_CACHE_USING_PRINTF - extern android::Mutex gWriteLogMutex; -#endif - -namespace android { - -class CommonCheck : public SkBounder { -public: - enum Type { - kNo_Type, - kDrawBitmap_Type, - kDrawGlyph_Type, - kDrawPaint_Type, - kDrawPath_Type, - kDrawPicture_Type, - kDrawPoints_Type, - kDrawPosText_Type, - kDrawPosTextH_Type, - kDrawRect_Type, - kDrawSprite_Type, - kDrawText_Type, - kDrawTextOnPath_Type, - kPopLayer_Type, - kPushLayer_Type, - kPushSave_Type - }; - - static bool isTextType(Type t) { - return t == kDrawPosTextH_Type || t == kDrawText_Type; - } - - CommonCheck() : mType(kNo_Type), mAllOpaque(true), mIsOpaque(true) { - setEmpty(); - } - - bool doRect(Type type) { - mType = type; - return doIRect(mUnion); - } - - bool isEmpty() { return mUnion.isEmpty(); } - - bool joinGlyphs(const SkIRect& rect) { - bool isGlyph = mType == kDrawGlyph_Type; - if (isGlyph) - mUnion.join(rect); - return isGlyph; - } - - void setAllOpaque(bool opaque) { mAllOpaque = opaque; } - void setEmpty() { mUnion.setEmpty(); } - void setIsOpaque(bool opaque) { mIsOpaque = opaque; } - void setType(Type type) { mType = type; } - - Type mType; - SkIRect mUnion; - bool mAllOpaque; - bool mIsOpaque; -}; - -#if DEBUG_NAV_UI - static const char* TypeNames[] = { - "kNo_Type", - "kDrawBitmap_Type", - "kDrawGlyph_Type", - "kDrawPaint_Type", - "kDrawPath_Type", - "kDrawPicture_Type", - "kDrawPoints_Type", - "kDrawPosText_Type", - "kDrawPosTextH_Type", - "kDrawRect_Type", - "kDrawSprite_Type", - "kDrawText_Type", - "kDrawTextOnPath_Type", - "kPopLayer_Type", - "kPushLayer_Type", - "kPushSave_Type" - }; -#endif - -#define kMargin 16 -#define kSlop 2 - -class BoundsCanvas : public ParseCanvas { -public: - - BoundsCanvas(CommonCheck* bounder) : mBounder(*bounder) { - mTransparentLayer = 0; - setBounder(bounder); - } - - virtual void drawPaint(const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPaint_Type); - INHERITED::drawPaint(paint); - } - - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPoints_Type); - INHERITED::drawPoints(mode, count, pts, paint); - } - - virtual void drawRect(const SkRect& rect, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawRect_Type); - INHERITED::drawRect(rect, paint); - } - - virtual void drawPath(const SkPath& path, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPath_Type); - INHERITED::drawPath(path, paint); - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& matrix, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawBitmap_Type); - mBounder.setIsOpaque(bitmap.isOpaque()); - INHERITED::commonDrawBitmap(bitmap, rect, matrix, paint); - } - - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint) { - mBounder.setType(CommonCheck::kDrawSprite_Type); - mBounder.setIsOpaque(bitmap.isOpaque() && - (!paint || paint->getAlpha() == 255)); - INHERITED::drawSprite(bitmap, left, top, paint); - } - - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawText(text, byteLength, x, y, paint); - mBounder.doRect(CommonCheck::kDrawText_Type); - } - - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawPosText(text, byteLength, pos, paint); - if (!mBounder.isEmpty()) - mBounder.doRect(CommonCheck::kDrawPosText_Type); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); - if (mBounder.mUnion.isEmpty()) { - DBG_NAV_LOGD("empty constY=%g", SkScalarToFloat(constY)); - return; - } - SkPaint::FontMetrics metrics; - paint.getFontMetrics(&metrics); - SkPoint upDown[2] = { {xpos[0], constY + metrics.fAscent}, - {xpos[0], constY + metrics.fDescent} }; - const SkMatrix& matrix = getTotalMatrix(); - matrix.mapPoints(upDown, 2); - if (upDown[0].fX == upDown[1].fX) { - mBounder.mUnion.fTop = SkScalarFloor(upDown[0].fY); - mBounder.mUnion.fBottom = SkScalarFloor(upDown[1].fY); - } - mBounder.doRect(CommonCheck::kDrawPosTextH_Type); - } - - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawTextOnPath(text, byteLength, path, matrix, paint); - mBounder.doRect(CommonCheck::kDrawTextOnPath_Type); - } - - virtual void drawPicture(SkPicture& picture) { - mBounder.setType(CommonCheck::kDrawPicture_Type); - INHERITED::drawPicture(picture); - } - - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { - int depth = INHERITED::saveLayer(bounds, paint, flags); - if (mTransparentLayer == 0 && paint && paint->getAlpha() < 255) { - mTransparentLayer = depth; - mBounder.setAllOpaque(false); - } - return depth; - } - - virtual void restore() { - mBounder.setType(CommonCheck::kDrawSprite_Type); // for layer draws - int depth = getSaveCount(); - if (depth == mTransparentLayer) { - mTransparentLayer = 0; - mBounder.setAllOpaque(true); - } - INHERITED::restore(); - } - - int mTransparentLayer; - CommonCheck& mBounder; -private: - typedef ParseCanvas INHERITED; -}; - -/* -LeftCheck examines the text in a picture, within a viewable rectangle, -and returns via left() the position of the left edge of the paragraph. -It first looks at the left edge of the test point, then looks above and below -it for more lines of text to determine the div's left edge. -*/ -class LeftCheck : public CommonCheck { -public: - LeftCheck(int x, int y) : mX(x), mY(y), mHitLeft(INT_MAX), - mMostLeft(INT_MAX) { - mHit.set(x - (HIT_SLOP << 1), y - HIT_SLOP, x, y + HIT_SLOP); - mPartial.setEmpty(); - mBounds.setEmpty(); - mPartialType = kNo_Type; - } - - int left() { - if (isTextType(mType)) - doRect(); // process the final line of text - return mMostLeft != INT_MAX ? mMostLeft : mX >> 1; - } - - // FIXME: this is identical to CenterCheck::onIRect() - // refactor so that LeftCheck and CenterCheck inherit common functions - virtual bool onIRect(const SkIRect& rect) { - bool opaqueBitmap = mType == kDrawBitmap_Type && mIsOpaque; - if (opaqueBitmap && rect.contains(mX, mY)) { - mMostLeft = rect.fLeft; - return false; - } - if (joinGlyphs(rect)) // assembles glyphs into a text string - return false; - if (!isTextType(mType) && !opaqueBitmap) - return false; - /* Text on one line may be broken into several parts. Reassemble - the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom - && rect.fBottom > mPartial.fTop - && mPartial.fRight + JOIN_SLOP_X >= rect.fLeft - && (mPartialType != kDrawBitmap_Type - || mPartial.height() <= rect.height() + JOIN_SLOP_Y)) { - DBG_NAV_LOGD("LeftCheck join mPartial=(%d, %d, %d, %d)" - " rect=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - mPartial.join(rect); - return false; - } - if (mPartial.isEmpty() == false) { - doRect(); // process the previous line of text -#if DEBUG_NAV_UI - if (mHitLeft == INT_MAX) - DBG_NAV_LOGD("LeftCheck disabled rect=(%d, %d, %d, %d)", - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); -#endif - } - mPartial = rect; - mPartialType = mType; - return false; - } - - void doRect() - { - /* Record the outer bounds of the lines of text that intersect the - touch coordinates, given some slop */ - if (SkIRect::Intersects(mPartial, mHit)) { - if (mHitLeft > mPartial.fLeft) - mHitLeft = mPartial.fLeft; - DBG_NAV_LOGD("LeftCheck mHitLeft=%d", mHitLeft); - } else if (mHitLeft == INT_MAX) - return; // wait for intersect success - /* If text is too far away vertically, don't consider it */ - if (!mBounds.isEmpty() && (mPartial.fTop > mBounds.fBottom + HIT_SLOP - || mPartial.fBottom < mBounds.fTop - HIT_SLOP)) { - DBG_NAV_LOGD("LeftCheck stop mPartial=(%d, %d, %d, %d)" - " mBounds=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - mBounds.fLeft, mBounds.fTop, mBounds.fRight, mBounds.fBottom); - mHitLeft = INT_MAX; // and disable future comparisons - return; - } - /* If the considered text is completely to the left or right of the - touch coordinates, skip it, turn off further detection */ - if (mPartial.fLeft > mX || mPartial.fRight < mX) { - DBG_NAV_LOGD("LeftCheck stop mX=%d mPartial=(%d, %d, %d, %d)", mX, - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom); - mHitLeft = INT_MAX; - return; - } - /* record the smallest margins on the left and right */ - if (mMostLeft > mPartial.fLeft) { - DBG_NAV_LOGD("LeftCheck new mMostLeft=%d (old=%d)", mPartial.fLeft, - mMostLeft); - mMostLeft = mPartial.fLeft; - } - if (mBounds.isEmpty()) - mBounds = mPartial; - else if (mPartial.fBottom > mBounds.fBottom) { - DBG_NAV_LOGD("LeftCheck new bottom=%d (old=%d)", mPartial.fBottom, - mBounds.fBottom); - mBounds.fBottom = mPartial.fBottom; - } - } - - static const int JOIN_SLOP_X = 30; // horizontal space between text parts - static const int JOIN_SLOP_Y = 5; // vertical space between text lines - static const int HIT_SLOP = 30; // diameter allowing for tap size - /* const */ SkIRect mHit; // sloppy hit rectangle - SkIRect mBounds; // reference bounds - SkIRect mPartial; // accumulated text bounds, per line - const int mX; // touch location - const int mY; - int mHitLeft; // touched text extremes - int mMostLeft; // paragraph extremes - Type mPartialType; -}; - -/* -CenterCheck examines the text in a picture, within a viewable rectangle, -and returns via center() the optimal amount to scroll in x to display the -paragraph of text. - -The caller of CenterCheck has configured (but not allocated) a bitmap -the height and three times the width of the view. The picture is drawn centered -in the bitmap, so text that would be revealed, if the view was scrolled up to -a view-width to the left or right, is considered. -*/ -class CenterCheck : public CommonCheck { -public: - CenterCheck(int x, int y, int width) : mX(x), mY(y), - mHitLeft(x), mHitRight(x), mMostLeft(INT_MAX), mMostRight(-INT_MAX), - mViewLeft(width), mViewRight(width << 1) { - mHit.set(x - CENTER_SLOP, y - CENTER_SLOP, - x + CENTER_SLOP, y + CENTER_SLOP); - mPartial.setEmpty(); - } - - int center() { - doRect(); // process the final line of text - /* If the touch coordinates aren't near any text, return 0 */ - if (mHitLeft == mHitRight) { - DBG_NAV_LOGD("abort: mHitLeft=%d ==mHitRight", mHitLeft); - return 0; - } - int leftOver = mHitLeft - mViewLeft; - int rightOver = mHitRight - mViewRight; - int center; - /* If the touched text is too large to entirely fit on the screen, - center it. */ - if (leftOver < 0 && rightOver > 0) { - center = (leftOver + rightOver) >> 1; - DBG_NAV_LOGD("overlap: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - center = (mMostLeft + mMostRight) >> 1; // the paragraph center - if (leftOver > 0 && rightOver >= 0) { // off to the right - if (center > mMostLeft) // move to center loses left-most text? - center = mMostLeft; - } else if (rightOver < 0 && leftOver <= 0) { // off to the left - if (center < mMostRight) // move to center loses right-most text? - center = mMostRight; - } else { -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - center = 0; // paragraph is already fully visible -#endif - } - DBG_NAV_LOGD("scroll: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - -protected: - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) // assembles glyphs into a text string - return false; - if (!isTextType(mType)) - return false; - /* Text on one line may be broken into several parts. Reassemble - the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom && rect.fBottom > - mPartial.fTop && mPartial.fRight + CENTER_SLOP >= rect.fLeft) { - DBG_NAV_LOGD("join mPartial=(%d, %d, %d, %d) rect=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - mPartial.join(rect); - return false; - } - if (mPartial.isEmpty() == false) - doRect(); // process the previous line of text - mPartial = rect; - return false; - } - - void doRect() - { - /* Record the outer bounds of the lines of text that was 'hit' by the - touch coordinates, given some slop */ - if (SkIRect::Intersects(mPartial, mHit)) { - if (mHitLeft > mPartial.fLeft) - mHitLeft = mPartial.fLeft; - if (mHitRight < mPartial.fRight) - mHitRight = mPartial.fRight; - DBG_NAV_LOGD("mHitLeft=%d mHitRight=%d", mHitLeft, mHitRight); - } - /* If the considered text is completely to the left or right of the - touch coordinates, skip it */ - if (mPartial.fLeft > mX || mPartial.fRight < mX) - return; - int leftOver = mPartial.fLeft - mViewLeft; - int rightOver = mPartial.fRight - mViewRight; - /* If leftOver <= 0, the text starts off the screen. - If rightOver >= 0, the text ends off the screen. - */ - if (leftOver <= 0 && rightOver >= 0) // discard wider than screen - return; -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - if (leftOver > 0 && rightOver < 0) // discard already visible - return; -#endif - /* record the smallest margins on the left and right */ - if (mMostLeft > leftOver) - mMostLeft = leftOver; - if (mMostRight < rightOver) - mMostRight = rightOver; - DBG_NAV_LOGD("leftOver=%d rightOver=%d mMostLeft=%d mMostRight=%d", - leftOver, rightOver, mMostLeft, mMostRight); - } - - static const int CENTER_SLOP = 10; // space between text parts and lines - /* const */ SkIRect mHit; // sloppy hit rectangle - SkIRect mPartial; // accumulated text bounds, per line - const int mX; // touch location - const int mY; - int mHitLeft; // touched text extremes - int mHitRight; - int mMostLeft; // paragraph extremes - int mMostRight; - const int mViewLeft; // middle third of 3x-wide view - const int mViewRight; -}; - -class ImageCanvas : public ParseCanvas { -public: - ImageCanvas(SkBounder* bounder) : mURI(NULL) { - setBounder(bounder); - } - - const char* getURI() { return mURI; } - -protected: -// Currently webkit's bitmap draws always seem to be cull'd before this entry -// point is called, so we assume that any bitmap that gets here is inside our -// tiny clip (may not be true in the future) - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& , const SkPaint& ) { - SkPixelRef* pixelRef = bitmap.pixelRef(); - if (pixelRef != NULL) { - mURI = pixelRef->getURI(); - } - } - -private: - const char* mURI; -}; - -class ImageCheck : public SkBounder { -public: - virtual bool onIRect(const SkIRect& rect) { - return false; - } -}; - -class JiggleCheck : public CommonCheck { -public: - JiggleCheck(int delta, int width) : mDelta(delta), mMaxX(width) { - mMaxJiggle = 0; - mMinX = mMinJiggle = abs(delta); - mMaxWidth = width + mMinX; - } - - int jiggle() { - if (mMinJiggle > mMaxJiggle) - return mDelta; - int avg = (mMinJiggle + mMaxJiggle + 1) >> 1; - return mDelta < 0 ? -avg : avg; - } - - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) - return false; - if (mType != kDrawBitmap_Type && !isTextType(mType)) - return false; - int min, max; - if (mDelta < 0) { - min = mMinX - rect.fLeft; - max = mMaxWidth - rect.fRight; - } else { - min = rect.fRight - mMaxX; - max = rect.fLeft; - } - if (min <= 0) - return false; - if (max >= mMinX) - return false; - if (mMinJiggle > min) - mMinJiggle = min; - if (mMaxJiggle < max) - mMaxJiggle = max; - return false; - } - - int mDelta; - int mMaxJiggle; - int mMaxX; - int mMinJiggle; - int mMinX; - int mMaxWidth; -}; - -class RingCheck : public CommonCheck { -public: - RingCheck(const WTF::Vector<WebCore::IntRect>& rings, - const WebCore::IntRect& bitBounds, const WebCore::IntRect& testBounds, - bool singleImage) - : mTestBounds(testBounds) - , mBitBounds(bitBounds) - , mPushPop(false) - , mSingleImage(singleImage) - { - const WebCore::IntRect* r; - for (r = rings.begin(); r != rings.end(); r++) { - SkIRect fatter = {r->x(), r->y(), r->right(), r->bottom()}; - fatter.inset(-CURSOR_RING_HIT_TEST_RADIUS, -CURSOR_RING_HIT_TEST_RADIUS); - DBG_NAV_LOGD("RingCheck fat=(%d,%d,r=%d,b=%d)", fatter.fLeft, fatter.fTop, - fatter.fRight, fatter.fBottom); - mTextSlop.op(fatter, SkRegion::kUnion_Op); - mTextTest.op(*r, SkRegion::kUnion_Op); - } - int dx = -bitBounds.x(); - int dy = -bitBounds.y(); - DBG_NAV_LOGD("RingCheck translate=(%d,%d)", dx, dy); - mTextSlop.translate(dx, dy); - mTextTest.translate(dx, dy); - mTestBounds.translate(dx, dy); - mEmpty.setEmpty(); - } - - bool hiddenRings(SkRegion* clipped) - { - findBestLayer(); - if (!mBestLayer) { - DBG_NAV_LOG("RingCheck empty"); - clipped->setEmpty(); - return true; - } - const SkRegion* layersEnd = mLayers.end(); - const Type* layerTypes = &mLayerTypes[mBestLayer - mLayers.begin()]; - bool collectGlyphs = true; - bool collectOvers = false; - SkRegion over; - for (const SkRegion* layers = mBestLayer; layers != layersEnd; layers++) { - Type layerType = *layerTypes++; - DBG_NAV_LOGD("RingCheck #%d %s (%d,%d,r=%d,b=%d)", - layers - mLayers.begin(), TypeNames[layerType], - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom); - if (collectGlyphs && (layerType == kDrawGlyph_Type - || ((layerType == kDrawRect_Type && mTextTest.contains(*layers)) - || (layerType == kDrawBitmap_Type && mTextSlop.contains(*layers))))) { - DBG_NAV_LOGD("RingCheck #%d collectOvers", layers - mLayers.begin()); - collectOvers = true; - clipped->op(*layers, SkRegion::kUnion_Op); - continue; - } - collectGlyphs &= layerType != kPushLayer_Type; - if (collectOvers && (layerType == kDrawRect_Type - || layerType == kDrawBitmap_Type - || (!collectGlyphs && layerType == kDrawSprite_Type))) { - DBG_NAV_LOGD("RingCheck #%d over.op", layers - mLayers.begin()); - over.op(*layers, SkRegion::kUnion_Op); - } - } - bool result = !collectOvers || clipped->intersects(over); - const SkIRect t = clipped->getBounds(); - const SkIRect o = over.getBounds(); - clipped->op(over, SkRegion::kDifference_Op); - clipped->translate(mBitBounds.x(), mBitBounds.y()); - const SkIRect c = clipped->getBounds(); - DBG_NAV_LOGD("RingCheck intersects=%s text=(%d,%d,r=%d,b=%d)" - " over=(%d,%d,r=%d,b=%d) clipped=(%d,%d,r=%d,b=%d)", - result ? "true" : "false", - t.fLeft, t.fTop, t.fRight, t.fBottom, - o.fLeft, o.fTop, o.fRight, o.fBottom, - c.fLeft, c.fTop, c.fRight, c.fBottom); - return result; - } - - void push(Type type, const SkIRect& bounds) - { -#if DEBUG_NAV_UI - // this caches the push string and subquently ignores if pushSave - // is immediately followed by popLayer. Push/pop pairs happen - // frequently and just add noise to the log. - static String lastLog; - String currentLog = String("RingCheck append #") - + String::number(mLayers.size()) - + " type=" + TypeNames[type] + " bounds=(" - + String::number(bounds.fLeft) - + "," + String::number(bounds.fTop) + "," - + String::number(bounds.fRight) + "," - + String::number(bounds.fBottom) + ")"; - if (lastLog.length() == 0 || type != kPopLayer_Type) { - if (lastLog.length() != 0) - DBG_NAV_LOGD("%s", lastLog.latin1().data()); - if (type == kPushSave_Type) - lastLog = currentLog; - else - DBG_NAV_LOGD("%s", currentLog.latin1().data()); - } else - lastLog = ""; -#endif - popEmpty(); - mPushPop |= type >= kPopLayer_Type; - if (type == kPopLayer_Type) { - Type last = mLayerTypes.last(); - // remove empty brackets - if (last == kPushLayer_Type || last == kPushSave_Type) { - mLayers.removeLast(); - mLayerTypes.removeLast(); - return; - } - // remove push/pop from push/bitmap/pop - size_t pushIndex = mLayerTypes.size() - 2; - if (last == kDrawBitmap_Type - && mLayerTypes.at(pushIndex) == kPushLayer_Type) { - mLayers.at(pushIndex) = mLayers.last(); - mLayerTypes.at(pushIndex) = kDrawBitmap_Type; - mLayers.removeLast(); - mLayerTypes.removeLast(); - return; - } - // remove non-layer brackets - int stack = 0; - Type* types = mLayerTypes.end(); - while (types != mLayerTypes.begin()) { - Type type = *--types; - if (type == kPopLayer_Type) { - stack++; - continue; - } - if (type != kPushLayer_Type && type != kPushSave_Type) - continue; - if (--stack >= 0) - continue; - if (type == kPushLayer_Type) - break; - int remove = types - mLayerTypes.begin(); - DBG_NAV_LOGD("RingCheck remove=%d mLayers.size=%d" - " mLayerTypes.size=%d", remove, mLayers.size(), - mLayerTypes.size()); - mLayers.remove(remove); - mLayerTypes.remove(remove); - mAppendLikeTypes = false; - return; - } - } - mLayers.append(bounds); - mLayerTypes.append(type); - } - - void startText(const SkPaint& paint) - { - mPaint = &paint; - if (!mLayerTypes.isEmpty() && mLayerTypes.last() == kDrawGlyph_Type - && !mLayers.last().isEmpty()) { - push(kDrawGlyph_Type, mEmpty); - } - } - - bool textOutsideRings() - { - findBestLayer(); - if (!mBestLayer) { - DBG_NAV_LOG("RingCheck empty"); - return false; - } - const SkRegion* layers = mBestLayer; - const Type* layerTypes = &mLayerTypes[layers - mLayers.begin()]; - // back up to include text drawn before the best layer - SkRegion active = SkRegion(mBitBounds); - active.translate(-mBitBounds.x(), -mBitBounds.y()); - while (layers != mLayers.begin()) { - --layers; - Type layerType = *--layerTypes; - DBG_NAV_LOGD("RingCheck #%d %s" - " mTestBounds=(%d,%d,r=%d,b=%d) layers=(%d,%d,r=%d,b=%d)" - " active=(%d,%d,r=%d,b=%d)", - layers - mLayers.begin(), TypeNames[layerType], - mTestBounds.getBounds().fLeft, mTestBounds.getBounds().fTop, - mTestBounds.getBounds().fRight, mTestBounds.getBounds().fBottom, - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom, - active.getBounds().fLeft, active.getBounds().fTop, - active.getBounds().fRight, active.getBounds().fBottom); - if (layerType == kDrawRect_Type || layerType == kDrawBitmap_Type) { - SkRegion temp = *layers; - temp.op(mTestBounds, SkRegion::kIntersect_Op); - active.op(temp, SkRegion::kDifference_Op); - if (active.isEmpty()) { - DBG_NAV_LOGD("RingCheck #%d empty", layers - mLayers.begin()); - break; - } - } else if (layerType == kDrawGlyph_Type) { - SkRegion temp = *layers; - temp.op(active, SkRegion::kIntersect_Op); - if (!mTestBounds.intersects(temp)) - continue; - if (!mTestBounds.contains(temp)) - return false; - } else - break; - } - layers = mBestLayer; - layerTypes = &mLayerTypes[layers - mLayers.begin()]; - bool foundGlyph = false; - bool collectGlyphs = true; - do { - Type layerType = *layerTypes++; - DBG_NAV_LOGD("RingCheck #%d %s mTestBounds=(%d,%d,r=%d,b=%d)" - " layers=(%d,%d,r=%d,b=%d) collects=%s intersects=%s contains=%s", - layers - mLayers.begin(), TypeNames[layerType], - mTestBounds.getBounds().fLeft, mTestBounds.getBounds().fTop, - mTestBounds.getBounds().fRight, mTestBounds.getBounds().fBottom, - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom, - collectGlyphs ? "true" : "false", - mTestBounds.intersects(*layers) ? "true" : "false", - mTextSlop.contains(*layers) ? "true" : "false"); - if (collectGlyphs && layerType == kDrawGlyph_Type) { - if (!mTestBounds.intersects(*layers)) - continue; - if (!mTextSlop.contains(*layers)) - return false; - foundGlyph = true; - } - collectGlyphs &= layerType != kPushLayer_Type; - } while (++layers != mLayers.end()); - DBG_NAV_LOGD("RingCheck foundGlyph=%s", foundGlyph ? "true" : "false"); - return foundGlyph; - } - -protected: - virtual bool onIRect(const SkIRect& rect) - { - joinGlyphs(rect); - if (mType != kDrawGlyph_Type && mType != kDrawRect_Type - && mType != kDrawSprite_Type && mType != kDrawBitmap_Type) - return false; - if (mLayerTypes.isEmpty() || mLayerTypes.last() != mType - || !mAppendLikeTypes || mPushPop || mSingleImage - // if the last and current were not glyphs, - // and the two bounds have a gap between, don't join them -- push - // an empty between them - || (mType != kDrawGlyph_Type && !joinable(rect))) { - push(mType, mEmpty); - } - DBG_NAV_LOGD("RingCheck join %s (%d,%d,r=%d,b=%d) '%c'", - TypeNames[mType], rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - mCh); - mLayers.last().op(rect, SkRegion::kUnion_Op); - mAppendLikeTypes = true; - mPushPop = false; - return false; - } - - virtual bool onIRectGlyph(const SkIRect& rect, - const SkBounder::GlyphRec& rec) - { - mCh = ' '; - if (mPaint) { - SkUnichar unichar; - SkPaint utfPaint = *mPaint; - utfPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - utfPaint.glyphsToUnichars(&rec.fGlyphID, 1, &unichar); - mCh = unichar < 0x7f ? unichar : '?'; - } - return onIRect(rect); - } - -private: - int calcOverlap(SkRegion& testRegion) - { - if (testRegion.isEmpty()) - return INT_MAX; - testRegion.op(mTextTest, SkRegion::kXOR_Op); - SkRegion::Iterator iter(testRegion); - int area = 0; - while (!iter.done()) { - const SkIRect& cr = iter.rect(); - area += cr.width() * cr.height(); - iter.next(); - } - DBG_NAV_LOGD("RingCheck area=%d", area); - return area; - } - - void findBestLayer() - { - popEmpty(); - mBestLayer = 0; - const SkRegion* layers = mLayers.begin(); - const SkRegion* layersEnd = mLayers.end(); - if (layers == layersEnd) { - DBG_NAV_LOG("RingCheck empty"); - return; - } - // find text most like focus rings by xoring found with original - int bestArea = INT_MAX; - const SkRegion* testLayer = 0; - SkRegion testRegion; - const Type* layerTypes = &mLayerTypes[layers - mLayers.begin()]; - for (; layers != mLayers.end(); layers++) { - Type layerType = *layerTypes++; -#if DEBUG_NAV_UI - const SkIRect& gb = layers->getBounds(); - const SkIRect& tb = mTextSlop.getBounds(); - DBG_NAV_LOGD("RingCheck #%d %s mTextSlop=(%d,%d,%d,%d)" - " contains=%s bounds=(%d,%d,%d,%d)", - layers - mLayers.begin(), TypeNames[layerType], - tb.fLeft, tb.fTop, tb.fRight, tb.fBottom, - mTextSlop.contains(*layers) ? "true" : "false", - gb.fLeft, gb.fTop, gb.fRight, gb.fBottom); -#endif - if (((layerType == kDrawGlyph_Type || layerType == kDrawBitmap_Type) - && mTextSlop.contains(*layers)) - || (layerType == kDrawRect_Type - && mTextTest.contains(*layers))) { - if (!testLayer) - testLayer = layers; - testRegion.op(*layers, SkRegion::kUnion_Op); - continue; - } - if (testLayer) { - int area = calcOverlap(testRegion); - if (bestArea > area) { - bestArea = area; - mBestLayer = testLayer; - } - DBG_NAV_LOGD("RingCheck #%d push test=%d best=%d", - layers - mLayers.begin(), testLayer - mLayers.begin(), - mBestLayer ? mBestLayer - mLayers.begin() : -1); - testRegion.setEmpty(); - testLayer = 0; - } - } - if (testLayer && bestArea > calcOverlap(testRegion)) { - DBG_NAV_LOGD("RingCheck last best=%d", testLayer - mLayers.begin()); - mBestLayer = testLayer; - } - } - - bool joinable(const SkIRect& rect) - { - SkRegion region = mLayers.last(); - if (!region.isRect()) - return false; - const SkIRect& bounds1 = region.getBounds(); - int area1 = bounds1.width() * bounds1.height(); - area1 += rect.width() * rect.height(); - region.op(rect, SkRegion::kUnion_Op); - const SkIRect& bounds2 = region.getBounds(); - int area2 = bounds2.width() * bounds2.height(); - return area2 <= area1; - } - - void popEmpty() - { - if (mLayerTypes.size() == 0) - return; - Type last = mLayerTypes.last(); - if (last >= kPopLayer_Type) - return; - const SkRegion& area = mLayers.last(); - if (!area.isEmpty()) - return; - DBG_NAV_LOGD("RingCheck #%d %s", mLayers.size() - 1, TypeNames[last]); - mLayers.removeLast(); - mLayerTypes.removeLast(); - } - - SkRegion mTestBounds; - IntRect mBitBounds; - SkIRect mEmpty; - const SkRegion* mBestLayer; - SkRegion mTextSlop; // outset rects for inclusion test - SkRegion mTextTest; // exact rects for xor area test - Type mLastType; - Vector<SkRegion> mLayers; - Vector<Type> mLayerTypes; - const SkPaint* mPaint; - char mCh; - bool mAppendLikeTypes; - bool mPushPop; - bool mSingleImage; -}; - -class RingCanvas : public BoundsCanvas { -public: - RingCanvas(RingCheck* bounder) - : INHERITED(bounder) - { - } - -protected: - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawText(text, byteLength, x, y, paint); - } - - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawPosText(text, byteLength, pos, paint); - } - - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawTextOnPath(text, byteLength, path, matrix, paint); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); - } - - virtual int save(SaveFlags flags) - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPushSave_Type, getTotalClip().getBounds()); - return INHERITED::save(flags); - } - - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPushLayer_Type, getTotalClip().getBounds()); - return INHERITED::save(flags); - } - - virtual void restore() - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPopLayer_Type, getTotalClip().getBounds()); - INHERITED::restore(); - } - -private: - typedef BoundsCanvas INHERITED; -}; - -bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, - WebCore::IntPoint* scrollPtr, bool findClosest) -{ - WebCore::IntRect newOutset; - const CachedNode* newNode = best->mNode; - // see if there's a middle node - // if the middle node is in the visited list, - // or if none was computed and the newNode is in the visited list, - // treat result as NULL - if (newNode != NULL && findClosest) { - if (best->bounds().intersects(mHistory->mPriorBounds) == false && - checkBetween(best, direction)) - newNode = best->mNode; - if (findClosest && maskIfHidden(best)) { - innerMove(document(), best, direction, scrollPtr, false); - return true; - } - newOutset = newNode->cursorRingBounds(best->mFrame); - } - int delta; - bool newNodeInView = scrollDelta(newOutset, direction, &delta); - if (delta && scrollPtr && (newNode == NULL || newNodeInView == false || - (best->mNavOutside && best->mWorkingOutside))) - *scrollPtr = WebCore::IntPoint(direction & UP_DOWN ? 0 : delta, - direction & UP_DOWN ? delta : 0); - return false; -} - -void CachedRoot::calcBitBounds(const IntRect& nodeBounds, IntRect* bitBounds) const -{ - IntRect contentBounds = IntRect(0, 0, mPicture->width(), mPicture->height()); - IntRect overBounds = nodeBounds; - overBounds.inflate(kMargin); - IntRect viewableBounds = mScrolledBounds; - viewableBounds.unite(mViewBounds); - *bitBounds = contentBounds; - bitBounds->intersect(overBounds); - if (!bitBounds->intersects(viewableBounds)) - *bitBounds = IntRect(0, 0, 0, 0); - DBG_NAV_LOGD("contentBounds=(%d,%d,r=%d,b=%d) overBounds=(%d,%d,r=%d,b=%d)" - " mScrolledBounds=(%d,%d,r=%d,b=%d) mViewBounds=(%d,%d,r=%d,b=%d)" - " bitBounds=(%d,%d,r=%d,b=%d)", - contentBounds.x(), contentBounds.y(), contentBounds.right(), - contentBounds.bottom(), - overBounds.x(), overBounds.y(), overBounds.right(), overBounds.bottom(), - mScrolledBounds.x(), mScrolledBounds.y(), mScrolledBounds.right(), - mScrolledBounds.bottom(), - mViewBounds.x(), mViewBounds.y(), mViewBounds.right(), - mViewBounds.bottom(), - bitBounds->x(), bitBounds->y(), bitBounds->right(), - bitBounds->bottom()); -} - - -int CachedRoot::checkForCenter(int x, int y) const -{ - int width = mViewBounds.width(); - SkPicture* picture = pictureAt(&x, &y); - CenterCheck centerCheck(x + width - mViewBounds.x(), y - mViewBounds.y(), - width); - BoundsCanvas checker(¢erCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width * 3, - mViewBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(width - mViewBounds.x()), - SkIntToScalar(-mViewBounds.y())); - checker.drawPicture(*picture); - return centerCheck.center(); -} - -void CachedRoot::checkForJiggle(int* xDeltaPtr) const -{ - int xDelta = *xDeltaPtr; - JiggleCheck jiggleCheck(xDelta, mViewBounds.width()); - BoundsCanvas checker(&jiggleCheck); - SkBitmap bitmap; - int absDelta = abs(xDelta); - bitmap.setConfig(SkBitmap::kARGB_8888_Config, mViewBounds.width() + - absDelta, mViewBounds.height()); - checker.setBitmapDevice(bitmap); - int x = -mViewBounds.x() - (xDelta < 0 ? xDelta : 0); - int y = -mViewBounds.y(); - SkPicture* picture = pictureAt(&x, &y); - checker.translate(SkIntToScalar(x), SkIntToScalar(y)); - checker.drawPicture(*picture); - *xDeltaPtr = jiggleCheck.jiggle(); -} - -bool CachedRoot::checkRings(SkPicture* picture, const CachedNode* node, - const WebCore::IntRect& testBounds) const -{ - if (!picture) - return false; - const WTF::Vector<WebCore::IntRect>& rings = node->rings(); - const WebCore::IntRect& nodeBounds = node->rawBounds(); - IntRect bitBounds; - calcBitBounds(nodeBounds, &bitBounds); - RingCheck ringCheck(rings, bitBounds, testBounds, node->singleImage()); - RingCanvas checker(&ringCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(), - bitBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-bitBounds.x()), - SkIntToScalar(-bitBounds.y())); - checker.drawPicture(*picture); - bool result = ringCheck.textOutsideRings(); - DBG_NAV_LOGD("bitBounds=(%d,%d,r=%d,b=%d) nodeBounds=(%d,%d,r=%d,b=%d)" - " testBounds=(%d,%d,r=%d,b=%d) success=%s", - bitBounds.x(), bitBounds.y(), bitBounds.right(), bitBounds.bottom(), - nodeBounds.x(), nodeBounds.y(), nodeBounds.right(), nodeBounds.bottom(), - testBounds.x(), testBounds.y(), testBounds.right(), testBounds.bottom(), - result ? "true" : "false"); - return result; -} - -void CachedRoot::draw(FindCanvas& canvas) const -{ - canvas.setLayerId(-1); // overlays change the ID as their pictures draw - canvas.drawPicture(*mPicture); -#if USE(ACCELERATED_COMPOSITING) - if (!mRootLayer) - return; - canvas.drawLayers(mRootLayer); -#endif -} - -const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* x, int* y, bool checkForHidden) const -{ -#if DEBUG_NAV_UI - DBG_NAV_LOGD("rect=(%d,%d,w=%d,h=%d) xy=(%d,%d)", rect.x(), rect.y(), - rect.width(), rect.height(), *x, *y); - if (mRootLayer) CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif - int best = INT_MAX; - bool inside = false; - (const_cast<CachedRoot*>(this))->resetClippedOut(); - const CachedFrame* directHitFramePtr; - const CachedNode* directHit = NULL; - const CachedNode* node = findBestAt(rect, &best, &inside, &directHit, - &directHitFramePtr, framePtr, x, y, checkForHidden); - DBG_NAV_LOGD("node=%d (%p) xy=(%d,%d)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer(), *x, *y); - if (node == NULL) { - node = findBestHitAt(rect, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer()); - } - if (node == NULL) { - *framePtr = findBestFrameAt(rect.x() + (rect.width() >> 1), - rect.y() + (rect.height() >> 1)); - } - return node; -} - -WebCore::IntPoint CachedRoot::cursorLocation() const -{ - const WebCore::IntRect& bounds = mHistory->mNavBounds; - return WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); -} - -WebCore::IntPoint CachedRoot::focusLocation() const -{ - return WebCore::IntPoint(mFocusBounds.x() + (mFocusBounds.width() >> 1), - mFocusBounds.y() + (mFocusBounds.height() >> 1)); -} - -// These reset the values because we only want to get the selection the first time. -// After that, the selection is no longer accurate. -int CachedRoot::getAndResetSelectionEnd() -{ - int end = mSelectionEnd; - mSelectionEnd = -1; - return end; -} - -int CachedRoot::getAndResetSelectionStart() -{ - int start = mSelectionStart; - mSelectionStart = -1; - return start; -} - -int CachedRoot::getBlockLeftEdge(int x, int y, float scale) const -{ - DBG_NAV_LOGD("x=%d y=%d scale=%g mViewBounds=(%d,%d,%d,%d)", x, y, scale, - mViewBounds.x(), mViewBounds.y(), mViewBounds.width(), - mViewBounds.height()); - // if (x, y) is in a textArea or textField, return that - const int slop = 1; - WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, - slop * 2, slop * 2); - const CachedFrame* frame; - int fx, fy; - const CachedNode* node = findAt(rect, &frame, &fx, &fy, true); - if (node && node->wantsKeyEvents()) { - DBG_NAV_LOGD("x=%d (%s)", node->bounds(frame).x(), - node->isTextInput() ? "text" : "plugin"); - return node->bounds(frame).x(); - } - SkPicture* picture = node ? frame->picture(node, &x, &y) : pictureAt(&x, &y); - if (!picture) - return x; - int halfW = (int) (mViewBounds.width() * scale * 0.5f); - int fullW = halfW << 1; - int halfH = (int) (mViewBounds.height() * scale * 0.5f); - int fullH = halfH << 1; - LeftCheck leftCheck(fullW, halfH); - BoundsCanvas checker(&leftCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, fullW, fullH); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(fullW - x), SkIntToScalar(halfH - y)); - checker.drawPicture(*picture); - int result = x + leftCheck.left() - fullW; - DBG_NAV_LOGD("halfW=%d halfH=%d mMostLeft=%d x=%d", - halfW, halfH, leftCheck.mMostLeft, result); - return result; -} - -void CachedRoot::getSimulatedMousePosition(WebCore::IntPoint* point) const -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - const WebCore::IntRect& mouseBounds = mHistory->mMouseBounds; - int x = mouseBounds.x(); - int y = mouseBounds.y(); - int width = mouseBounds.width(); - int height = mouseBounds.height(); - point->setX(x + (width >> 1)); // default to box center - point->setY(y + (height >> 1)); -#if DEBUG_NAV_UI - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - DBG_NAV_LOGD("mHistory->mNavBounds={%d,%d,%d,%d} " - "mHistory->mMouseBounds={%d,%d,%d,%d} point={%d,%d}", - navBounds.x(), navBounds.y(), navBounds.width(), navBounds.height(), - mouseBounds.x(), mouseBounds.y(), mouseBounds.width(), - mouseBounds.height(), point->x(), point->y()); -#endif -} - -void CachedRoot::init(WebCore::Frame* frame, CachedHistory* history) -{ - CachedFrame::init(this, -1, frame); - reset(); - mHistory = history; - mPicture = NULL; -} - -bool CachedRoot::innerDown(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.right()); - setupScrolledBounds(); - // (line up) - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testTop = mScrolledBounds.y(); - int viewBottom = mViewBounds.bottom(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.bottom() > viewBottom && viewBottom < mContents.height()) - return false; - if (navBounds.isEmpty() == false) { - int navTop = navBounds.y(); - int scrollBottom; - if (testTop < navTop && navTop < (scrollBottom = mScrolledBounds.bottom())) { - mScrolledBounds.setHeight(scrollBottom - navTop); - mScrolledBounds.setY(navTop); - } - } - setCursorCache(0, mMaxYScroll); - frameDown(test, NULL, bestData); - return true; -} - -bool CachedRoot::innerLeft(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.bottom()); - setupScrolledBounds(); - mScrolledBounds.setX(mScrolledBounds.x() - mMaxXScroll); - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testRight = mScrolledBounds.right(); - int viewLeft = mViewBounds.x(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.x() < viewLeft && viewLeft > mContents.x()) - return false; - if (navBounds.isEmpty() == false) { - int navRight = navBounds.right(); - int scrollLeft; - if (testRight > navRight && navRight > (scrollLeft = mScrolledBounds.x())) - mScrolledBounds.setWidth(navRight - scrollLeft); - } - setCursorCache(-mMaxXScroll, 0); - frameLeft(test, NULL, bestData); - return true; -} - - -void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, - Direction direction, WebCore::IntPoint* scroll, bool firstCall) -{ - bestData->reset(); - bool outOfCursor = mCursorIndex == CURSOR_CLEARED; - DBG_NAV_LOGD("mHistory->didFirstLayout()=%s && mCursorIndex=%d", - mHistory->didFirstLayout() ? "true" : "false", mCursorIndex); - if (mHistory->didFirstLayout() && mCursorIndex < CURSOR_SET) { - mHistory->reset(); - outOfCursor = true; - } - const CachedFrame* cursorFrame; - const CachedNode* cursor = currentCursor(&cursorFrame); - mHistory->setWorking(direction, cursorFrame, cursor, mViewBounds); - bool findClosest = false; - if (mScrollOnly == false) { - switch (direction) { - case LEFT: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.right(), - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerLeft(node, bestData); - break; - case RIGHT: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x() - 1, - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerRight(node, bestData); - break; - case UP: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.bottom(), mViewBounds.width(), 1); - findClosest = innerUp(node, bestData); - break; - case DOWN: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.y() - 1, mViewBounds.width(), 1); - findClosest = innerDown(node, bestData); - break; - case UNINITIALIZED: - default: - ASSERT(0); - } - } - if (firstCall) - mHistory->mPriorBounds = mHistory->mNavBounds; // bounds always advances, even if new node is ultimately NULL - bestData->setMouseBounds(bestData->bounds()); - if (adjustForScroll(bestData, direction, scroll, findClosest)) - return; - if (bestData->mNode != NULL) { - mHistory->addToVisited(bestData->mNode, direction); - mHistory->mNavBounds = bestData->bounds(); - mHistory->mMouseBounds = bestData->mouseBounds(); - } else if (scroll->x() != 0 || scroll->y() != 0) { - WebCore::IntRect newBounds = mHistory->mNavBounds; - int offsetX = scroll->x(); - int offsetY = scroll->y(); - newBounds.move(offsetX, offsetY); - if (mViewBounds.x() > newBounds.x()) - offsetX = mViewBounds.x() - mHistory->mNavBounds.x(); - else if (mViewBounds.right() < newBounds.right()) - offsetX = mViewBounds.right() - mHistory->mNavBounds.right(); - if (mViewBounds.y() > newBounds.y()) - offsetY = mViewBounds.y() - mHistory->mNavBounds.y(); - else if (mViewBounds.bottom() < newBounds.bottom()) - offsetY = mViewBounds.bottom() - mHistory->mNavBounds.bottom(); - mHistory->mNavBounds.move(offsetX, offsetY); - } - mHistory->setDidFirstLayout(false); -} - -bool CachedRoot::innerRight(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.bottom()); - setupScrolledBounds(); - // (align) - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testLeft = mScrolledBounds.x(); - int viewRight = mViewBounds.right(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.right() > viewRight && viewRight < mContents.width()) - return false; - if (navBounds.isEmpty() == false) { - int navLeft = navBounds.x(); - int scrollRight; - if (testLeft < navLeft && navLeft < (scrollRight = mScrolledBounds.right())) { - mScrolledBounds.setWidth(scrollRight - navLeft); - mScrolledBounds.setX(navLeft); - } - } - setCursorCache(mMaxXScroll, 0); - frameRight(test, NULL, bestData); - return true; -} - -bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.right()); - setupScrolledBounds(); - mScrolledBounds.setY(mScrolledBounds.y() - mMaxYScroll); - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testBottom = mScrolledBounds.bottom(); - int viewTop = mViewBounds.y(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.y() < viewTop && viewTop > mContents.y()) - return false; - if (navBounds.isEmpty() == false) { - int navBottom = navBounds.bottom(); - int scrollTop; - if (testBottom > navBottom && navBottom > (scrollTop = mScrolledBounds.y())) - mScrolledBounds.setHeight(navBottom - scrollTop); - } - setCursorCache(0, -mMaxYScroll); - frameUp(test, NULL, bestData); - return true; -} - -WTF::String CachedRoot::imageURI(int x, int y) const -{ - DBG_NAV_LOGD("x/y=(%d,%d)", x, y); - ImageCheck imageCheck; - ImageCanvas checker(&imageCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); - checker.setBitmapDevice(bitmap); - SkPicture* picture = pictureAt(&x, &y); - checker.translate(SkIntToScalar(-x), SkIntToScalar(-y)); - checker.drawPicture(*picture); - DBG_NAV_LOGD("uri=%s", checker.getURI()); - return WTF::String(checker.getURI()); -} - -bool CachedRoot::maskIfHidden(BestData* best) const -{ - const CachedNode* bestNode = best->mNode; - if (bestNode->isUnclipped()) - return false; - const CachedFrame* frame = best->mFrame; - SkPicture* picture = frame->picture(bestNode); - if (picture == NULL) { - DBG_NAV_LOG("missing picture"); - return false; - } - Vector<IntRect> rings; - bestNode->cursorRings(frame, &rings); - const WebCore::IntRect& bounds = bestNode->bounds(frame); - IntRect bitBounds; - calcBitBounds(bounds, &bitBounds); - RingCheck ringCheck(rings, bitBounds, bounds, bestNode->singleImage()); - RingCanvas checker(&ringCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(), - bitBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-bitBounds.x()), - SkIntToScalar(-bitBounds.y())); - checker.drawPicture(*picture); - SkRegion clipRgn; - bool clipped = ringCheck.hiddenRings(&clipRgn); - CachedNode* node = const_cast<CachedNode*>(best->mNode); - DBG_NAV_LOGD("clipped=%s clipRgn.isEmpty=%s", clipped ? "true" : "false", - clipRgn.isEmpty() ? "true" : "false"); - if (clipped && clipRgn.isEmpty()) { - node->setDisabled(true); - IntRect clippedBounds = bounds; - clippedBounds.intersect(bitBounds); - node->setClippedOut(clippedBounds != bounds); - return true; - } - // was it partially occluded by later drawing? - // if partially occluded, modify the bounds so that the mouse click has a better x,y - if (clipped) { - DBG_NAV_LOGD("clipped clipRgn={%d,%d,r=%d,b=%d}", - clipRgn.getBounds().fLeft, clipRgn.getBounds().fTop, - clipRgn.getBounds().fRight, clipRgn.getBounds().fBottom); - best->setMouseBounds(clipRgn.getBounds()); - if (!node->clip(best->mouseBounds())) { - node->setDisabled(true); - node->setClippedOut(true); - return true; - } - } else - node->fixUpCursorRects(frame); - return false; -} - -const CachedNode* CachedRoot::moveCursor(Direction direction, const CachedFrame** framePtr, - WebCore::IntPoint* scroll) -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - CachedRoot* frame = this; - const CachedNode* node = frame->document(); - if (node == NULL) - return NULL; - if (mViewBounds.isEmpty()) - return NULL; - resetClippedOut(); - setData(); - BestData bestData; - innerMove(node, &bestData, direction, scroll, true); - // if node is partially or fully concealed by layer, scroll it into view - if (mRootLayer && bestData.mNode && !bestData.mNode->isInLayer()) { -#if USE(ACCELERATED_COMPOSITING) -#if DUMP_NAV_CACHE - CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif - SkIRect original = bestData.mNode->cursorRingBounds(bestData.mFrame); - DBG_NAV_LOGD("original=(%d,%d,w=%d,h=%d) scroll=(%d,%d)", - original.fLeft, original.fTop, original.width(), original.height(), - scroll->x(), scroll->y()); - original.offset(-scroll->x(), -scroll->y()); - SkRegion rings(original); - SkTDArray<SkRect> region; - mRootLayer->clipArea(®ion); - SkRegion layers; - for (int index = 0; index < region.count(); index++) { - SkIRect enclosing; - region[index].round(&enclosing); - rings.op(enclosing, SkRegion::kDifference_Op); - layers.op(enclosing, SkRegion::kUnion_Op); - } - SkIRect layerBounds(layers.getBounds()); - SkIRect ringBounds(rings.getBounds()); - int scrollX = scroll->x(); - int scrollY = scroll->y(); - if (rings.getBounds() != original) { - int topOverlap = layerBounds.fBottom - original.fTop; - int bottomOverlap = original.fBottom - layerBounds.fTop; - int leftOverlap = layerBounds.fRight - original.fLeft; - int rightOverlap = original.fRight - layerBounds.fLeft; - if (direction & UP_DOWN) { - if (layerBounds.fLeft < original.fLeft && leftOverlap < 0) - scroll->setX(leftOverlap); - if (original.fRight < layerBounds.fRight && rightOverlap > 0 - && -leftOverlap > rightOverlap) - scroll->setX(rightOverlap); - bool topSet = scrollY > topOverlap && (direction == UP - || !scrollY); - if (topSet) - scroll->setY(topOverlap); - if (scrollY < bottomOverlap && (direction == DOWN || (!scrollY - && (!topSet || -topOverlap > bottomOverlap)))) - scroll->setY(bottomOverlap); - } else { - if (layerBounds.fTop < original.fTop && topOverlap < 0) - scroll->setY(topOverlap); - if (original.fBottom < layerBounds.fBottom && bottomOverlap > 0 - && -topOverlap > bottomOverlap) - scroll->setY(bottomOverlap); - bool leftSet = scrollX > leftOverlap && (direction == LEFT - || !scrollX); - if (leftSet) - scroll->setX(leftOverlap); - if (scrollX < rightOverlap && (direction == RIGHT || (!scrollX - && (!leftSet || -leftOverlap > rightOverlap)))) - scroll->setX(rightOverlap); - } - DBG_NAV_LOGD("rings=(%d,%d,w=%d,h=%d) layers=(%d,%d,w=%d,h=%d)" - " scroll=(%d,%d)", - ringBounds.fLeft, ringBounds.fTop, ringBounds.width(), ringBounds.height(), - layerBounds.fLeft, layerBounds.fTop, layerBounds.width(), layerBounds.height(), - scroll->x(), scroll->y()); - } -#endif - } - *framePtr = bestData.mFrame; - return const_cast<CachedNode*>(bestData.mNode); -} - -const CachedNode* CachedRoot::nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const -{ - bool startFound = false; - return CachedFrame::nextTextField(start, framePtr, &startFound); -} - -SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr, int* id) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (mRootLayer) { - const LayerAndroid* layer = mRootLayer->find(xPtr, yPtr, mPicture); - if (layer) { - SkPicture* picture = layer->picture(); - DBG_NAV_LOGD("layer %d picture=%p (%d,%d)", layer->uniqueId(), - picture, picture ? picture->width() : 0, - picture ? picture->height() : 0); - if (picture) { - if (id) - *id = layer->uniqueId(); - return picture; - } - } - } -#endif - DBG_NAV_LOGD("root mPicture=%p (%d,%d)", mPicture, mPicture ? - mPicture->width() : 0, mPicture ? mPicture->height() : 0); - if (id) - *id = -1; - return mPicture; -} - -void CachedRoot::reset() -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - mContents = mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mMaxXScroll = mMaxYScroll = 0; - mRootLayer = 0; - mSelectionStart = mSelectionEnd = -1; - mScrollOnly = false; -} - -bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, int* delta) -{ - switch (direction) { - case LEFT: - *delta = -mMaxXScroll; - return newOutset.x() >= mViewBounds.x(); - case RIGHT: - *delta = mMaxXScroll; - return newOutset.right() <= mViewBounds.right(); - case UP: - *delta = -mMaxYScroll; - return newOutset.y() >= mViewBounds.y(); - case DOWN: - *delta = mMaxYScroll; - return newOutset.bottom() <= mViewBounds.bottom(); - default: - *delta = 0; - ASSERT(0); - } - return false; -} - -void CachedRoot::setCachedFocus(CachedFrame* frame, CachedNode* node) -{ - mFocusBounds = WebCore::IntRect(0, 0, 0, 0); - if (node == NULL) - return; - node->setIsFocus(true); - mFocusBounds = node->bounds(frame); - frame->setFocusIndex(node - frame->document()); - CachedFrame* parent; - while ((parent = frame->parent()) != NULL) { - parent->setFocusIndex(frame->indexInParent()); - frame = parent; - } -#if DEBUG_NAV_UI - const CachedFrame* focusFrame; - const CachedNode* focus = currentFocus(&focusFrame); - WebCore::IntRect bounds = WebCore::IntRect(0, 0, 0, 0); - if (focus) - bounds = focus->bounds(focusFrame); - DBG_NAV_LOGD("new focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif -} - -void CachedRoot::setCursor(CachedFrame* frame, CachedNode* node) -{ -#if DEBUG_NAV_UI - const CachedFrame* cursorFrame; - const CachedNode* cursor = currentCursor(&cursorFrame); - WebCore::IntRect bounds; - if (cursor) - bounds = cursor->bounds(cursorFrame); - DBG_NAV_LOGD("old cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif - clearCursor(); - if (node == NULL) - return; - node->setIsCursor(true); - node->show(); - frame->setCursorIndex(node - frame->document()); - CachedFrame* parent; - while ((parent = frame->parent()) != NULL) { - parent->setCursorIndex(frame->indexInParent()); - frame = parent; - } -#if DEBUG_NAV_UI - cursor = currentCursor(&cursorFrame); - bounds = WebCore::IntRect(0, 0, 0, 0); - if (cursor) - bounds = cursor->bounds(cursorFrame); - DBG_NAV_LOGD("new cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif -} - -void CachedRoot::setCursorCache(int scrollX, int scrollY) const -{ - mCursor = currentCursor(); - if (mCursor) - mCursorBounds = mCursor->bounds(this); - if (!mRootLayer) - return; - SkRegion baseScrolled(mScrolledBounds); - mBaseUncovered = SkRegion(mScrolledBounds); -#if USE(ACCELERATED_COMPOSITING) -#if DUMP_NAV_CACHE - CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif - SkTDArray<SkRect> region; - mRootLayer->clipArea(®ion); - WebCore::IntSize offset( - copysign(min(max(0, mContents.width() - mScrolledBounds.width()), - abs(scrollX)), scrollX), - copysign(min(max(0, mContents.height() - mScrolledBounds.height()), - abs(scrollY)), scrollY)); - bool hasOffset = offset.width() || offset.height(); - // restrict scrollBounds to that which is not under layer - for (int index = 0; index < region.count(); index++) { - SkIRect less; - region[index].round(&less); - DBG_NAV_LOGD("less=(%d,%d,w=%d,h=%d)", less.fLeft, less.fTop, - less.width(), less.height()); - mBaseUncovered.op(less, SkRegion::kDifference_Op); - if (!hasOffset) - continue; - less.offset(offset.width(), offset.height()); - baseScrolled.op(less, SkRegion::kDifference_Op); - } - if (hasOffset) - mBaseUncovered.op(baseScrolled, SkRegion::kUnion_Op); -#endif -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedRoot* CachedRoot::Debug::base() const { - CachedRoot* nav = (CachedRoot*) ((char*) this - OFFSETOF(CachedRoot, mDebug)); - return nav; -} - -void CachedRoot::Debug::print() const -{ -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gWriteLogMutex.lock(); - ASSERT(gNavCacheLogFile == NULL); - gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a"); -#endif - CachedRoot* b = base(); - b->CachedFrame::mDebug.print(); - b->mHistory->mDebug.print(b); - DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n", - b->mMaxXScroll, b->mMaxYScroll); - if (b->mRootLayer) - CachedLayer::Debug::printRootLayerAndroid(b->mRootLayer); -#ifdef DUMP_NAV_CACHE_USING_PRINTF - if (gNavCacheLogFile) - fclose(gNavCacheLogFile); - gNavCacheLogFile = NULL; - gWriteLogMutex.unlock(); -#endif -} - -#endif - -} diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h deleted file mode 100644 index 1f8b851..0000000 --- a/WebKit/android/nav/CachedRoot.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2007, 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 CachedRoot_H -#define CachedRoot_H - -#include "CachedFrame.h" -#include "IntRect.h" -#include "SkPicture.h" -#include "SkRegion.h" -#include "wtf/Vector.h" - -class SkRect; - -namespace WebCore { - class LayerAndroid; -} - -namespace android { - -class CachedHistory; -class CachedNode; -class FindCanvas; - -class CachedRoot : public CachedFrame { -public: - bool adjustForScroll(BestData* , Direction , WebCore::IntPoint* scrollPtr, - bool findClosest); - const SkRegion& baseUncovered() const { return mBaseUncovered; } - void calcBitBounds(const IntRect& , IntRect* ) const; - int checkForCenter(int x, int y) const; - void checkForJiggle(int* ) const; - bool checkRings(SkPicture* , const CachedNode* , - const WebCore::IntRect& testBounds) const; - WebCore::IntPoint cursorLocation() const; - int documentHeight() { return mContents.height(); } - int documentWidth() { return mContents.width(); } - void draw(FindCanvas& ) const; - const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , - int* x, int* y, bool checkForHidden) const; - const WebCore::IntRect& focusBounds() const { return mFocusBounds; } - WebCore::IntPoint focusLocation() const; - int getAndResetSelectionEnd(); - int getAndResetSelectionStart(); - int getBlockLeftEdge(int x, int y, float scale) const; - void getSimulatedMousePosition(WebCore::IntPoint* ) const; - void init(WebCore::Frame* , CachedHistory* ); - bool innerDown(const CachedNode* , BestData* ) const; - bool innerLeft(const CachedNode* , BestData* ) const; - void innerMove(const CachedNode* ,BestData* bestData, Direction , - WebCore::IntPoint* scroll, bool firstCall); - bool innerRight(const CachedNode* , BestData* ) const; - bool innerUp(const CachedNode* , BestData* ) const; - WTF::String imageURI(int x, int y) const; - bool maskIfHidden(BestData* ) const; - const CachedNode* moveCursor(Direction , const CachedFrame** , WebCore::IntPoint* scroll); - /** - * Find the next textfield/textarea - * @param start The textfield/textarea to search from. - * @param framePtr If non-zero, returns CachedFrame* containing result. - * @return CachedNode* Next textfield/textarea or null (0) if none. - */ - const CachedNode* nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const; - SkPicture* pictureAt(int* xPtr, int* yPtr, int* id) const; - SkPicture* pictureAt(int* xPtr, int* yPtr) const { - return pictureAt(xPtr, yPtr, 0); } - void reset(); - CachedHistory* rootHistory() const { return mHistory; } - const WebCore::LayerAndroid* rootLayer() const { return mRootLayer; } - bool scrollDelta(WebCore::IntRect& cursorRingBounds, Direction , int* delta); - const WebCore::IntRect& scrolledBounds() const { return mScrolledBounds; } - void setCursor(CachedFrame* , CachedNode* ); - void setCursorCache(int scrollX, int scrollY) const; // compute cached state used to find next cursor - void setCachedFocus(CachedFrame* , CachedNode* ); - void setFocusBounds(const WebCore::IntRect& r) { mFocusBounds = r; } - void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; } - void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; } - void setPicture(SkPicture* picture) { mPicture = picture; } - void setRootLayer(WebCore::LayerAndroid* layer) { - mRootLayer = layer; - resetLayers(); - } - void setScrollOnly(bool state) { mScrollOnly = state; } - void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; } - void setupScrolledBounds() const { mScrolledBounds = mViewBounds; } - void setVisibleRect(const WebCore::IntRect& r) { mViewBounds = r; } - int textGeneration() const { return mTextGeneration; } - int width() const { return mPicture ? mPicture->width() : 0; } -private: - friend class CachedFrame; - CachedHistory* mHistory; - SkPicture* mPicture; - WebCore::LayerAndroid* mRootLayer; - WebCore::IntRect mFocusBounds; // dom text input focus node bounds - mutable WebCore::IntRect mScrolledBounds; // view bounds + amount visible as result of scroll - int mTextGeneration; - int mMaxXScroll; - int mMaxYScroll; - // These two are ONLY used when the tree is rebuilt and the focus is a textfield/area - int mSelectionStart; - int mSelectionEnd; - // these four set up as cache for use by frameDown/Up/Left/Right etc - mutable WebCore::IntRect mCursorBounds; - mutable const CachedNode* mCursor; - mutable SkRegion mBaseUncovered; - bool mScrollOnly; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedRoot* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/WebKit/android/nav/DrawExtra.h b/WebKit/android/nav/DrawExtra.h deleted file mode 100644 index 6716a65..0000000 --- a/WebKit/android/nav/DrawExtra.h +++ /dev/null @@ -1,48 +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 DrawExtra_h -#define DrawExtra_h - -class SkCanvas; - -namespace WebCore { - class IntRect; - class LayerAndroid; -} - -using namespace WebCore; - -namespace android { - -class DrawExtra { -public: - virtual ~DrawExtra() {} - virtual void draw(SkCanvas* , LayerAndroid* , IntRect* ) = 0; -}; - -} - -#endif diff --git a/WebKit/android/nav/FindCanvas.cpp b/WebKit/android/nav/FindCanvas.cpp deleted file mode 100644 index 2d310b3..0000000 --- a/WebKit/android/nav/FindCanvas.cpp +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright 2008, 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 "webviewglue" - -#include "config.h" -#include "FindCanvas.h" -#include "LayerAndroid.h" -#include "IntRect.h" -#include "SelectText.h" -#include "SkBlurMaskFilter.h" -#include "SkCornerPathEffect.h" -#include "SkRect.h" -#include "SkUtils.h" - -#include <utils/Log.h> - -#define INTEGER_OUTSET 2 - -namespace android { - -// MatchInfo methods -//////////////////////////////////////////////////////////////////////////////// - -MatchInfo::MatchInfo() { - m_picture = 0; -} - -MatchInfo::~MatchInfo() { - SkSafeUnref(m_picture); -} - -MatchInfo::MatchInfo(const MatchInfo& src) { - m_layerId = src.m_layerId; - m_location = src.m_location; - m_picture = src.m_picture; - SkSafeRef(m_picture); -} - -void MatchInfo::set(const SkRegion& region, SkPicture* pic, int layerId) { - SkSafeUnref(m_picture); - m_layerId = layerId; - m_location = region; - m_picture = pic; - SkASSERT(pic); - pic->ref(); -} - -// GlyphSet methods -//////////////////////////////////////////////////////////////////////////////// - -GlyphSet::GlyphSet(const SkPaint& paint, const UChar* lower, const UChar* upper, - size_t byteLength) { - SkPaint clonePaint(paint); - clonePaint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - mTypeface = paint.getTypeface(); - mCount = clonePaint.textToGlyphs(lower, byteLength, NULL); - if (mCount > MAX_STORAGE_COUNT) { - mLowerGlyphs = new uint16_t[2*mCount]; - } else { - mLowerGlyphs = &mStorage[0]; - } - // Use one array, and have mUpperGlyphs point to a portion of it, - // so that we can reduce the number of new/deletes - mUpperGlyphs = mLowerGlyphs + mCount; - int count2 = clonePaint.textToGlyphs(lower, byteLength, mLowerGlyphs); - SkASSERT(mCount == count2); - count2 = clonePaint.textToGlyphs(upper, byteLength, mUpperGlyphs); - SkASSERT(mCount == count2); -} - -GlyphSet::~GlyphSet() { - // Do not need to delete mTypeface, which is not owned by us. - if (mCount > MAX_STORAGE_COUNT) { - delete[] mLowerGlyphs; - } // Otherwise, we just used local storage space, so no need to delete - // Also do not need to delete mUpperGlyphs, which simply points to a - // part of mLowerGlyphs -} - -GlyphSet& GlyphSet::operator=(GlyphSet& src) { - mTypeface = src.mTypeface; - mCount = src.mCount; - if (mCount > MAX_STORAGE_COUNT) { - mLowerGlyphs = new uint16_t[2*mCount]; - } else { - mLowerGlyphs = &mStorage[0]; - } - memcpy(mLowerGlyphs, src.mLowerGlyphs, 2*mCount*sizeof(uint16_t)); - mUpperGlyphs = mLowerGlyphs + mCount; - return *this; -} - -bool GlyphSet::characterMatches(uint16_t c, int index) { - SkASSERT(index < mCount && index >= 0); - return c == mLowerGlyphs[index] || c == mUpperGlyphs[index]; -} - -// FindCanvas methods -//////////////////////////////////////////////////////////////////////////////// - -FindCanvas::FindCanvas(int width, int height, const UChar* lower, - const UChar* upper, size_t byteLength) - : mLowerText(lower) - , mUpperText(upper) - , mLength(byteLength) - , mNumFound(0) { - // the text has been provided in read order. Reverse as needed so the - // result contains left-to-right characters. - const uint16_t* start = mLowerText; - size_t count = byteLength >> 1; - const uint16_t* end = mLowerText + count; - while (start < end) { - SkUnichar ch = SkUTF16_NextUnichar(&start); - WTF::Unicode::Direction charDirection = WTF::Unicode::direction(ch); - if (WTF::Unicode::RightToLeftArabic == charDirection - || WTF::Unicode::RightToLeft == charDirection) { - mLowerReversed.clear(); - mLowerReversed.append(mLowerText, count); - WebCore::ReverseBidi(mLowerReversed.begin(), count); - mLowerText = mLowerReversed.begin(); - mUpperReversed.clear(); - mUpperReversed.append(mUpperText, count); - WebCore::ReverseBidi(mUpperReversed.begin(), count); - mUpperText = mUpperReversed.begin(); - break; - } - } - - setBounder(&mBounder); - mOutset = -SkIntToScalar(INTEGER_OUTSET); - mMatches = new WTF::Vector<MatchInfo>(); - mWorkingIndex = 0; - mWorkingCanvas = 0; - mWorkingPicture = 0; -} - -FindCanvas::~FindCanvas() { - setBounder(NULL); - /* Just in case getAndClear was not called. */ - delete mMatches; - SkSafeUnref(mWorkingPicture); -} - -// Each version of addMatch returns a rectangle for a match. -// Not all of the parameters are used by each version. -SkRect FindCanvas::addMatchNormal(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar pos[], SkScalar y) { - const uint16_t* lineStart = glyphs - index; - /* Use the original paint, since "text" is in glyphs */ - SkScalar before = paint.measureText(lineStart, index * sizeof(uint16_t), 0); - SkRect rect; - rect.fLeft = pos[0] + before; - int countInBytes = count * sizeof(uint16_t); - rect.fRight = paint.measureText(glyphs, countInBytes, 0) + rect.fLeft; - SkPaint::FontMetrics fontMetrics; - paint.getFontMetrics(&fontMetrics); - SkScalar baseline = y; - rect.fTop = baseline + fontMetrics.fAscent; - rect.fBottom = baseline + fontMetrics.fDescent; - const SkMatrix& matrix = getTotalMatrix(); - matrix.mapRect(&rect); - // Add the text to our picture. - SkCanvas* canvas = getWorkingCanvas(); - int saveCount = canvas->save(); - canvas->concat(matrix); - canvas->drawText(glyphs, countInBytes, pos[0] + before, y, paint); - canvas->restoreToCount(saveCount); - return rect; -} - -SkRect FindCanvas::addMatchPos(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar xPos[], SkScalar /* y */) { - SkRect r; - r.setEmpty(); - const SkPoint* temp = reinterpret_cast<const SkPoint*> (xPos); - const SkPoint* points = &temp[index]; - int countInBytes = count * sizeof(uint16_t); - SkPaint::FontMetrics fontMetrics; - paint.getFontMetrics(&fontMetrics); - // Need to check each character individually, since the heights may be - // different. - for (int j = 0; j < count; j++) { - SkRect bounds; - bounds.fLeft = points[j].fX; - bounds.fRight = bounds.fLeft + - paint.measureText(&glyphs[j], sizeof(uint16_t), 0); - SkScalar baseline = points[j].fY; - bounds.fTop = baseline + fontMetrics.fAscent; - bounds.fBottom = baseline + fontMetrics.fDescent; - /* Accumulate and then add the resulting rect to mMatches */ - r.join(bounds); - } - SkMatrix matrix = getTotalMatrix(); - matrix.mapRect(&r); - SkCanvas* canvas = getWorkingCanvas(); - int saveCount = canvas->save(); - canvas->concat(matrix); - canvas->drawPosText(glyphs, countInBytes, points, paint); - canvas->restoreToCount(saveCount); - return r; -} - -SkRect FindCanvas::addMatchPosH(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar position[], SkScalar constY) { - SkRect r; - // We only care about the positions starting at the index of our match - const SkScalar* xPos = &position[index]; - // This assumes that the position array is monotonic increasing - // The left bounds will be the position of the left most character - r.fLeft = xPos[0]; - // The right bounds will be the position of the last character plus its - // width - int lastIndex = count - 1; - r.fRight = paint.measureText(&glyphs[lastIndex], sizeof(uint16_t), 0) - + xPos[lastIndex]; - // Grab font metrics to determine the top and bottom of the bounds - SkPaint::FontMetrics fontMetrics; - paint.getFontMetrics(&fontMetrics); - r.fTop = constY + fontMetrics.fAscent; - r.fBottom = constY + fontMetrics.fDescent; - const SkMatrix& matrix = getTotalMatrix(); - matrix.mapRect(&r); - SkCanvas* canvas = getWorkingCanvas(); - int saveCount = canvas->save(); - canvas->concat(matrix); - canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), xPos, constY, paint); - canvas->restoreToCount(saveCount); - return r; -} - -void FindCanvas::drawLayers(LayerAndroid* layer) { -#if USE(ACCELERATED_COMPOSITING) - SkPicture* picture = layer->picture(); - if (picture) { - setLayerId(layer->uniqueId()); - drawPicture(*picture); - } - for (int i = 0; i < layer->countChildren(); i++) - drawLayers(layer->getChild(i)); -#endif -} - -void FindCanvas::drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - findHelper(text, byteLength, paint, &x, y, &FindCanvas::addMatchNormal); -} - -void FindCanvas::drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - // Pass in the first y coordinate for y so that we can check to see whether - // it is lower than the last draw call (to check if we are continuing to - // another line). - findHelper(text, byteLength, paint, (const SkScalar*) pos, pos[0].fY, - &FindCanvas::addMatchPos); -} - -void FindCanvas::drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - findHelper(text, byteLength, paint, xpos, constY, - &FindCanvas::addMatchPosH); -} - -/* The current behavior is to skip substring matches. This means that in the - * string - * batbatbat - * a search for - * batbat - * will return 1 match. If the desired behavior is to return 2 matches, define - * INCLUDE_SUBSTRING_MATCHES to be 1. - */ -#define INCLUDE_SUBSTRING_MATCHES 0 - -// Need a quick way to know a maximum distance between drawText calls to know if -// they are part of the same logical phrase when searching. By crude -// inspection, half the point size seems a good guess at the width of a space -// character. -static inline SkScalar approximateSpaceWidth(const SkPaint& paint) { - return SkScalarHalf(paint.getTextSize()); -} - -void FindCanvas::findHelper(const void* text, size_t byteLength, - const SkPaint& paint, const SkScalar positions[], - SkScalar y, - SkRect (FindCanvas::*addMatch)(int index, - const SkPaint& paint, int count, - const uint16_t* glyphs, - const SkScalar positions[], SkScalar y)) { - SkASSERT(paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding); - SkASSERT(mMatches); - GlyphSet* glyphSet = getGlyphs(paint); - const int count = glyphSet->getCount(); - int numCharacters = byteLength >> 1; - const uint16_t* chars = (const uint16_t*) text; - // This block will check to see if we are continuing from another line. If - // so, the user needs to have added a space, which we do not draw. - if (mWorkingIndex) { - SkPoint newY; - getTotalMatrix().mapXY(0, y, &newY); - SkIRect workingBounds = mWorkingRegion.getBounds(); - int newYInt = SkScalarRound(newY.fY); - if (workingBounds.fTop > newYInt) { - // The new text is above the working region, so we know it's not - // a continuation. - resetWorkingCanvas(); - mWorkingIndex = 0; - mWorkingRegion.setEmpty(); - } else if (workingBounds.fBottom < newYInt) { - // Now we know that this line is lower than our partial match. - SkPaint clonePaint(paint); - clonePaint.setTextEncoding(SkPaint::kUTF8_TextEncoding); - uint16_t space; - clonePaint.textToGlyphs(" ", 1, &space); - if (glyphSet->characterMatches(space, mWorkingIndex)) { - mWorkingIndex++; - if (mWorkingIndex == count) { - // We already know that it is not clipped out because we - // checked for that before saving the working region. - insertMatchInfo(mWorkingRegion); - - resetWorkingCanvas(); - mWorkingIndex = 0; - mWorkingRegion.setEmpty(); - // We have found a match, so continue on this line from - // scratch. - } - } else { - resetWorkingCanvas(); - mWorkingIndex = 0; - mWorkingRegion.setEmpty(); - } - } - // If neither one is true, then we are likely continuing on the same - // line, but are in a new draw call because the paint has changed. In - // this case, we can continue without adding a space. - } - // j is the position in the search text - // Start off with mWorkingIndex in case we are continuing from a prior call - int j = mWorkingIndex; - // index is the position in the drawn text - int index = 0; - for ( ; index != numCharacters; index++) { - if (glyphSet->characterMatches(chars[index], j)) { - // The jth character in the search text matches the indexth position - // in the drawn text, so increase j. - j++; - if (j != count) { - continue; - } - // The last count characters match, so we found the entire - // search string. - int remaining = count - mWorkingIndex; - int matchIndex = index - remaining + 1; - // Set up a pointer to the matching text in 'chars'. - const uint16_t* glyphs = chars + matchIndex; - SkRect rect = (this->*addMatch)(matchIndex, paint, - remaining, glyphs, positions, y); - // We need an SkIRect for SkRegion operations. - SkIRect iRect; - rect.roundOut(&iRect); - // Want to outset the drawn rectangle by the same amount as - // mOutset - iRect.inset(-INTEGER_OUTSET, -INTEGER_OUTSET); - SkRegion regionToAdd(iRect); - if (!mWorkingRegion.isEmpty()) { - // If this is on the same line as our working region, make - // sure that they are close enough together that they are - // supposed to be part of the same text string. - // The width of two spaces has arbitrarily been chosen. - const SkIRect& workingBounds = mWorkingRegion.getBounds(); - if (workingBounds.fTop <= iRect.fBottom && - workingBounds.fBottom >= iRect.fTop && - SkIntToScalar(iRect.fLeft - workingBounds.fRight) > - approximateSpaceWidth(paint)) { - index = -1; // Will increase to 0 on next run - // In this case, we need to start from the beginning of - // the text being searched and our search term. - j = 0; - mWorkingIndex = 0; - mWorkingRegion.setEmpty(); - continue; - } - // Add the mWorkingRegion, which contains rectangles from - // the previous line(s). - regionToAdd.op(mWorkingRegion, SkRegion::kUnion_Op); - } - insertMatchInfo(regionToAdd); -#if INCLUDE_SUBSTRING_MATCHES - // Reset index to the location of the match and reset j to the - // beginning, so that on the next iteration of the loop, index - // will advance by 1 and we will compare the next character in - // chars to the first character in the GlyphSet. - index = matchIndex; -#endif - // Whether the clip contained it or not, we need to start over - // with our recording canvas - resetWorkingCanvas(); - } else { - // Index needs to be set to index - j + 1. - // This is a ridiculous case, but imagine the situation where the - // user is looking for the string "jjog" in the drawText call for - // "jjjog". The first two letters match. However, when the index - // is 2, and we discover that 'o' and 'j' do not match, we should go - // back to 1, where we do, in fact, have a match - // FIXME: This does not work if (as in our example) "jj" is in one - // draw call and "jog" is in the next. Doing so would require a - // stack, keeping track of multiple possible working indeces and - // regions. This is likely an uncommon case. - index = index - j; // index will be increased by one on the next - // iteration - } - // We reach here in one of two cases: - // 1) We just completed a match, so any working rectangle/index is no - // longer needed, and we will start over from the beginning - // 2) The glyphs do not match, so we start over at the beginning of - // the search string. - j = 0; - mWorkingIndex = 0; - mWorkingRegion.setEmpty(); - } - // At this point, we have searched all of the text in the current drawText - // call. - // Keep track of a partial match that may start on this line. - if (j > 0) { // if j is greater than 0, we have a partial match - int relativeCount = j - mWorkingIndex; // Number of characters in this - // part of the match. - int partialIndex = index - relativeCount; // Index that starts our - // partial match. - const uint16_t* partialGlyphs = chars + partialIndex; - SkRect partial = (this->*addMatch)(partialIndex, paint, relativeCount, - partialGlyphs, positions, y); - partial.inset(mOutset, mOutset); - SkIRect dest; - partial.roundOut(&dest); - mWorkingRegion.op(dest, SkRegion::kUnion_Op); - mWorkingIndex = j; - return; - } - // This string doesn't go into the next drawText, so reset our working - // variables - mWorkingRegion.setEmpty(); - mWorkingIndex = 0; -} - -SkCanvas* FindCanvas::getWorkingCanvas() { - if (!mWorkingPicture) { - mWorkingPicture = new SkPicture; - mWorkingCanvas = mWorkingPicture->beginRecording(0,0); - } - return mWorkingCanvas; -} - -GlyphSet* FindCanvas::getGlyphs(const SkPaint& paint) { - SkTypeface* typeface = paint.getTypeface(); - GlyphSet* end = mGlyphSets.end(); - for (GlyphSet* ptr = mGlyphSets.begin();ptr != end; ptr++) { - if (ptr->getTypeface() == typeface) { - return ptr; - } - } - - GlyphSet set(paint, mLowerText, mUpperText, mLength); - *mGlyphSets.append() = set; - return &(mGlyphSets.top()); -} - -void FindCanvas::insertMatchInfo(const SkRegion& region) { - mNumFound++; - mWorkingPicture->endRecording(); - MatchInfo matchInfo; - mMatches->append(matchInfo); - LOGD("%s region=%p pict=%p layer=%d", __FUNCTION__, - ®ion, mWorkingPicture, mLayerId); - mMatches->last().set(region, mWorkingPicture, mLayerId); -} - -void FindCanvas::resetWorkingCanvas() { - mWorkingPicture->unref(); - mWorkingPicture = 0; - // Do not need to reset mWorkingCanvas itself because we only access it via - // getWorkingCanvas. -} - -// This function sets up the paints that are used to draw the matches. -void FindOnPage::setUpFindPaint() { - // Set up the foreground paint - m_findPaint.setAntiAlias(true); - const SkScalar roundiness = SkIntToScalar(2); - SkCornerPathEffect* cornerEffect = new SkCornerPathEffect(roundiness); - m_findPaint.setPathEffect(cornerEffect); - m_findPaint.setARGB(255, 132, 190, 0); - - // Set up the background blur paint. - m_findBlurPaint.setAntiAlias(true); - m_findBlurPaint.setARGB(204, 0, 0, 0); - m_findBlurPaint.setPathEffect(cornerEffect); - cornerEffect->unref(); - SkMaskFilter* blurFilter = SkBlurMaskFilter::Create(SK_Scalar1, - SkBlurMaskFilter::kNormal_BlurStyle); - m_findBlurPaint.setMaskFilter(blurFilter)->unref(); - m_isFindPaintSetUp = true; -} - -IntRect FindOnPage::currentMatchBounds() const { - IntRect noBounds = IntRect(0, 0, 0, 0); - if (!m_matches || !m_matches->size()) - return noBounds; - MatchInfo& info = (*m_matches)[m_findIndex]; - // FIXME: this should test if the match in the layer is visible - if (info.isInLayer()) - return noBounds; - return info.getLocation().getBounds(); -} - -bool FindOnPage::currentMatchIsInLayer() const { - if (!m_matches || !m_matches->size()) - return false; - MatchInfo& info = (*m_matches)[m_findIndex]; - return info.isInLayer(); -} - -// This function is only used by findNext and setMatches. In it, we store -// upper left corner of the match specified by m_findIndex in -// m_currentMatchLocation. -void FindOnPage::storeCurrentMatchLocation() { - SkASSERT(m_findIndex < m_matches->size()); - const SkIRect& bounds = (*m_matches)[m_findIndex].getLocation().getBounds(); - m_currentMatchLocation.set(bounds.fLeft, bounds.fTop); - m_hasCurrentLocation = true; -} - -// Put a cap on the number of matches to draw. If the current page has more -// matches than this, only draw the focused match. -#define MAX_NUMBER_OF_MATCHES_TO_DRAW 101 - -void FindOnPage::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval) { - if (!m_lastBounds.isEmpty()) { - inval->unite(m_lastBounds); - m_lastBounds.setEmpty(); - } - if (!m_hasCurrentLocation || !m_matches || !m_matches->size()) - return; - int layerId = layer->uniqueId(); - if (m_findIndex >= m_matches->size()) - m_findIndex = 0; - const MatchInfo& matchInfo = (*m_matches)[m_findIndex]; - const SkRegion& currentMatchRegion = matchInfo.getLocation(); - - // Set up the paints used for drawing the matches - if (!m_isFindPaintSetUp) - setUpFindPaint(); - - // Draw the current match - if (matchInfo.layerId() == layerId) { - drawMatch(currentMatchRegion, canvas, true); - // Now draw the picture, so that it shows up on top of the rectangle - int saveCount = canvas->save(); - SkPath matchPath; - currentMatchRegion.getBoundaryPath(&matchPath); - canvas->clipPath(matchPath); - canvas->drawPicture(*matchInfo.getPicture()); - canvas->restoreToCount(saveCount); - const SkMatrix& matrix = canvas->getTotalMatrix(); - const SkRect& localBounds = matchPath.getBounds(); - SkRect globalBounds; - matrix.mapRect(&globalBounds, localBounds); - globalBounds.round(&m_lastBounds); - inval->unite(m_lastBounds); - } - // Draw the rest - unsigned numberOfMatches = m_matches->size(); - if (numberOfMatches > 1 - && numberOfMatches < MAX_NUMBER_OF_MATCHES_TO_DRAW) { - for(unsigned i = 0; i < numberOfMatches; i++) { - // The current match has already been drawn - if (i == m_findIndex) - continue; - if ((*m_matches)[i].layerId() != layerId) - continue; - const SkRegion& region = (*m_matches)[i].getLocation(); - // Do not draw matches which intersect the current one, or if it is - // offscreen - if (currentMatchRegion.intersects(region)) - continue; - SkRect bounds; - bounds.set(region.getBounds()); - if (canvas->quickReject(bounds, SkCanvas::kAA_EdgeType)) - continue; - drawMatch(region, canvas, false); - } - } -} - -// Draw the match specified by region to the canvas. -void FindOnPage::drawMatch(const SkRegion& region, SkCanvas* canvas, - bool focused) -{ - // For the match which has focus, use a filled paint. For the others, use - // a stroked paint. - if (focused) { - m_findPaint.setStyle(SkPaint::kFill_Style); - m_findBlurPaint.setStyle(SkPaint::kFill_Style); - } else { - m_findPaint.setStyle(SkPaint::kStroke_Style); - m_findPaint.setStrokeWidth(SK_Scalar1); - m_findBlurPaint.setStyle(SkPaint::kStroke_Style); - m_findBlurPaint.setStrokeWidth(SkIntToScalar(2)); - } - // Find the path for the current match - SkPath matchPath; - region.getBoundaryPath(&matchPath); - // Offset the path for a blurred shadow - SkPath blurPath; - matchPath.offset(SK_Scalar1, SkIntToScalar(2), &blurPath); - int saveCount = 0; - if (!focused) { - saveCount = canvas->save(); - canvas->clipPath(matchPath, SkRegion::kDifference_Op); - } - // Draw the blurred background - canvas->drawPath(blurPath, m_findBlurPaint); - if (!focused) - canvas->restoreToCount(saveCount); - // Draw the foreground - canvas->drawPath(matchPath, m_findPaint); -} - -void FindOnPage::findNext(bool forward) -{ - if (!m_matches || !m_matches->size() || !m_hasCurrentLocation) - return; - if (forward) { - m_findIndex++; - if (m_findIndex == m_matches->size()) - m_findIndex = 0; - } else { - if (m_findIndex == 0) { - m_findIndex = m_matches->size() - 1; - } else { - m_findIndex--; - } - } - storeCurrentMatchLocation(); -} - -// With this call, WebView takes ownership of matches, and is responsible for -// deleting it. -void FindOnPage::setMatches(WTF::Vector<MatchInfo>* matches) -{ - if (m_matches) - delete m_matches; - m_matches = matches; - if (m_matches->size()) { - if (m_hasCurrentLocation) { - for (unsigned i = 0; i < m_matches->size(); i++) { - const SkIRect& rect = (*m_matches)[i].getLocation().getBounds(); - if (rect.fLeft == m_currentMatchLocation.fX - && rect.fTop == m_currentMatchLocation.fY) { - m_findIndex = i; - return; - } - } - } - // If we did not have a stored location, or if we were unable to restore - // it, store the new one. - m_findIndex = 0; - storeCurrentMatchLocation(); - } else { - m_hasCurrentLocation = false; - } -} - -} diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h deleted file mode 100644 index 76ee1e2..0000000 --- a/WebKit/android/nav/FindCanvas.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright 2008, 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 Find_Canvas_h -#define Find_Canvas_h - -#include "DrawExtra.h" -#include "IntRect.h" -#include "SkBounder.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "SkTDArray.h" - -#include <unicode/umachine.h> -#include <wtf/Vector.h> - -namespace android { - -// Stores both region information and an SkPicture of the match, so that the -// region can be drawn, followed by drawing the matching text on top of it. -// This class owns its SkPicture -class MatchInfo { -public: - MatchInfo(); - ~MatchInfo(); - MatchInfo(const MatchInfo& src); - const SkRegion& getLocation() const { return m_location; } - // Return a pointer to our picture, representing the matching text. Does - // not transfer ownership of the picture. - SkPicture* getPicture() const { return m_picture; } - // This will make a copy of the region, and increase the ref count on the - // SkPicture. If this MatchInfo already had one, unref it. - bool isInLayer() const { return m_layerId >= 0; } - int layerId() const { return m_layerId; } - void set(const SkRegion& region, SkPicture* pic, int layerId); -private: - MatchInfo& operator=(MatchInfo& src); - SkRegion m_location; - SkPicture* m_picture; - int m_layerId; -}; - -// A class containing a typeface for reference, the length in glyphs, and -// the upper and lower case representations of the search string. -class GlyphSet { -public: - GlyphSet(const SkPaint& paint, const UChar* lower, const UChar* upper, - size_t byteLength); - ~GlyphSet(); - GlyphSet& operator=(GlyphSet& src); - - // Return true iff c matches one of our glyph arrays at index - bool characterMatches(uint16_t c, int index); - - int getCount() const { return mCount; } - - const SkTypeface* getTypeface() const { return mTypeface; } - -private: - // Disallow copy constructor - GlyphSet(GlyphSet& src) { } - - // mTypeface is used for comparison only - const SkTypeface* mTypeface; - // mLowerGlyphs points to all of our storage space: the lower set followed - // by the upper set. mUpperGlyphs is purely a convenience pointer to the - // start of the upper case glyphs. - uint16_t* mLowerGlyphs; - uint16_t* mUpperGlyphs; - // mCount is the number of glyphs of the search string. Must be the same - // for both the lower case set and the upper case set. - int mCount; - - // Arbitrarily chose the maximum storage to use in the GlyphSet. This is - // based on the length of the word being searched. If users are always - // searching for 3 letter words (for example), an ideal number would be 3. - // Each time the user searches for a word longer than (in this case, 3) that - // will result in calling new/delete. - enum Storage { - MAX_STORAGE_COUNT = 16 - }; - // In order to eliminate new/deletes, create storage that will be enough - // most of the time - uint16_t mStorage[2*MAX_STORAGE_COUNT]; -}; - -class FindBounder : public SkBounder { -public: - FindBounder() {} - ~FindBounder() {} -protected: - virtual bool onIRect(const SkIRect&) { return false; } -}; - -class FindCanvas : public SkCanvas { -public: - FindCanvas(int width, int height, const UChar* , const UChar*, - size_t byteLength); - - virtual ~FindCanvas(); - - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint); - - /* FIXME: This path has not been tested. */ - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint); - - /* Also untested */ - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint); - - /* Not sure what to do here or for drawTextOnPathHV */ - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - } - - void drawLayers(LayerAndroid* ); - int found() const { return mNumFound; } - void setLayerId(int layerId) { mLayerId = layerId; } - - // This method detaches our array of matches and passes ownership to - // the caller, who is then responsible for deleting them. - WTF::Vector<MatchInfo>* detachMatches() { - WTF::Vector<MatchInfo>* array = mMatches; - mMatches = NULL; - return array; - } - -private: - // These calls are made by findHelper to store information about each match - // that is found. They return a rectangle which is used to highlight the - // match. They also add to our SkPicture (which can be accessed with - // getDrawnMatches) a draw of each match. This way it can be drawn after - // the rectangle. The rect that is returned is in device coordinates. - SkRect addMatchNormal(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar pos[], SkScalar y); - - SkRect addMatchPos(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar xPos[], SkScalar /* y */); - - SkRect addMatchPosH(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar position[], SkScalar constY); - - // Helper for each of our draw calls - void findHelper(const void* text, size_t byteLength, const SkPaint& paint, - const SkScalar xPos[], SkScalar y, - SkRect (FindCanvas::*addMatch)(int index, - const SkPaint& paint, int count, const uint16_t* glyphs, - const SkScalar pos[], SkScalar y)); - - // If we already have a working canvas, grab it. Otherwise, create a new - // one. - SkCanvas* getWorkingCanvas(); - - // Return the set of glyphs and its count for the text being searched for - // and the parameter paint. If one has already been created and cached - // for this paint, use it. If not, create a new one and cache it. - GlyphSet* getGlyphs(const SkPaint& paint); - - // Store all the accumulated info about a match in our vector. - void insertMatchInfo(const SkRegion& region); - - // Throw away our cumulative information about our working SkCanvas. After - // this call, next call to getWorkingCanvas will create a new one. - void resetWorkingCanvas(); - - // Since we may transfer ownership of this array (see detachRects()), we - // hold a pointer to the array instead of just the array itself. - WTF::Vector<MatchInfo>* mMatches; - const UChar* mLowerText; - const UChar* mUpperText; - Vector<UChar> mLowerReversed; - Vector<UChar> mUpperReversed; - size_t mLength; - FindBounder mBounder; - int mNumFound; - SkScalar mOutset; - SkTDArray<GlyphSet> mGlyphSets; - - SkPicture* mWorkingPicture; - SkCanvas* mWorkingCanvas; - SkRegion mWorkingRegion; - int mWorkingIndex; - int mLayerId; -}; - -class FindOnPage : public DrawExtra { -public: - FindOnPage() { - m_matches = 0; - m_hasCurrentLocation = false; - m_isFindPaintSetUp = false; - m_lastBounds.setEmpty(); - } - virtual ~FindOnPage() { delete m_matches; } - void clearCurrentLocation() { m_hasCurrentLocation = false; } - IntRect currentMatchBounds() const; - int currentMatchIndex() const { return m_findIndex; } - bool currentMatchIsInLayer() const; - virtual void draw(SkCanvas* , LayerAndroid* , IntRect* ); - void findNext(bool forward); - bool isCurrentLocationValid() { return m_hasCurrentLocation; } - void setMatches(WTF::Vector<MatchInfo>* matches); -private: - void drawMatch(const SkRegion& region, SkCanvas* canvas, bool focused); - void setUpFindPaint(); - void storeCurrentMatchLocation(); - WTF::Vector<MatchInfo>* m_matches; - // Stores the location of the current match. - SkIPoint m_currentMatchLocation; - // Tells whether the value in m_currentMatchLocation is valid. - bool m_hasCurrentLocation; - // Tells whether we have done the setup to draw the Find matches. - bool m_isFindPaintSetUp; - // Paint used to draw our Find matches. - SkPaint m_findPaint; - // Paint used for the background of our Find matches. - SkPaint m_findBlurPaint; - unsigned m_findIndex; - SkIRect m_lastBounds; -}; - -} - -#endif // Find_Canvas_h diff --git a/WebKit/android/nav/ParseCanvas.h b/WebKit/android/nav/ParseCanvas.h deleted file mode 100644 index 9b7a889..0000000 --- a/WebKit/android/nav/ParseCanvas.h +++ /dev/null @@ -1,52 +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 PARSE_CANVAS_H -#define PARSE_CANVAS_H - -#include "SkCanvas.h" - -namespace android { - -class ParseCanvas : public SkCanvas { -protected: - virtual ~ParseCanvas() { - setBounder(0); - } - - // Pictures parsed for content never want to create offscreen bitmaps. - // Instead, just save and restore the canvas state -- this also keeps - // the picture contents at their original coordinates. - virtual int saveLayer(const SkRect* , const SkPaint* , SaveFlags flags) { - return INHERITED::save(flags); - } -private: - typedef SkCanvas INHERITED; -}; - -} - -#endif - diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp deleted file mode 100644 index f8ea799..0000000 --- a/WebKit/android/nav/SelectText.cpp +++ /dev/null @@ -1,1983 +0,0 @@ -/* - * Copyright 2008, 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 "webviewglue" - -#include "CachedPrefix.h" -#include "BidiResolver.h" -#include "CachedRoot.h" -#include "LayerAndroid.h" -#include "ParseCanvas.h" -#include "SelectText.h" -#include "SkBitmap.h" -#include "SkBounder.h" -#include "SkGradientShader.h" -#include "SkMatrix.h" -#include "SkPicture.h" -#include "SkPixelXorXfermode.h" -#include "SkPoint.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "SkUtils.h" -#include "TextRun.h" - -#ifdef DEBUG_NAV_UI -#include <wtf/text/CString.h> -#endif - -#define VERBOSE_LOGGING 0 -// #define EXTRA_NOISY_LOGGING 1 - -// TextRunIterator has been copied verbatim from GraphicsContext.cpp -namespace WebCore { - -class TextRunIterator { -public: - TextRunIterator() - : m_textRun(0) - , m_offset(0) - { - } - - TextRunIterator(const TextRun* textRun, unsigned offset) - : m_textRun(textRun) - , m_offset(offset) - { - } - - TextRunIterator(const TextRunIterator& other) - : m_textRun(other.m_textRun) - , m_offset(other.m_offset) - { - } - - unsigned offset() const { return m_offset; } - void increment() { m_offset++; } - bool atEnd() const { return !m_textRun || m_offset >= m_textRun->length(); } - UChar current() const { return (*m_textRun)[m_offset]; } - WTF::Unicode::Direction direction() const { return atEnd() ? WTF::Unicode::OtherNeutral : WTF::Unicode::direction(current()); } - - bool operator==(const TextRunIterator& other) - { - return m_offset == other.m_offset && m_textRun == other.m_textRun; - } - - bool operator!=(const TextRunIterator& other) { return !operator==(other); } - -private: - const TextRun* m_textRun; - int m_offset; -}; - -// ReverseBidi is a trimmed-down version of GraphicsContext::drawBidiText() -void ReverseBidi(UChar* chars, int len) { - using namespace WTF::Unicode; - WTF::Vector<UChar> result; - result.reserveCapacity(len); - TextRun run(chars, len); - BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; - bidiResolver.setStatus(BidiStatus(LeftToRight, LeftToRight, LeftToRight, - BidiContext::create(0, LeftToRight, false))); - bidiResolver.setPosition(TextRunIterator(&run, 0)); - bidiResolver.createBidiRunsForLine(TextRunIterator(&run, len)); - if (!bidiResolver.runCount()) - return; - BidiCharacterRun* bidiRun = bidiResolver.firstRun(); - while (bidiRun) { - int bidiStart = bidiRun->start(); - int bidiStop = bidiRun->stop(); - int size = result.size(); - int bidiCount = bidiStop - bidiStart; - result.append(chars + bidiStart, bidiCount); - if (bidiRun->level() % 2) { - UChar* start = &result[size]; - UChar* end = start + bidiCount; - // reverse the order of any RTL substrings - while (start < end) { - UChar temp = *start; - *start++ = *--end; - *end = temp; - } - start = &result[size]; - end = start + bidiCount - 1; - // if the RTL substring had a surrogate pair, restore its order - while (start < end) { - UChar trail = *start++; - if (!U16_IS_SURROGATE(trail)) - continue; - start[-1] = *start; // lead - *start++ = trail; - } - } - bidiRun = bidiRun->next(); - } - bidiResolver.deleteRuns(); - memcpy(chars, &result[0], len * sizeof(UChar)); -} - -} - -namespace android { - -#define HYPHEN_MINUS 0x2D // ASCII hyphen -#define SOLIDUS 0x2F // ASCII slash -#define REVERSE_SOLIDUS 0x5C // ASCII backslash -#define HYPHEN 0x2010 // unicode hyphen, first in range of dashes -#define HORZ_BAR 0x2015 // unicode horizontal bar, last in range of dashes -#define TOUCH_SLOP 10 // additional distance from character rect when hit - -class CommonCheck : public SkBounder { -public: - CommonCheck(const SkIRect& area) - : mArea(area) - , mLastUni(0) - { - mLastGlyph.fGlyphID = static_cast<uint16_t>(-1); - mLastCandidate.fGlyphID = static_cast<uint16_t>(-1); - mMatrix.reset(); - reset(); - } - - /* called only while the picture is parsed */ - int base() { - if (mBase == INT_MAX) { - SkPoint result; - mMatrix.mapXY(0, mY, &result); - mBase = SkScalarFloor(result.fY); - } - return mBase; - } - - /* called only while the picture is parsed */ - int bottom() { - if (mBottom == INT_MAX) { - SkPoint result; - SkPaint::FontMetrics metrics; - mPaint.getFontMetrics(&metrics); - mMatrix.mapXY(0, metrics.fDescent + mY, &result); - mBottom = SkScalarCeil(result.fY); - } - return mBottom; - } - -#if DEBUG_NAV_UI - // make current (possibily uncomputed) value visible for debugging - int bottomDebug() const - { - return mBottom; - } -#endif - - bool addNewLine(const SkBounder::GlyphRec& rec) - { - SkFixed lineSpacing = SkFixedAbs(mLastGlyph.fLSB.fY - rec.fLSB.fY); - SkFixed lineHeight = SkIntToFixed(bottom() - top()); - return lineSpacing >= lineHeight + (lineHeight >> 1); // 1.5 - } - - bool addSpace(const SkBounder::GlyphRec& rec) - { - bool newBaseLine = mLastGlyph.fLSB.fY != rec.fLSB.fY; - if (((mLastUni >= HYPHEN && mLastUni <= HORZ_BAR) - || mLastUni == HYPHEN_MINUS || mLastUni == SOLIDUS - || mLastUni == REVERSE_SOLIDUS) && newBaseLine) - { - return false; - } - return isSpace(rec); - } - - void finishGlyph() - { - mLastGlyph = mLastCandidate; - mLastUni = mLastUniCandidate; - mLastPaint = mLastPaintCandidate; - } - - const SkIRect& getArea() const { - return mArea; - } - - /* called only while the picture is parsed */ - SkUnichar getUniChar(const SkBounder::GlyphRec& rec) - { - SkUnichar unichar; - SkPaint::TextEncoding save = mPaint.getTextEncoding(); - mPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - mPaint.glyphsToUnichars(&rec.fGlyphID, 1, &unichar); - mPaint.setTextEncoding(save); - return unichar; - } - - bool isSpace(const SkBounder::GlyphRec& rec) - { - if (mLastGlyph.fGlyphID == static_cast<uint16_t>(-1)) - return true; - DBG_NAV_LOGD("mLastGlyph=((%g, %g),(%g, %g), %d)" - " rec=((%g, %g),(%g, %g), %d) mLastUni=0x%04x '%c'", - SkFixedToScalar(mLastGlyph.fLSB.fX), - SkFixedToScalar(mLastGlyph.fLSB.fY), - SkFixedToScalar(mLastGlyph.fRSB.fX), - SkFixedToScalar(mLastGlyph.fRSB.fY), mLastGlyph.fGlyphID, - SkFixedToScalar(rec.fLSB.fX), SkFixedToScalar(rec.fLSB.fY), - SkFixedToScalar(rec.fRSB.fX), SkFixedToScalar(rec.fRSB.fY), - rec.fGlyphID, - mLastUni, mLastUni && mLastUni < 0x7f ? mLastUni : '?'); - bool newBaseLine = mLastGlyph.fLSB.fY != rec.fLSB.fY; - if (newBaseLine) - return true; - SkFixed gapOne = mLastGlyph.fLSB.fX - rec.fRSB.fX; - SkFixed gapTwo = rec.fLSB.fX - mLastGlyph.fRSB.fX; - if (gapOne < 0 && gapTwo < 0) - return false; // overlaps - const SkBounder::GlyphRec& first = mLastGlyph.fLSB.fX < rec.fLSB.fX - ? mLastGlyph : rec; - const SkBounder::GlyphRec& second = mLastGlyph.fLSB.fX < rec.fLSB.fX - ? rec : mLastGlyph; - uint16_t firstGlyph = first.fGlyphID; - SkScalar firstWidth = mLastPaint.measureText(&firstGlyph, sizeof(firstGlyph)); - SkFixed ceilWidth = SkIntToFixed(SkScalarCeil(firstWidth)); - SkFixed posNoSpace = first.fLSB.fX + ceilWidth; - SkFixed ceilSpace = SkIntToFixed(SkFixedCeil(minSpaceWidth(mLastPaint))); - SkFixed posWithSpace = posNoSpace + ceilSpace; - SkFixed diffNoSpace = SkFixedAbs(second.fLSB.fX - posNoSpace); - SkFixed diffWithSpace = SkFixedAbs(second.fLSB.fX - posWithSpace); - DBG_NAV_LOGD("second=%g width=%g (%g) noSpace=%g (%g) withSpace=%g (%g)" - " fontSize=%g", - SkFixedToScalar(second.fLSB.fX), - firstWidth, SkFixedToScalar(ceilWidth), - SkFixedToScalar(posNoSpace), SkFixedToScalar(diffNoSpace), - SkFixedToScalar(posWithSpace), SkFixedToScalar(diffWithSpace), - mLastPaint.getTextSize()); - return diffWithSpace <= diffNoSpace; - } - - SkFixed minSpaceWidth(SkPaint& paint) - { - if (mMinSpaceWidth == SK_FixedMax) { - SkPaint::TextEncoding save = paint.getTextEncoding(); - paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); - SkScalar width = paint.measureText(" ", 1); - mMinSpaceWidth = SkScalarToFixed(width * mMatrix.getScaleX()); - paint.setTextEncoding(save); - DBG_NAV_LOGV("width=%g matrix sx/sy=(%g, %g) tx/ty=(%g, %g)" - " mMinSpaceWidth=%g", width, - mMatrix.getScaleX(), mMatrix.getScaleY(), - mMatrix.getTranslateX(), mMatrix.getTranslateY(), - SkFixedToScalar(mMinSpaceWidth)); - } - return mMinSpaceWidth; - } - - void recordGlyph(const SkBounder::GlyphRec& rec) - { - mLastCandidate = rec; - mLastUniCandidate = getUniChar(rec); - mLastPaintCandidate = mPaint; - } - - void reset() - { - mMinSpaceWidth = SK_FixedMax; // mark as uninitialized - mBase = mBottom = mTop = INT_MAX; // mark as uninitialized - } - - void set(CommonCheck& check) - { - mLastGlyph = check.mLastGlyph; - mLastUni = check.mLastUni; - mMatrix = check.mMatrix; - mLastPaint = check.mLastPaint; - reset(); - } - - void setGlyph(CommonCheck& check) - { - mLastGlyph = check.mLastGlyph; - mLastUni = check.mLastUni; - mLastPaint = check.mLastPaint; - } - - void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y, - const void* text) - { - mMatrix = matrix; - mPaint = paint; - mText = static_cast<const uint16_t*>(text); - mY = y; - reset(); - } - - /* called only while the picture is parsed */ - int top() { - if (mTop == INT_MAX) { - SkPoint result; - SkPaint::FontMetrics metrics; - mPaint.getFontMetrics(&metrics); - mMatrix.mapXY(0, metrics.fAscent + mY, &result); - mTop = SkScalarFloor(result.fY); - } - return mTop; - } - -#if DEBUG_NAV_UI - // make current (possibily uncomputed) value visible for debugging - int topDebug() const - { - return mTop; - } -#endif - -protected: - SkIRect mArea; - SkBounder::GlyphRec mLastCandidate; - SkBounder::GlyphRec mLastGlyph; - SkPaint mLastPaint; // available after picture has been parsed - SkPaint mLastPaintCandidate; // associated with candidate glyph - SkUnichar mLastUni; - SkUnichar mLastUniCandidate; - SkMatrix mMatrix; - SkPaint mPaint; // only set up while the picture is parsed - const uint16_t* mText; - SkScalar mY; -private: - int mBase; - int mBottom; - SkFixed mMinSpaceWidth; - int mTop; - friend class EdgeCheck; -}; - -// generate the limit area for the new selection -class LineCheck : public CommonCheck { -public: - LineCheck(int x, int y, const SkIRect& area) - : INHERITED(area) - , mX(x) - , mY(y) - , mInBetween(false) - { - mLast.setEmpty(); - } - - void finish(const SkRegion& selectedRgn) - { - if (!mParagraphs.count() && mLast.isEmpty()) - return; - processLine(); - bool above = false; - bool below = false; - bool selected = false; - SkRegion localRgn(selectedRgn); - localRgn.translate(-mArea.fLeft, -mArea.fTop, &localRgn); - DBG_NAV_LOGD("localRgn=(%d,%d,%d,%d)", - localRgn.getBounds().fLeft, localRgn.getBounds().fTop, - localRgn.getBounds().fRight, localRgn.getBounds().fBottom); - for (int index = 0; index < mParagraphs.count(); index++) { - const SkIRect& rect = mParagraphs[index]; - bool localSelected = localRgn.intersects(rect); - DBG_NAV_LOGD("[%d] rect=(%d,%d,%d,%d)", index, rect.fLeft, rect.fTop, - rect.fRight, rect.fBottom); - if (localSelected) { - DBG_NAV_LOGD("[%d] localSelected=true", index); - *mSelected.append() = rect; - } - if (rect.fRight <= mX || rect.fLeft >= mX) - continue; - if (mY > rect.fBottom) { - below = true; - selected |= localSelected; - DBG_NAV_LOGD("[%d] below=true localSelected=%s", index, - localSelected ? "true" : "false"); - } - if (mY < rect.fTop) { - above = true; - selected |= localSelected; - DBG_NAV_LOGD("[%d] above=true localSelected=%s", index, - localSelected ? "true" : "false"); - } - } - DBG_NAV_LOGD("mX=%d mY=%d above=%s below=%s selected=%s", - mX, mY, above ? "true" : "false", below ? "true" : "false", - selected ? "true" : "false"); - mInBetween = above && below && selected; - } - - bool inBetween() const - { - return mInBetween; - } - - bool inColumn(const SkIRect& test) const - { - for (int index = 0; index < mSelected.count(); index++) { - const SkIRect& rect = mSelected[index]; - if (rect.fRight > test.fLeft && rect.fLeft < test.fRight) - return true; - } - return false; - } - - bool inColumn(int x, int y) const - { - for (int index = 0; index < mSelected.count(); index++) { - const SkIRect& rect = mSelected[index]; - if (rect.contains(x, y)) - return true; - } - return false; - } - - virtual bool onIRect(const SkIRect& rect) - { - SkIRect bounds; - bounds.set(rect.fLeft, top(), rect.fRight, bottom()); - // assume that characters must be consecutive to describe spaces - // (i.e., don't join rects drawn at different times) - if (bounds.fTop != mLast.fTop || bounds.fBottom != mLast.fBottom - || bounds.fLeft > mLast.fRight + minSpaceWidth(mPaint) - || bounds.fLeft < mLast.fLeft) { - processLine(); - mLast = bounds; - } else - mLast.join(bounds); - return false; - } - - void processLine() - { - // assume line spacing of 1.5 - int lineHeight = bottom() - top(); - mLast.inset(0, -lineHeight >> 1); - // collect arrays of rectangles making up glyphs below or above this one - for (int index = 0; index < mParagraphs.count(); index++) { - SkIRect& rect = mParagraphs[index]; - if (SkIRect::Intersects(rect, mLast)) { - rect.join(mLast); - return; - } - } - *mParagraphs.append() = mLast; - } - -protected: - int mX; - int mY; - SkIRect mLast; - SkTDArray<SkIRect> mParagraphs; - SkTDArray<SkIRect> mSelected; - bool mInBetween; -private: - typedef CommonCheck INHERITED; -}; - -class SelectText::FirstCheck : public CommonCheck { -public: - FirstCheck(int x, int y, const SkIRect& area) - : INHERITED(area) - , mLineCheck(0) - , mFocusX(x - area.fLeft) - , mFocusY(y - area.fTop) - , mBestInColumn(false) - , mRecordGlyph(false) - { - reset(); - } - - const SkIRect& adjustedBounds(int* base) - { - *base = mBestBase + mArea.fTop; - mBestBounds.offset(mArea.fLeft, mArea.fTop); - DBG_NAV_LOGD("FirstCheck mBestBounds:(%d, %d, %d, %d) mTop=%d mBottom=%d", - mBestBounds.fLeft, mBestBounds.fTop, mBestBounds.fRight, - mBestBounds.fBottom, topDebug(), bottomDebug()); - return mBestBounds; - } - - int focusX() const { return mFocusX; } - int focusY() const { return mFocusY; } - - virtual bool onIRectGlyph(const SkIRect& rect, - const SkBounder::GlyphRec& rec) - { - /* compute distance from rectangle center. - * centerX = (rect.L + rect.R) / 2 - * multiply centerX and comparison x by 2 to retain better precision - */ - SkIRect testBounds = {rect.fLeft, top(), rect.fRight, bottom()}; - // dx and dy are the distances from the tested edge - // The edge distance is paramount if the test point is far away - int dx = std::max(0, std::max(testBounds.fLeft - mFocusX, - mFocusX - testBounds.fRight)); - int dy = std::max(0, std::max(testBounds.fTop - mFocusY, - mFocusY - testBounds.fBottom)); - bool testInColumn = false; - bool inBetween = false; - bool inFocus = false; - if (mLineCheck) { - testInColumn = mLineCheck->inColumn(testBounds); - inBetween = mLineCheck->inBetween(); - inFocus = mLineCheck->inColumn(mFocusX, mFocusY); - } -#ifdef EXTRA_NOISY_LOGGING - if (dy < 10) { - SkUnichar ch = getUniChar(rec); - DBG_NAV_LOGD("FC dx/y=%d,%d mDx/y=%d,%d test=%d,%d,%d,%d" - " best=%d,%d,%d,%d bestIn=%s tween=%s testIn=%s focus=%s ch=%c", - dx, dy, mDx, mDy, - testBounds.fLeft, testBounds.fTop, testBounds.fRight, - testBounds.fBottom, mBestBounds.fLeft, mBestBounds.fTop, - mBestBounds.fRight, mBestBounds.fBottom, - mBestInColumn ? "true" : "false", inBetween ? "true" : "false", - testInColumn ? "true" : "false", inFocus ? "true" : "false", - ch < 0x7f ? ch : '?'); - } -#endif - if ((mBestInColumn || inBetween) && !testInColumn) { -#ifdef EXTRA_NOISY_LOGGING - if (dy < 10) DBG_NAV_LOG("FirstCheck reject column"); -#endif - return false; - } - bool ignoreColumn = mBestInColumn == testInColumn || !inFocus; - if (ignoreColumn && dy > 0 && (mDy < dy - || (mDy == dy && dx > 0 && mDx <= dx))) { -#ifdef EXTRA_NOISY_LOGGING - if (dy < 10) DBG_NAV_LOG("FirstCheck reject edge"); -#endif - return false; - } - // cx and cy are the distances from the tested center - // The center distance is used when the test point is over the text - int cx = std::abs(((testBounds.fLeft + testBounds.fRight) >> 1) - - mFocusX); - int cy = std::abs(((testBounds.fTop + testBounds.fBottom) >> 1) - - mFocusY); - if (ignoreColumn && dy == 0 && mDy == 0) { - if (mCy < cy) { -#ifdef EXTRA_NOISY_LOGGING - DBG_NAV_LOGD("FirstCheck reject cy=%d mCy=%d", cy, mCy); -#endif - return false; - } - if (mCy == cy) { - if (dx == 0 && mDx == 0) { - if (mCx < cx) { -#ifdef EXTRA_NOISY_LOGGING - DBG_NAV_LOGD("FirstCheck reject cx=%d mCx=%d", cx, mCx); -#endif - return false; - } - } else if (dx > 0 && mDx <= dx) { -#ifdef EXTRA_NOISY_LOGGING - DBG_NAV_LOGD("FirstCheck reject dx=%d mDx=%d", dx, mDx); -#endif - return false; - } - } - } -#ifdef EXTRA_NOISY_LOGGING - if (dy < 10) { - DBG_NAV_LOGD("FirstCheck cx/y=(%d,%d)", cx, cy); - } -#endif - mBestBase = base(); - mBestBounds = testBounds; - mBestInColumn = testInColumn; -#ifndef EXTRA_NOISY_LOGGING - if (dy < 10 && dx < 10) -#endif - { -#if DEBUG_NAV_UI - SkUnichar ch = getUniChar(rec); -#endif - DBG_NAV_LOGD("FirstCheck dx/y=(%d,%d) mFocus=(%d,%d)" - " mBestBounds={%d,%d,r=%d,b=%d} inColumn=%s ch=%c", - dx, dy, mFocusX, mFocusY, - mBestBounds.fLeft, mBestBounds.fTop, - mBestBounds.fRight, mBestBounds.fBottom, - mBestInColumn ? "true" : "false", ch < 0x7f ? ch : '?'); - } - mCx = cx; - mCy = cy; - mDx = dx; - mDy = dy; - if (mRecordGlyph) - recordGlyph(rec); - return false; - } - - void reset() - { - mBestBounds.setEmpty(); - mDx = mDy = mCx = mCy = INT_MAX; - } - - void setLines(const LineCheck* lineCheck) { mLineCheck = lineCheck; } - void setRecordGlyph() { mRecordGlyph = true; } - -protected: - const LineCheck* mLineCheck; - int mBestBase; - SkIRect mBestBounds; - int mCx; - int mCy; - int mDx; - int mDy; - int mFocusX; - int mFocusY; - bool mBestInColumn; - bool mRecordGlyph; -private: - typedef CommonCheck INHERITED; -}; - -class SelectText::EdgeCheck : public SelectText::FirstCheck { -public: - EdgeCheck(int x, int y, const SkIRect& area, CommonCheck& last, bool left) - : INHERITED(x, y, area) - , mLast(area) - , mLeft(left) - { - mLast.set(last); // CommonCheck::set() - setGlyph(last); - } - - bool adjacent() - { - return !mLast.isSpace(mLastGlyph); - } - - const SkIRect& bestBounds(int* base) - { - *base = mBestBase; - return mBestBounds; - } - - virtual bool onIRectGlyph(const SkIRect& rect, - const SkBounder::GlyphRec& rec) - { - int dx = mLeft ? mFocusX - rect.fRight : rect.fLeft - mFocusX; - int dy = ((top() + bottom()) >> 1) - mFocusY; - dx = abs(dx); - dy = abs(dy); - if (mLeft ? mFocusX <= rect.fLeft : mFocusX >= rect.fRight) { - if (dx <= 10 && dy <= 10) { - DBG_NAV_LOGD("EdgeCheck fLeft=%d fRight=%d mFocusX=%d dx=%d dy=%d", - rect.fLeft, rect.fRight, mFocusX, dx, dy); - } - return false; - } - if (mDy > dy || (mDy == dy && mDx > dx)) { - if (rec.fLSB == mLastGlyph.fLSB && rec.fRSB == mLastGlyph.fRSB) { - DBG_NAV_LOGD("dup rec.fLSB.fX=%g rec.fRSB.fX=%g", - SkFixedToScalar(rec.fLSB.fX), SkFixedToScalar(rec.fRSB.fX)); - return false; - } - recordGlyph(rec); - mDx = dx; - mDy = dy; - mBestBase = base(); - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); - if (dx <= 10 && dy <= 10) { - DBG_NAV_LOGD("EdgeCheck mBestBounds={%d,%d,r=%d,b=%d} dx/y=(%d, %d)", - mBestBounds.fLeft, mBestBounds.fTop, - mBestBounds.fRight, mBestBounds.fBottom, dx, dy); - } - } - return false; - } - - void shiftStart(SkIRect bounds) - { - DBG_NAV_LOGD("EdgeCheck mFocusX=%d mLeft=%s bounds.fLeft=%d bounds.fRight=%d", - mFocusX, mLeft ? "true" : "false", bounds.fLeft, bounds.fRight); - reset(); - mFocusX = mLeft ? bounds.fLeft : bounds.fRight; - mLast.set(*this); // CommonCheck::set() - } - -protected: - CommonCheck mLast; - bool mLeft; -private: - typedef SelectText::FirstCheck INHERITED; -}; - -class FindFirst : public CommonCheck { -public: - FindFirst(const SkIRect& area) - : INHERITED(area) - { - mBestBounds.set(area.width(), area.height(), area.width(), area.height()); - } - - const SkIRect& bestBounds(int* base) - { - *base = mBestBase; - return mBestBounds; - } - - virtual bool onIRect(const SkIRect& rect) - { - if (mBestBounds.isEmpty()) { - mBestBase = base(); - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); - } - return false; - } - -protected: - int mBestBase; - SkIRect mBestBounds; -private: - typedef CommonCheck INHERITED; -}; - -class FindLast : public FindFirst { -public: - FindLast(const SkIRect& area) - : INHERITED(area) - { - mBestBounds.setEmpty(); - } - - virtual bool onIRect(const SkIRect& rect) - { - mBestBase = base(); - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); - return false; - } - -private: - typedef FindFirst INHERITED; -}; - -static bool baseLinesAgree(const SkIRect& rectA, int baseA, - const SkIRect& rectB, int baseB) -{ - return (rectA.fTop < baseB && rectA.fBottom >= baseB) - || (rectB.fTop < baseA && rectB.fBottom >= baseA); -} - -class BuilderCheck : public CommonCheck { -protected: - enum IntersectionType { - NO_INTERSECTION, // debugging printf expects this to equal zero - LAST_INTERSECTION, // debugging printf expects this to equal one - WAIT_FOR_INTERSECTION - }; - - BuilderCheck(const SkIRect& start, int startBase, const SkIRect& end, - int endBase, const SkIRect& area) - : INHERITED(area) - , mCapture(false) - , mEnd(end) - , mEndBase(endBase) - , mStart(start) - , mStartBase(startBase) - { - mEnd.offset(-area.fLeft, -area.fTop); - mEndBase -= area.fTop; - mEndExtra.setEmpty(); - mLast.setEmpty(); - mLastBase = INT_MAX; - mSelectRect.setEmpty(); - mStart.offset(-area.fLeft, -area.fTop); - mStartBase -= area.fTop; - mStartExtra.setEmpty(); - DBG_NAV_LOGD(" mStart=(%d,%d,r=%d,b=%d) mStartBase=%d" - " mEnd=(%d,%d,r=%d,b=%d) mEndBase=%d", - mStart.fLeft, mStart.fTop, mStart.fRight, mStart.fBottom, mStartBase, - mEnd.fLeft, mEnd.fTop, mEnd.fRight, mEnd.fBottom, mEndBase); - } - - int checkFlipRect(const SkIRect& full, int fullBase) { - mCollectFull = false; - // is the text to collect between the selection top and bottom? - if (fullBase < mStart.fTop || fullBase > mEnd.fBottom) { - if (VERBOSE_LOGGING && !mLast.isEmpty()) DBG_NAV_LOGD("%s 1" - " full=(%d,%d,r=%d,b=%d) fullBase=%d" - " mLast=(%d,%d,r=%d,b=%d) mLastBase=%d", - mLastIntersects ? "LAST_INTERSECTION" : "NO_INTERSECTION", - full.fLeft, full.fTop, full.fRight, full.fBottom, fullBase, - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom, mLastBase); - return mLastIntersects; - } - // is the text to the left of the selection start? - if (baseLinesAgree(mStart, mStartBase, full, fullBase) - && full.fLeft < mStart.fLeft) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("%s 2" - " full=(%d,%d,r=%d,b=%d) fullBase=%d" - " mLast=(%d,%d,r=%d,b=%d) mLastBase=%d" - " mStart=(%d,%d,r=%d,b=%d) mStartBase=%d", - mLastIntersects ? "LAST_INTERSECTION" : "NO_INTERSECTION", - full.fLeft, full.fTop, full.fRight, full.fBottom, fullBase, - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom, mLastBase, - mStart.fLeft, mStart.fTop, mStart.fRight, mStart.fBottom, mStartBase); - mStartExtra.join(full); - return mLastIntersects; - } - // is the text to the right of the selection end? - if (baseLinesAgree(mEnd, mEndBase, full, fullBase) - && full.fRight > mEnd.fRight) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("%s 3" - " full=(%d,%d,r=%d,b=%d) fullBase=%d" - " mLast=(%d,%d,r=%d,b=%d) mLastBase=%d" - " mEnd=(%d,%d,r=%d,b=%d) mEndBase=%d", - mLastIntersects ? "LAST_INTERSECTION" : "NO_INTERSECTION", - full.fLeft, full.fTop, full.fRight, full.fBottom, fullBase, - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom, mLastBase, - mEnd.fLeft, mEnd.fTop, mEnd.fRight, mEnd.fBottom, mEndBase); - mEndExtra.join(full); - return mLastIntersects; - } - int spaceGap = SkFixedRound(minSpaceWidth(mPaint) * 3); - // should text to the left of the start be added to the selection bounds? - if (!mStartExtra.isEmpty()) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("mSelectRect=(%d,%d,r=%d,b=%d)" - " mStartExtra=(%d,%d,r=%d,b=%d)", - mSelectRect.fLeft, mSelectRect.fTop, mSelectRect.fRight, mSelectRect.fBottom, - mStartExtra.fLeft, mStartExtra.fTop, mStartExtra.fRight, mStartExtra.fBottom); - if (mStartExtra.fRight + spaceGap >= mStart.fLeft) - mSelectRect.join(mStartExtra); - mStartExtra.setEmpty(); - } - // should text to the right of the end be added to the selection bounds? - if (!mEndExtra.isEmpty()) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("mSelectRect=(%d,%d,r=%d,b=%d)" - " mEndExtra=(%d,%d,r=%d,b=%d)", - mSelectRect.fLeft, mSelectRect.fTop, mSelectRect.fRight, mSelectRect.fBottom, - mEndExtra.fLeft, mEndExtra.fTop, mEndExtra.fRight, mEndExtra.fBottom); - if (mEndExtra.fLeft - spaceGap <= mEnd.fRight) - mSelectRect.join(mEndExtra); - mEndExtra.setEmpty(); - } - bool sameBaseLine = baseLinesAgree(mLast, mLastBase, full, fullBase); - bool adjacent = (full.fLeft - mLast.fRight) < spaceGap; - // is this the first, or are there more characters on the same line? - if (mLast.isEmpty() || (sameBaseLine && adjacent)) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("WAIT_FOR_INTERSECTION" - " full=(%d,%d,r=%d,b=%d) fullBase=%d" - " mLast=(%d,%d,r=%d,b=%d) mLastBase=%d" - " mSelectRect=(%d,%d,r=%d,b=%d)", - full.fLeft, full.fTop, full.fRight, full.fBottom, fullBase, - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom, mLastBase, - mSelectRect.fLeft, mSelectRect.fTop, mSelectRect.fRight, mSelectRect.fBottom); - mLast.join(full); - mLastIntersects = SkIRect::Intersects(mLast, mSelectRect); - return WAIT_FOR_INTERSECTION; - } - if (VERBOSE_LOGGING) DBG_NAV_LOGD("%s 4" - " mLast=(%d,%d,r=%d,b=%d) mLastBase=%d" - " full=(%d,%d,r=%d,b=%d) fullBase=%d" - " mSelectRect=(%d,%d,r=%d,b=%d)" - " mStartExtra=(%d,%d,r=%d,b=%d)" - " mEndExtra=(%d,%d,r=%d,b=%d)", - mLastIntersects ? "LAST_INTERSECTION" : "NO_INTERSECTION", - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom, mLastBase, - full.fLeft, full.fTop, full.fRight, full.fBottom, fullBase, - mSelectRect.fLeft, mSelectRect.fTop, mSelectRect.fRight, mSelectRect.fBottom, - mStartExtra.fLeft, mStartExtra.fTop, mStartExtra.fRight, mStartExtra.fBottom, - mEndExtra.fLeft, mEndExtra.fTop, mEndExtra.fRight, mEndExtra.fBottom); - // after the caller determines what to do with the last collection, - // start the collection over with full and fullBase. - mCollectFull = true; - return mLastIntersects; - } - - bool resetLast(const SkIRect& full, int fullBase) - { - if (mCollectFull) { - mLast = full; - mLastBase = fullBase; - mLastIntersects = SkIRect::Intersects(mLast, mSelectRect); - } else { - mLast.setEmpty(); - mLastBase = INT_MAX; - mLastIntersects = false; - } - return mCollectFull; - } - - void setFlippedState() - { - mSelectRect = mStart; - mSelectRect.join(mEnd); - DBG_NAV_LOGD("mSelectRect=(%d,%d,r=%d,b=%d)", - mSelectRect.fLeft, mSelectRect.fTop, mSelectRect.fRight, mSelectRect.fBottom); - mLast.setEmpty(); - mLastBase = INT_MAX; - mLastIntersects = NO_INTERSECTION; - } - - bool mCapture; - bool mCollectFull; - SkIRect mEnd; - int mEndBase; - SkIRect mEndExtra; - bool mFlipped; - SkIRect mLast; - int mLastBase; - int mLastIntersects; - SkIRect mSelectRect; - SkIRect mStart; - SkIRect mStartExtra; - int mStartBase; -private: - typedef CommonCheck INHERITED; - -}; - -class MultilineBuilder : public BuilderCheck { -public: - MultilineBuilder(const SkIRect& start, int startBase, const SkIRect& end, - int endBase, const SkIRect& area, SkRegion* region) - : INHERITED(start, startBase, end, endBase, area) - , mSelectRegion(region) - { - mFlipped = false; - } - - void addLastToRegion() { - if (VERBOSE_LOGGING) DBG_NAV_LOGD(" mLast=(%d,%d,r=%d,b=%d)", - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom); - mSelectRegion->op(mLast, SkRegion::kUnion_Op); - } - - void finish() { - if (!mFlipped || !mLastIntersects) - return; - addLastToRegion(); - } - - // return true if capture end was not found after capture begin - bool flipped() { - DBG_NAV_LOGD("flipped=%s", mCapture ? "true" : "false"); - if (!mCapture) - return false; - mFlipped = true; - setFlippedState(); - mSelectRegion->setEmpty(); - return true; - } - - virtual bool onIRect(const SkIRect& rect) { - SkIRect full; - full.set(rect.fLeft, top(), rect.fRight, bottom()); - int fullBase = base(); - if (mFlipped) { - int intersectType = checkFlipRect(full, fullBase); - if (intersectType == LAST_INTERSECTION) - addLastToRegion(); - if (intersectType != WAIT_FOR_INTERSECTION) - resetLast(full, fullBase); - return false; - } - if (full == mStart) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("full == mStart full=(%d,%d,r=%d,b=%d)", - full.fLeft, full.fTop, full.fRight, full.fBottom); - mCapture = true; - } - if (mCapture) { - bool sameLines = baseLinesAgree(mLast, mLastBase, full, fullBase); - if (sameLines) - mLast.join(full); - if (!sameLines || full == mEnd) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("finish mLast=(%d,%d,r=%d,b=%d)", - mLast.fLeft, mLast.fTop, mLast.fRight, mLast.fBottom); - addLastToRegion(); - mLast = full; - mLastBase = fullBase; - } - } - if (full == mEnd) { - if (VERBOSE_LOGGING) DBG_NAV_LOGD("full == mEnd full=(%d,%d,r=%d,b=%d)", - full.fLeft, full.fTop, full.fRight, full.fBottom); - mCapture = false; - if (full == mStart) - addLastToRegion(); - } - return false; - } - -protected: - SkRegion* mSelectRegion; -private: - typedef BuilderCheck INHERITED; -}; - -static inline bool compareBounds(const SkIRect* first, const SkIRect* second) -{ - return first->fTop < second->fTop; -} - -class TextExtractor : public BuilderCheck { -public: - TextExtractor(const SkIRect& start, int startBase, const SkIRect& end, - int endBase, const SkIRect& area, bool flipped) - : INHERITED(start, startBase, end, endBase, area) - , mSelectStartIndex(-1) - , mSkipFirstSpace(true) // don't start with a space - { - mFlipped = flipped; - if (flipped) - setFlippedState(); - } - - void addCharacter(const SkBounder::GlyphRec& rec) - { - if (mSelectStartIndex < 0) - mSelectStartIndex = mSelectText.count(); - if (!mSkipFirstSpace) { - if (addNewLine(rec)) { - DBG_NAV_LOG("write new line"); - *mSelectText.append() = '\n'; - *mSelectText.append() = '\n'; - } else if (addSpace(rec)) { - DBG_NAV_LOG("write space"); - *mSelectText.append() = ' '; - } - } else - mSkipFirstSpace = false; - recordGlyph(rec); - finishGlyph(); - if (VERBOSE_LOGGING) DBG_NAV_LOGD("glyphID=%d uni=%d '%c'", rec.fGlyphID, - mLastUni, mLastUni && mLastUni < 0x7f ? mLastUni : '?'); - if (mLastUni) { - uint16_t chars[2]; - size_t count = SkUTF16_FromUnichar(mLastUni, chars); - *mSelectText.append() = chars[0]; - if (count == 2) - *mSelectText.append() = chars[1]; - } - } - - void addLast() - { - *mSelectBounds.append() = mLast; - *mSelectStart.append() = mSelectStartIndex; - *mSelectEnd.append() = mSelectText.count(); - } - - /* Text characters are collected before it's been determined that the - characters are part of the selection. The bounds describe valid parts - of the selection, but the bounds are out of order. - - This sorts the characters by sorting the bounds, then copying the - characters that were captured. - */ - void finish() - { - if (mLastIntersects) - addLast(); - Vector<SkIRect*> sortedBounds; - SkTDArray<uint16_t> temp; - int index; - DBG_NAV_LOGD("mSelectBounds.count=%d text=%d", mSelectBounds.count(), - mSelectText.count()); - for (index = 0; index < mSelectBounds.count(); index++) - sortedBounds.append(&mSelectBounds[index]); - std::sort(sortedBounds.begin(), sortedBounds.end(), compareBounds); - int lastEnd = -1; - for (index = 0; index < mSelectBounds.count(); index++) { - int order = sortedBounds[index] - &mSelectBounds[0]; - int start = mSelectStart[order]; - int end = mSelectEnd[order]; - DBG_NAV_LOGD("order=%d start=%d end=%d top=%d", order, start, end, - mSelectBounds[order].fTop); - int count = temp.count(); - if (count > 0 && temp[count - 1] != '\n' && start != lastEnd) { - // always separate paragraphs when original text is out of order - DBG_NAV_LOG("write new line"); - *temp.append() = '\n'; - *temp.append() = '\n'; - } - temp.append(end - start, &mSelectText[start]); - lastEnd = end; - } - mSelectText.swap(temp); - } - - virtual bool onIRectGlyph(const SkIRect& rect, - const SkBounder::GlyphRec& rec) - { - SkIRect full; - full.set(rect.fLeft, top(), rect.fRight, bottom()); - int fullBase = base(); - if (mFlipped) { - int intersectType = checkFlipRect(full, fullBase); - if (WAIT_FOR_INTERSECTION == intersectType) - addCharacter(rec); // may not be copied - else { - if (LAST_INTERSECTION == intersectType) - addLast(); - else - mSkipFirstSpace = true; - mSelectStartIndex = -1; - if (resetLast(full, fullBase)) - addCharacter(rec); // may not be copied - } - return false; - } - if (full == mStart) - mCapture = true; - if (mCapture) - addCharacter(rec); - else - mSkipFirstSpace = true; - if (full == mEnd) - mCapture = false; - return false; - } - - WTF::String text() { - if (mFlipped) - finish(); - // the text has been copied in visual order. Reverse as needed if - // result contains right-to-left characters. - const uint16_t* start = mSelectText.begin(); - const uint16_t* end = mSelectText.end(); - while (start < end) { - SkUnichar ch = SkUTF16_NextUnichar(&start); - WTF::Unicode::Direction charDirection = WTF::Unicode::direction(ch); - if (WTF::Unicode::RightToLeftArabic == charDirection - || WTF::Unicode::RightToLeft == charDirection) { - WebCore::ReverseBidi(mSelectText.begin(), mSelectText.count()); - break; - } - } - return WTF::String(mSelectText.begin(), mSelectText.count()); - } - -protected: - SkIRect mEmpty; - SkTDArray<SkIRect> mSelectBounds; - SkTDArray<int> mSelectEnd; - SkTDArray<int> mSelectStart; - int mSelectStartIndex; - SkTDArray<uint16_t> mSelectText; - bool mSkipFirstSpace; -private: - typedef BuilderCheck INHERITED; -}; - -class TextCanvas : public ParseCanvas { -public: - - TextCanvas(CommonCheck* bounder) - : mBounder(*bounder) { - setBounder(bounder); - SkBitmap bitmap; - const SkIRect& area = bounder->getArea(); - bitmap.setConfig(SkBitmap::kARGB_8888_Config, area.width(), - area.height()); - setBitmapDevice(bitmap); - translate(SkIntToScalar(-area.fLeft), SkIntToScalar(-area.fTop)); -#ifdef DEBUG_NAV_UI - const SkIRect& clip = getTotalClip().getBounds(); - const SkMatrix& matrix = getTotalMatrix(); - DBG_NAV_LOGD("bitmap=(%d,%d) clip=(%d,%d,%d,%d) matrix=(%g,%g)", - bitmap.width(), bitmap.height(), clip.fLeft, clip.fTop, - clip.fRight, clip.fBottom, matrix.getTranslateX(), matrix.getTranslateY()); -#endif - } - - virtual void drawPaint(const SkPaint& paint) { - } - - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - } - - virtual void drawRect(const SkRect& rect, const SkPaint& paint) { - } - - virtual void drawPath(const SkPath& path, const SkPaint& paint) { - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& matrix, const SkPaint& paint) { - } - - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint = NULL) { - } - - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - mBounder.setUp(paint, getTotalMatrix(), y, text); - INHERITED::drawText(text, byteLength, x, y, paint); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - mBounder.setUp(paint, getTotalMatrix(), constY, text); - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); - } - - virtual void drawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint) { - } - - CommonCheck& mBounder; -private: - typedef ParseCanvas INHERITED; -}; - -static bool buildSelection(const SkPicture& picture, const SkIRect& area, - const SkIRect& selStart, int startBase, - const SkIRect& selEnd, int endBase, SkRegion* region) -{ - DBG_NAV_LOGD("area=(%d, %d, %d, %d) selStart=(%d, %d, %d, %d)" - " selEnd=(%d, %d, %d, %d)", - area.fLeft, area.fTop, area.fRight, area.fBottom, - selStart.fLeft, selStart.fTop, selStart.fRight, selStart.fBottom, - selEnd.fLeft, selEnd.fTop, selEnd.fRight, selEnd.fBottom); - MultilineBuilder builder(selStart, startBase, selEnd, endBase, area, region); - TextCanvas checker(&builder); - checker.drawPicture(const_cast<SkPicture&>(picture)); - bool flipped = builder.flipped(); - if (flipped) { - TextCanvas checker(&builder); - checker.drawPicture(const_cast<SkPicture&>(picture)); - } - builder.finish(); - region->translate(area.fLeft, area.fTop); - return flipped; -} - -static SkIRect findFirst(const SkPicture& picture, int* base) -{ - SkIRect area; - area.set(0, 0, picture.width(), picture.height()); - FindFirst finder(area); - TextCanvas checker(&finder); - checker.drawPicture(const_cast<SkPicture&>(picture)); - return finder.bestBounds(base); -} - -static SkIRect findLast(const SkPicture& picture, int* base) -{ - SkIRect area; - area.set(0, 0, picture.width(), picture.height()); - FindLast finder(area); - TextCanvas checker(&finder); - checker.drawPicture(const_cast<SkPicture&>(picture)); - return finder.bestBounds(base); -} - -static WTF::String text(const SkPicture& picture, const SkIRect& area, - const SkIRect& start, int startBase, const SkIRect& end, - int endBase, bool flipped) -{ - TextExtractor extractor(start, startBase, end, endBase, area, flipped); - TextCanvas checker(&extractor); - checker.drawPicture(const_cast<SkPicture&>(picture)); - return extractor.text(); -} - -#define CONTROL_NOTCH 16 -#define CONTROL_HEIGHT 35 -#define CONTROL_WIDTH 21 -#define STROKE_WIDTH 1.0f -#define STROKE_OUTSET 3.5f -#define STROKE_I_OUTSET 4 // (int) ceil(STROKE_OUTSET) -#define STROKE_COLOR 0x66000000 -#define OUTER_COLOR 0x33000000 -#define INNER_COLOR 0xe6aae300 - -#define SLOP 35 - -SelectText::SelectText() -{ - m_picture = 0; - reset(); - SkPaint paint; - SkRect oval; - - SkPath startOuterPath; - oval.set(-CONTROL_WIDTH - STROKE_OUTSET, CONTROL_NOTCH - STROKE_OUTSET, - -CONTROL_WIDTH + STROKE_OUTSET, CONTROL_NOTCH + STROKE_OUTSET); - startOuterPath.arcTo(oval, 180, 45, true); - oval.set(-STROKE_OUTSET, -STROKE_OUTSET, STROKE_OUTSET, STROKE_OUTSET); - startOuterPath.arcTo(oval, 180 + 45, 135, false); - oval.set(-STROKE_OUTSET, CONTROL_HEIGHT - STROKE_OUTSET, - STROKE_OUTSET, CONTROL_HEIGHT + STROKE_OUTSET); - startOuterPath.arcTo(oval, 0, 90, false); - oval.set(-CONTROL_WIDTH - STROKE_OUTSET, CONTROL_HEIGHT - STROKE_OUTSET, - -CONTROL_WIDTH + STROKE_OUTSET, CONTROL_HEIGHT + STROKE_OUTSET); - startOuterPath.arcTo(oval, 90, 90, false); - startOuterPath.close(); - SkPath startInnerPath; - startInnerPath.moveTo(-CONTROL_WIDTH, CONTROL_NOTCH); - startInnerPath.lineTo(-CONTROL_WIDTH, CONTROL_HEIGHT); - startInnerPath.lineTo(0, CONTROL_HEIGHT); - startInnerPath.lineTo(0, 0); - startInnerPath.close(); - startOuterPath.addPath(startInnerPath, 0, 0); - - SkCanvas* canvas = m_startControl.beginRecording( - CONTROL_WIDTH + STROKE_OUTSET * 2, - CONTROL_HEIGHT + STROKE_OUTSET * 2); - paint.setAntiAlias(true); - paint.setColor(INNER_COLOR); - paint.setStyle(SkPaint::kFill_Style); - canvas->drawPath(startInnerPath, paint); - paint.setColor(OUTER_COLOR); - canvas->drawPath(startOuterPath, paint); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(STROKE_COLOR); - paint.setStrokeWidth(STROKE_WIDTH); - canvas->drawPath(startInnerPath, paint); - m_startControl.endRecording(); - - SkPath endOuterPath; - oval.set(-STROKE_OUTSET, -STROKE_OUTSET, STROKE_OUTSET, STROKE_OUTSET); - endOuterPath.arcTo(oval, 180, 135, true); - oval.set(CONTROL_WIDTH - STROKE_OUTSET, CONTROL_NOTCH - STROKE_OUTSET, - CONTROL_WIDTH + STROKE_OUTSET, CONTROL_NOTCH + STROKE_OUTSET); - endOuterPath.arcTo(oval, 360 - 45, 45, false); - oval.set(CONTROL_WIDTH - STROKE_OUTSET, CONTROL_HEIGHT - STROKE_OUTSET, - CONTROL_WIDTH + STROKE_OUTSET, CONTROL_HEIGHT + STROKE_OUTSET); - endOuterPath.arcTo(oval, 0, 90, false); - oval.set(-STROKE_OUTSET, CONTROL_HEIGHT - STROKE_OUTSET, - STROKE_OUTSET, CONTROL_HEIGHT + STROKE_OUTSET); - endOuterPath.arcTo(oval, 90, 90, false); - startOuterPath.close(); - SkPath endInnerPath; - endInnerPath.moveTo(0, 0); - endInnerPath.lineTo(0, CONTROL_HEIGHT); - endInnerPath.lineTo(CONTROL_WIDTH, CONTROL_HEIGHT); - endInnerPath.lineTo(CONTROL_WIDTH, CONTROL_NOTCH); - endInnerPath.close(); - endOuterPath.addPath(endInnerPath, 0, 0); - - canvas = m_endControl.beginRecording(CONTROL_WIDTH + STROKE_OUTSET * 2, - CONTROL_HEIGHT + STROKE_OUTSET * 2); - paint.setColor(INNER_COLOR); - paint.setStyle(SkPaint::kFill_Style); - canvas->drawPath(endInnerPath, paint); - paint.setColor(OUTER_COLOR); - canvas->drawPath(endOuterPath, paint); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(STROKE_COLOR); - paint.setStrokeWidth(STROKE_WIDTH); - canvas->drawPath(endInnerPath, paint); - m_endControl.endRecording(); -} - -SelectText::~SelectText() -{ - SkSafeUnref(m_picture); -} - -void SelectText::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval) -{ - if (m_layerId != layer->uniqueId()) - return; - // reset m_picture to match m_layerId - SkSafeUnref(m_picture); - m_picture = layer->picture(); - SkSafeRef(m_picture); - DBG_NAV_LOGD("m_extendSelection=%d m_drawPointer=%d layer [%d]", - m_extendSelection, m_drawPointer, layer->uniqueId()); - if (m_extendSelection) - drawSelectionRegion(canvas, inval); - if (m_drawPointer) - drawSelectionPointer(canvas, inval); -} - -static void addInval(IntRect* inval, const SkCanvas* canvas, - const SkRect& bounds) { - const SkMatrix& matrix = canvas->getTotalMatrix(); - SkRect transformed; - matrix.mapRect(&transformed, bounds); - SkIRect iTrans; - transformed.round(&iTrans); - inval->unite(iTrans); -} - -void SelectText::drawSelectionPointer(SkCanvas* canvas, IntRect* inval) -{ - SkPath path; - if (m_extendSelection) - getSelectionCaret(&path); - else - getSelectionArrow(&path); - SkPixelXorXfermode xorMode(SK_ColorWHITE); - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorBLACK); - if (m_extendSelection) - paint.setXfermode(&xorMode); - else - paint.setStrokeWidth(SK_Scalar1 * 2); - int sc = canvas->save(); - canvas->scale(m_inverseScale, m_inverseScale); - canvas->translate(m_selectX, m_selectY); - canvas->drawPath(path, paint); - if (!m_extendSelection) { - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(SK_ColorWHITE); - canvas->drawPath(path, paint); - } - SkRect bounds = path.getBounds(); - bounds.inset(-SK_Scalar1 * 2, -SK_Scalar1 * 2); // stroke width - addInval(inval, canvas, bounds); - canvas->restoreToCount(sc); -} - -static void addStart(SkRegion* diff, const SkIRect& rect) -{ - SkIRect bounds; - bounds.set(rect.fLeft - CONTROL_WIDTH - STROKE_I_OUTSET, - rect.fBottom - STROKE_I_OUTSET, rect.fLeft + STROKE_I_OUTSET, - rect.fBottom + CONTROL_HEIGHT + STROKE_I_OUTSET); - diff->op(bounds, SkRegion::kUnion_Op); -} - -static void addEnd(SkRegion* diff, const SkIRect& rect) -{ - SkIRect bounds; - bounds.set(rect.fRight - STROKE_I_OUTSET, rect.fBottom - STROKE_I_OUTSET, - rect.fRight + CONTROL_WIDTH + STROKE_I_OUTSET, - rect.fBottom + CONTROL_HEIGHT + STROKE_I_OUTSET); - diff->op(bounds, SkRegion::kUnion_Op); -} - -void SelectText::drawSelectionRegion(SkCanvas* canvas, IntRect* inval) -{ - if (!m_picture) - return; - SkIRect ivisBounds = m_visibleRect; - ivisBounds.join(m_selStart); - ivisBounds.join(m_selEnd); - DBG_NAV_LOGD("m_selStart=(%d,%d,r=%d,b=%d) m_selEnd=(%d,%d,r=%d,b=%d)" - " ivisBounds=(%d,%d,r=%d,b=%d)", - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, - m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom, - ivisBounds.fLeft, ivisBounds.fTop, ivisBounds.fRight, ivisBounds.fBottom); - if (m_lastSelRegion != m_selRegion) - m_lastSelRegion.set(m_selRegion); - SkRegion diff(m_lastSelRegion); - m_selRegion.setEmpty(); - m_flipped = buildSelection(*m_picture, ivisBounds, m_selStart, m_startBase, - m_selEnd, m_endBase, &m_selRegion); - SkPath path; - m_selRegion.getBoundaryPath(&path); - path.setFillType(SkPath::kEvenOdd_FillType); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(SkColorSetARGB(0x80, 0x83, 0xCC, 0x39)); - canvas->drawPath(path, paint); - // experiment to draw touchable controls that resize the selection - canvas->save(); - canvas->translate(m_selStart.fLeft, m_selStart.fBottom); - canvas->drawPicture(m_startControl); - canvas->restore(); - canvas->save(); - canvas->translate(m_selEnd.fRight, m_selEnd.fBottom); - canvas->drawPicture(m_endControl); - canvas->restore(); - SkIRect a = diff.getBounds(); - SkIRect b = m_selRegion.getBounds(); - diff.op(m_selRegion, SkRegion::kXOR_Op); - SkIRect c = diff.getBounds(); - DBG_NAV_LOGD("old=(%d,%d,r=%d,b=%d) new=(%d,%d,r=%d,b=%d) diff=(%d,%d,r=%d,b=%d)", - a.fLeft, a.fTop, a.fRight, a.fBottom, b.fLeft, b.fTop, b.fRight, b.fBottom, - c.fLeft, c.fTop, c.fRight, c.fBottom); - DBG_NAV_LOGD("lastStart=(%d,%d,r=%d,b=%d) m_lastEnd=(%d,%d,r=%d,b=%d)", - m_lastStart.fLeft, m_lastStart.fTop, m_lastStart.fRight, m_lastStart.fBottom, - m_lastEnd.fLeft, m_lastEnd.fTop, m_lastEnd.fRight, m_lastEnd.fBottom); - if (!m_lastDrawnStart.isEmpty()) - addStart(&diff, m_lastDrawnStart); - if (m_lastStart != m_selStart) { - m_lastDrawnStart = m_lastStart; - m_lastStart = m_selStart; - } - addStart(&diff, m_selStart); - if (!m_lastDrawnEnd.isEmpty()) - addEnd(&diff, m_lastDrawnEnd); - if (m_lastEnd != m_selEnd) { - m_lastDrawnEnd = m_lastEnd; - m_lastEnd = m_selEnd; - } - addEnd(&diff, m_selEnd); - SkIRect iBounds = diff.getBounds(); - DBG_NAV_LOGD("diff=(%d,%d,r=%d,b=%d)", - iBounds.fLeft, iBounds.fTop, iBounds.fRight, iBounds.fBottom); - SkRect bounds; - bounds.set(iBounds); - addInval(inval, canvas, bounds); -} - -void SelectText::extendSelection(const IntRect& vis, int x, int y) -{ - if (!m_picture) - return; - setVisibleRect(vis); - SkIRect clipRect = m_visibleRect; - int base; - DBG_NAV_LOGD("extend x/y=%d,%d m_startOffset=%d,%d", x, y, - m_startOffset.fX, m_startOffset.fY); - x -= m_startOffset.fX; - y -= m_startOffset.fY; - if (m_startSelection) { - if (!clipRect.contains(x, y) - || !clipRect.contains(m_original.fX, m_original.fY)) { - clipRect.set(m_original.fX, m_original.fY, x, y); - clipRect.sort(); - clipRect.inset(-m_visibleRect.width(), -m_visibleRect.height()); - } - FirstCheck center(m_original.fX, m_original.fY, clipRect); - m_selStart = m_selEnd = findClosest(center, *m_picture, &base); - if (m_selStart.isEmpty()) - return; - DBG_NAV_LOGD("selStart clip=(%d,%d,%d,%d) m_original=%d,%d" - " m_selStart=(%d,%d,%d,%d)", clipRect.fLeft, clipRect.fTop, - clipRect.fRight, clipRect.fBottom, m_original.fX, m_original.fY, - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom); - m_startBase = m_endBase = base; - m_startSelection = false; - m_extendSelection = true; - m_original.fX = m_original.fY = 0; - } - DBG_NAV_LOGD("extend x/y=%d,%d m_original=%d,%d", x, y, - m_original.fX, m_original.fY); - x -= m_original.fX; - y -= m_original.fY; - if (!clipRect.contains(x, y) || !clipRect.contains(m_selStart)) { - clipRect.set(m_selStart.fLeft, m_selStart.fTop, x, y); - clipRect.sort(); - clipRect.inset(-m_visibleRect.width(), -m_visibleRect.height()); - } - DBG_NAV_LOGD("extend clip=(%d,%d,%d,%d) x/y=%d,%d wordSel=%s outsideWord=%s", - clipRect.fLeft, clipRect.fTop, clipRect.fRight, clipRect.fBottom, x, y, - m_wordSelection ? "true" : "false", m_outsideWord ? "true" : "false"); - FirstCheck extension(x, y, clipRect); - SkIRect found = findClosest(extension, *m_picture, &base); - if (m_wordSelection) { - SkIRect wordBounds = m_wordBounds; - if (!m_outsideWord) - wordBounds.inset(-TOUCH_SLOP, -TOUCH_SLOP); - DBG_NAV_LOGD("x=%d y=%d wordBounds=(%d,%d,r=%d,b=%d)" - " found=(%d,%d,r=%d,b=%d)", x, y, wordBounds.fLeft, wordBounds.fTop, - wordBounds.fRight, wordBounds.fBottom, found.fLeft, found.fTop, - found.fRight, found.fBottom); - if (wordBounds.contains(x, y)) { - DBG_NAV_LOG("wordBounds.contains=true"); - m_outsideWord = false; - return; - } - m_outsideWord = true; - if (found.fBottom <= wordBounds.fTop) - m_hitTopLeft = true; - else if (found.fTop >= wordBounds.fBottom) - m_hitTopLeft = false; - else - m_hitTopLeft = (found.fLeft + found.fRight) - < (wordBounds.fLeft + wordBounds.fRight); - } - DBG_NAV_LOGD("x=%d y=%d m_startSelection=%s %s=(%d, %d, %d, %d)" - " m_extendSelection=%s", - x, y, m_startSelection ? "true" : "false", - m_hitTopLeft ? "m_selStart" : "m_selEnd", - found.fLeft, found.fTop, found.fRight, found.fBottom, - m_extendSelection ? "true" : "false"); - if (m_hitTopLeft) { - m_startBase = base; - m_selStart = found; - } else { - m_endBase = base; - m_selEnd = found; - } - swapAsNeeded(); -} - -SkIRect SelectText::findClosest(FirstCheck& check, const SkPicture& picture, - int* base) -{ - LineCheck lineCheck(check.focusX(), check.focusY(), check.getArea()); - TextCanvas lineChecker(&lineCheck); - lineChecker.drawPicture(const_cast<SkPicture&>(picture)); - lineCheck.finish(m_selRegion); - check.setLines(&lineCheck); - TextCanvas checker(&check); - checker.drawPicture(const_cast<SkPicture&>(picture)); - check.finishGlyph(); - return check.adjustedBounds(base); -} - -SkIRect SelectText::findEdge(const SkPicture& picture, const SkIRect& area, - int x, int y, bool left, int* base) -{ - SkIRect result; - result.setEmpty(); - FirstCheck center(x, y, area); - center.setRecordGlyph(); - int closestBase; - SkIRect closest = findClosest(center, picture, &closestBase); - SkIRect sloppy = closest; - sloppy.inset(-TOUCH_SLOP, -TOUCH_SLOP); - if (!sloppy.contains(x, y)) { - DBG_NAV_LOGD("sloppy=(%d, %d, %d, %d) area=(%d, %d, %d, %d) x/y=%d,%d", - sloppy.fLeft, sloppy.fTop, sloppy.fRight, sloppy.fBottom, - area.fLeft, area.fTop, area.fRight, area.fBottom, x, y); - return result; - } - EdgeCheck edge(x, y, area, center, left); - do { // detect left or right until there's a gap - DBG_NAV_LOGD("edge=%p picture=%p area=%d,%d,%d,%d", - &edge, &picture, area.fLeft, area.fTop, area.fRight, area.fBottom); - TextCanvas checker(&edge); - checker.drawPicture(const_cast<SkPicture&>(picture)); - edge.finishGlyph(); - if (!edge.adjacent()) { - if (result.isEmpty()) { - *base = closestBase; - DBG_NAV_LOGD("closest=%d,%d,%d,%d", closest.fLeft, - closest.fTop, closest.fRight, closest.fBottom); - return closest; - } - DBG_NAV_LOG("adjacent break"); - break; - } - int nextBase; - const SkIRect& next = edge.bestBounds(&nextBase); - if (next.isEmpty()) { - DBG_NAV_LOG("empty"); - break; - } - if (result == next) { - DBG_NAV_LOG("result == next"); - break; - } - *base = nextBase; - result = next; - edge.shiftStart(result); - } while (true); - if (!result.isEmpty()) { - *base += area.fTop; - result.offset(area.fLeft, area.fTop); - } - return result; -} - -SkIRect SelectText::findLeft(const SkPicture& picture, const SkIRect& area, - int x, int y, int* base) -{ - return findEdge(picture, area, x, y, true, base); -} - -SkIRect SelectText::findRight(const SkPicture& picture, const SkIRect& area, - int x, int y, int* base) -{ - return findEdge(picture, area, x, y, false, base); -} - -const String SelectText::getSelection() -{ - if (!m_picture) - return String(); - SkIRect clipRect; - clipRect.set(0, 0, m_picture->width(), m_picture->height()); - String result = text(*m_picture, clipRect, m_selStart, m_startBase, - m_selEnd, m_endBase, m_flipped); - DBG_NAV_LOGD("clip=(%d,%d,%d,%d)" - " m_selStart=(%d, %d, %d, %d) m_selEnd=(%d, %d, %d, %d)", - clipRect.fLeft, clipRect.fTop, clipRect.fRight, clipRect.fBottom, - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, - m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom); - DBG_NAV_LOGD("text=%s", result.latin1().data()); // uses CString - return result; -} - -void SelectText::getSelectionArrow(SkPath* path) -{ - const int arrow[] = { - 0, 14, 3, 11, 5, 15, 9, 15, 7, 11, 11, 11 - }; - for (unsigned index = 0; index < sizeof(arrow)/sizeof(arrow[0]); index += 2) - path->lineTo(arrow[index], arrow[index + 1]); - path->close(); -} - -void SelectText::getSelectionCaret(SkPath* path) -{ - SkScalar height = m_selStart.fBottom - m_selStart.fTop; - SkScalar dist = height / 4; - path->moveTo(0, -height / 2); - path->rLineTo(0, height); - path->rLineTo(-dist, dist); - path->rMoveTo(0, -0.5f); - path->rLineTo(dist * 2, 0); - path->rMoveTo(0, 0.5f); - path->rLineTo(-dist, -dist); -} - -bool SelectText::hitCorner(int cx, int cy, int x, int y) const -{ - SkIRect test; - test.set(cx, cy, cx, cy); - test.inset(-SLOP, -SLOP); - return test.contains(x, y); -} - -bool SelectText::hitSelection(int x, int y) const -{ - x -= m_startOffset.fX; - y -= m_startOffset.fY; - int left = m_selStart.fLeft - CONTROL_WIDTH / 2; - int top = m_selStart.fBottom + CONTROL_HEIGHT / 2; - if (hitCorner(left, top, x, y)) - return true; - int right = m_selEnd.fRight + CONTROL_WIDTH / 2; - int bottom = m_selEnd.fBottom + CONTROL_HEIGHT / 2; - if (hitCorner(right, bottom, x, y)) - return true; - return m_selRegion.contains(x, y); -} - -void SelectText::moveSelection(const IntRect& vis, int x, int y) -{ - if (!m_picture) - return; - x -= m_startOffset.fX; - y -= m_startOffset.fY; - setVisibleRect(vis); - SkIRect clipRect = m_visibleRect; - clipRect.join(m_selStart); - clipRect.join(m_selEnd); - FirstCheck center(x, y, clipRect); - int base; - SkIRect found = findClosest(center, *m_picture, &base); - if (m_hitTopLeft || !m_extendSelection) { - m_startBase = base; - m_selStart = found; - } - if (!m_hitTopLeft || !m_extendSelection) { - m_endBase = base; - m_selEnd = found; - } - swapAsNeeded(); - DBG_NAV_LOGD("x=%d y=%d extendSelection=%s m_selStart=(%d, %d, %d, %d)" - " m_selEnd=(%d, %d, %d, %d)", x, y, m_extendSelection ? "true" : "false", - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, - m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom); -} - -void SelectText::reset() -{ - DBG_NAV_LOG("m_extendSelection=false"); - m_selStart.setEmpty(); - m_lastStart.setEmpty(); - m_lastDrawnStart.setEmpty(); - m_selEnd.setEmpty(); - m_lastEnd.setEmpty(); - m_lastDrawnEnd.setEmpty(); - m_extendSelection = false; - m_startSelection = false; - SkSafeUnref(m_picture); - m_picture = 0; - m_layerId = 0; -} - -IntPoint SelectText::selectableText(const CachedRoot* root) -{ - int x = 0; - int y = 0; - SkPicture* picture = root->pictureAt(&x, &y, &m_layerId); - if (!picture) { - DBG_NAV_LOG("picture==0"); - return IntPoint(0, 0); - } - int width = picture->width(); - int height = picture->height(); - IntRect vis(0, 0, width, height); - FirstCheck center(width >> 1, height >> 1, vis); - int base; - const SkIRect& closest = findClosest(center, *picture, &base); - return IntPoint((closest.fLeft + closest.fRight) >> 1, - (closest.fTop + closest.fBottom) >> 1); -} - -void SelectText::selectAll() -{ - if (!m_picture) - return; - m_selStart = findFirst(*m_picture, &m_startBase); - m_selEnd = findLast(*m_picture, &m_endBase); - m_extendSelection = true; -} - -int SelectText::selectionX() const -{ - return (m_hitTopLeft ? m_selStart.fLeft : m_selEnd.fRight) + m_startOffset.fX; -} - -int SelectText::selectionY() const -{ - const SkIRect& rect = m_hitTopLeft ? m_selStart : m_selEnd; - return ((rect.fTop + rect.fBottom) >> 1) + m_startOffset.fY; -} - -void SelectText::setVisibleRect(const IntRect& vis) -{ - DBG_NAV_LOGD("vis=(%d,%d,w=%d,h=%d) offset=(%d,%d)", - vis.x(), vis.y(), vis.width(), vis.height(), m_startOffset.fX, - m_startOffset.fY); - m_visibleRect = vis; - m_visibleRect.offset(-m_startOffset.fX, -m_startOffset.fY); -} - -bool SelectText::startSelection(const CachedRoot* root, const IntRect& vis, - int x, int y) -{ - m_wordSelection = false; - m_startOffset.set(x, y); - DBG_NAV_LOGD("x/y=(%d,%d)", x, y); - SkSafeUnref(m_picture); - m_picture = root->pictureAt(&x, &y, &m_layerId); - DBG_NAV_LOGD("m_picture=%p m_layerId=%d x/y=(%d,%d)", m_picture, m_layerId, - x, y); - if (!m_picture) { - DBG_NAV_LOG("picture==0"); - return false; - } - m_picture->ref(); - m_startOffset.fX -= x; - m_startOffset.fY -= y; - m_original.fX = x; - m_original.fY = y; - setVisibleRect(vis); - if (m_selStart.isEmpty()) { - DBG_NAV_LOGD("empty start picture=(%d,%d) x=%d y=%d", - m_picture->width(), m_picture->height(), x, y); - m_startSelection = true; - return true; - } - int left = m_selStart.fLeft - CONTROL_WIDTH / 2; - int top = m_selStart.fBottom + CONTROL_HEIGHT / 2; - m_hitTopLeft = hitCorner(left, top, x, y); - int right = m_selEnd.fRight + CONTROL_WIDTH / 2; - int bottom = m_selEnd.fBottom + CONTROL_HEIGHT / 2; - bool hitBottomRight = hitCorner(right, bottom, x, y); - DBG_NAV_LOGD("picture=(%d,%d) left=%d top=%d right=%d bottom=%d x=%d y=%d", - m_picture->width(), m_picture->height(),left, top, right, bottom, x, y); - if (m_hitTopLeft && (!hitBottomRight || y - top < bottom - y)) { - DBG_NAV_LOG("hit top left"); - m_original.fX -= m_selStart.fLeft; - m_original.fY -= (m_selStart.fTop + m_selStart.fBottom) >> 1; - } else if (hitBottomRight) { - DBG_NAV_LOG("hit bottom right"); - m_original.fX -= m_selEnd.fRight; - m_original.fY -= (m_selEnd.fTop + m_selEnd.fBottom) >> 1; - } - return m_hitTopLeft || hitBottomRight; -} - -/* selects the word at (x, y) -* a word is normally delimited by spaces -* a string of digits (even with inside spaces) is a word (for phone numbers) -* FIXME: digit find isn't implemented yet -* returns true if a word was selected -*/ -bool SelectText::wordSelection(const CachedRoot* root, const IntRect& vis, - int x, int y) -{ - IntRect tapArea = IntRect(x - TOUCH_SLOP, y - TOUCH_SLOP, TOUCH_SLOP * 2, - TOUCH_SLOP * 2); - if (!startSelection(root, tapArea, x, y)) - return false; - extendSelection(tapArea, x, y); - if (m_selStart.isEmpty()) - return false; - setDrawPointer(false); - setVisibleRect(vis); - SkIRect ivisBounds = m_visibleRect; - ivisBounds.join(m_selStart); - ivisBounds.join(m_selEnd); - DBG_NAV_LOGD("m_selStart=(%d,%d,r=%d,b=%d) m_selEnd=(%d,%d,r=%d,b=%d)" - " ivisBounds=(%d,%d,r=%d,b=%d)", - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, - m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom, - ivisBounds.fLeft, ivisBounds.fTop, ivisBounds.fRight, ivisBounds.fBottom); - m_selRegion.setEmpty(); - buildSelection(*m_picture, ivisBounds, m_selStart, m_startBase, - m_selEnd, m_endBase, &m_selRegion); - x = m_selStart.fLeft; - y = (m_selStart.fTop + m_selStart.fBottom) >> 1; - SkIRect clipRect = m_visibleRect; - clipRect.fLeft -= m_visibleRect.width() >> 1; - clipRect.fLeft = std::max(clipRect.fLeft, 0); - int base; - SkIRect left = findLeft(*m_picture, clipRect, x, y, &base); - if (!left.isEmpty()) { - m_startBase = base; - m_selStart = left; - } - x = m_selEnd.fRight; - y = (m_selEnd.fTop + m_selEnd.fBottom) >> 1; - clipRect = m_visibleRect; - clipRect.fRight += m_visibleRect.width() >> 1; - SkIRect right = findRight(*m_picture, clipRect, x, y, &base); - if (!right.isEmpty()) { - m_endBase = base; - m_selEnd = right; - } - DBG_NAV_LOGD("m_selStart=(%d, %d, %d, %d) m_selEnd=(%d, %d, %d, %d)", - m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, - m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom); - if (!left.isEmpty() || !right.isEmpty()) { - m_wordBounds = m_selStart; - m_wordBounds.join(m_selEnd); - m_extendSelection = m_wordSelection = true; - m_outsideWord = false; - return true; - } - return false; -} - -void SelectText::swapAsNeeded() -{ - if (m_selStart.fTop >= (m_selEnd.fTop + m_selEnd.fBottom) >> 1 - || (m_selEnd.fTop < (m_selStart.fTop + m_selStart.fBottom) >> 1 - && m_selStart.fRight > m_selEnd.fLeft)) - { - SkTSwap(m_startBase, m_endBase); - SkTSwap(m_selStart, m_selEnd); - m_hitTopLeft ^= true; - DBG_NAV_LOGD("m_hitTopLeft=%s", m_hitTopLeft ? "true" : "false"); - } -} - -} diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h deleted file mode 100644 index 42239cf..0000000 --- a/WebKit/android/nav/SelectText.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2008, 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 SELECT_TEXT_H -#define SELECT_TEXT_H - -#include "DrawExtra.h" -#include "IntPoint.h" -#include "IntRect.h" -#include "PlatformString.h" -#include "SkPath.h" -#include "SkPicture.h" -#include "SkRect.h" -#include "SkRegion.h" - -namespace android { - -class CachedRoot; - -class SelectText : public DrawExtra { -public: - SelectText(); - virtual ~SelectText(); - virtual void draw(SkCanvas* , LayerAndroid* , IntRect* ); - void extendSelection(const IntRect& vis, int x, int y); - const String getSelection(); - bool hitSelection(int x, int y) const; - void moveSelection(const IntRect& vis, int x, int y); - void reset(); - IntPoint selectableText(const CachedRoot* ); - void selectAll(); - int selectionX() const; - int selectionY() const; - void setDrawPointer(bool drawPointer) { m_drawPointer = drawPointer; } - void setExtendSelection(bool extend) { m_extendSelection = extend; } - bool startSelection(const CachedRoot* , const IntRect& vis, int x, int y); - bool wordSelection(const CachedRoot* , const IntRect& vis, int x, int y); -public: - float m_inverseScale; // inverse scale, x, y used for drawing select path - int m_selectX; - int m_selectY; -private: - class FirstCheck; - class EdgeCheck; - void drawSelectionPointer(SkCanvas* , IntRect* ); - void drawSelectionRegion(SkCanvas* , IntRect* ); - SkIRect findClosest(FirstCheck& , const SkPicture& , int* base); - SkIRect findEdge(const SkPicture& , const SkIRect& area, - int x, int y, bool left, int* base); - SkIRect findLeft(const SkPicture& picture, const SkIRect& area, - int x, int y, int* base); - SkIRect findRight(const SkPicture& picture, const SkIRect& area, - int x, int y, int* base); - static void getSelectionArrow(SkPath* ); - void getSelectionCaret(SkPath* ); - bool hitCorner(int cx, int cy, int x, int y) const; - void setVisibleRect(const IntRect& ); - void swapAsNeeded(); - SkIPoint m_original; // computed start of extend selection - SkIPoint m_startOffset; // difference from global to layer - SkIRect m_selStart; - SkIRect m_selEnd; - SkIRect m_lastStart; - SkIRect m_lastEnd; - SkIRect m_lastDrawnStart; - SkIRect m_lastDrawnEnd; - SkIRect m_wordBounds; - int m_startBase; - int m_endBase; - int m_layerId; - SkIRect m_visibleRect; // constrains picture computations to visible area - SkRegion m_lastSelRegion; - SkRegion m_selRegion; // computed from sel start, end - SkPicture m_startControl; - SkPicture m_endControl; - const SkPicture* m_picture; - bool m_drawPointer; - bool m_extendSelection; // false when trackball is moving pointer - bool m_flipped; - bool m_hitTopLeft; - bool m_startSelection; - bool m_wordSelection; - bool m_outsideWord; -}; - -} - -namespace WebCore { - -void ReverseBidi(UChar* chars, int len); - -} - -#endif diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp deleted file mode 100644 index ff5d73d..0000000 --- a/WebKit/android/nav/WebView.cpp +++ /dev/null @@ -1,2673 +0,0 @@ -/* - * Copyright 2007, 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 "webviewglue" - -#include "config.h" - -#include "AndroidAnimation.h" -#include "AndroidLog.h" -#include "BaseLayerAndroid.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "DrawExtra.h" -#include "FindCanvas.h" -#include "Frame.h" -#include "GraphicsJNI.h" -#include "HTMLInputElement.h" -#include "IntPoint.h" -#include "IntRect.h" -#include "LayerAndroid.h" -#include "Node.h" -#include "utils/Functor.h" -#include "private/hwui/DrawGlInfo.h" -#include "PlatformGraphicsContext.h" -#include "PlatformString.h" -#include "ScrollableLayerAndroid.h" -#include "SelectText.h" -#include "SkCanvas.h" -#include "SkDumpCanvas.h" -#include "SkPicture.h" -#include "SkRect.h" -#include "SkTime.h" -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif -#include "TilesManager.h" -#include "WebCoreJni.h" -#include "WebRequestContext.h" -#include "WebViewCore.h" -#include "android_graphics.h" - -#ifdef GET_NATIVE_VIEW -#undef GET_NATIVE_VIEW -#endif - -#define GET_NATIVE_VIEW(env, obj) ((WebView*)env->GetIntField(obj, gWebViewField)) - -#include <JNIUtility.h> -#include <JNIHelp.h> -#include <jni.h> -#include <android_runtime/android_util_AssetManager.h> -#include <ui/KeycodeLabels.h> -#include <utils/AssetManager.h> -#include <wtf/text/AtomicString.h> -#include <wtf/text/CString.h> - -namespace android { - -static jfieldID gWebViewField; - -//------------------------------------- - -static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[]) -{ - jmethodID m = env->GetMethodID(clazz, name, signature); - LOG_ASSERT(m, "Could not find method %s", name); - return m; -} - -//------------------------------------- -// This class provides JNI for making calls into native code from the UI side -// of the multi-threaded WebView. -class WebView -{ -public: -enum FrameCachePermission { - DontAllowNewer, - AllowNewer, - AllowNewest -}; - -enum DrawExtras { // keep this in sync with WebView.java - DrawExtrasNone = 0, - DrawExtrasFind = 1, - DrawExtrasSelection = 2, - DrawExtrasCursorRing = 3 -}; - -struct JavaGlue { - jweak m_obj; - jmethodID m_calcOurContentVisibleRectF; - jmethodID m_overrideLoading; - jmethodID m_scrollBy; - jmethodID m_sendMoveFocus; - jmethodID m_sendMoveMouse; - jmethodID m_sendMoveMouseIfLatest; - jmethodID m_sendMotionUp; - jmethodID m_domChangedFocus; - jmethodID m_getScaledMaxXScroll; - jmethodID m_getScaledMaxYScroll; - jmethodID m_getVisibleRect; - jmethodID m_rebuildWebTextView; - jmethodID m_viewInvalidate; - jmethodID m_viewInvalidateRect; - jmethodID m_postInvalidateDelayed; - jmethodID m_inFullScreenMode; - jfieldID m_rectLeft; - jfieldID m_rectTop; - jmethodID m_rectWidth; - jmethodID m_rectHeight; - jfieldID m_rectFLeft; - jfieldID m_rectFTop; - jmethodID m_rectFWidth; - jmethodID m_rectFHeight; - AutoJObject object(JNIEnv* env) { - return getRealObject(env, m_obj); - } -} m_javaGlue; - -WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, AssetManager* am) : - m_ring((WebViewCore*) viewImpl) -{ - jclass clazz = env->FindClass("android/webkit/WebView"); - // m_javaGlue = new JavaGlue; - m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView); - m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z"); - m_javaGlue.m_calcOurContentVisibleRectF = GetJMethod(env, clazz, "calcOurContentVisibleRectF", "(Landroid/graphics/RectF;)V"); - m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); - m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V"); - m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); - m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(ZZ)V"); - m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V"); - m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()V"); - m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); - m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); - m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); - m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V"); - m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); - m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V"); - m_javaGlue.m_postInvalidateDelayed = GetJMethod(env, clazz, - "viewInvalidateDelayed", "(JIIII)V"); - m_javaGlue.m_inFullScreenMode = GetJMethod(env, clazz, "inFullScreenMode", "()Z"); - env->DeleteLocalRef(clazz); - - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class"); - m_javaGlue.m_rectLeft = env->GetFieldID(rectClass, "left", "I"); - m_javaGlue.m_rectTop = env->GetFieldID(rectClass, "top", "I"); - m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I"); - m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); - env->DeleteLocalRef(rectClass); - - jclass rectClassF = env->FindClass("android/graphics/RectF"); - LOG_ASSERT(rectClassF, "Could not find RectF class"); - m_javaGlue.m_rectFLeft = env->GetFieldID(rectClassF, "left", "F"); - m_javaGlue.m_rectFTop = env->GetFieldID(rectClassF, "top", "F"); - m_javaGlue.m_rectFWidth = GetJMethod(env, rectClassF, "width", "()F"); - m_javaGlue.m_rectFHeight = GetJMethod(env, rectClassF, "height", "()F"); - env->DeleteLocalRef(rectClassF); - - env->SetIntField(javaWebView, gWebViewField, (jint)this); - m_viewImpl = (WebViewCore*) viewImpl; - m_frameCacheUI = 0; - m_navPictureUI = 0; - m_generation = 0; - m_heightCanMeasure = false; - m_lastDx = 0; - m_lastDxTime = 0; - m_ringAnimationEnd = 0; - m_baseLayer = 0; - m_glDrawFunctor = 0; - if (drawableDir.isEmpty()) - m_buttonSkin = 0; - else - m_buttonSkin = new RenderSkinButton(am, drawableDir); -#if USE(ACCELERATED_COMPOSITING) - m_glWebViewState = 0; -#endif -} - -~WebView() -{ - if (m_javaGlue.m_obj) - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->DeleteWeakGlobalRef(m_javaGlue.m_obj); - m_javaGlue.m_obj = 0; - } -#if USE(ACCELERATED_COMPOSITING) - // We must remove the m_glWebViewState prior to deleting m_baseLayer. If we - // do not remove it here, we risk having BaseTiles trying to paint using a - // deallocated base layer. - stopGL(); -#endif - delete m_frameCacheUI; - delete m_navPictureUI; - SkSafeUnref(m_baseLayer); - delete m_glDrawFunctor; - delete m_buttonSkin; -} - -void stopGL() -{ -#if USE(ACCELERATED_COMPOSITING) - delete m_glWebViewState; - m_glWebViewState = 0; -#endif -} - -WebViewCore* getWebViewCore() const { - return m_viewImpl; -} - -// removes the cursor altogether (e.g., when going to a new page) -void clearCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - m_viewImpl->m_hasCursorBounds = false; - root->clearCursor(); - viewInvalidate(); -} - -// leaves the cursor where it is, but suppresses drawing it -void hideCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - hideCursor(root); -} - -void hideCursor(CachedRoot* root) -{ - DBG_NAV_LOG("inner"); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); - viewInvalidate(); -} - -#if DUMP_NAV_CACHE -void debugDump() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) - root->mDebug.print(); -} -#endif - -// Traverse our stored array of buttons that are in our picture, and update -// their subpictures according to their current state. -// Called from the UI thread. This is the one place in the UI thread where we -// access the buttons stored in the WebCore thread. -// hasFocus keeps track of whether the WebView has focus && windowFocus. -// If not, we do not want to draw the button in a selected or pressed state -void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) -{ - bool cursorIsOnButton = false; - const CachedFrame* cachedFrame; - const CachedNode* cachedCursor = 0; - // Lock the mutex, since we now share with the WebCore thread. - m_viewImpl->gButtonMutex.lock(); - if (m_viewImpl->m_buttons.size() && m_buttonSkin) { - // FIXME: In a future change, we should keep track of whether the selection - // has changed to short circuit (note that we would still need to update - // if we received new buttons from the WebCore thread). - WebCore::Node* cursor = 0; - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - cachedCursor = root->currentCursor(&cachedFrame); - if (cachedCursor) - cursor = (WebCore::Node*) cachedCursor->nodePointer(); - } - - // Traverse the array, and update each button, depending on whether it - // is selected. - Container* end = m_viewImpl->m_buttons.end(); - for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) { - RenderSkinAndroid::State state = RenderSkinAndroid::kNormal; - if (ptr->matches(cursor)) { - cursorIsOnButton = true; - // If the WebView is out of focus/window focus, set the state to - // normal, but still keep track of the fact that the selected is a - // button - if (hasFocus) { - if (pressed || m_ring.m_isPressed) - state = RenderSkinAndroid::kPressed; - else if (SkTime::GetMSecs() < m_ringAnimationEnd) - state = RenderSkinAndroid::kFocused; - } - } - ptr->updateFocusState(state, m_buttonSkin); - } - } - m_viewImpl->gButtonMutex.unlock(); - if (invalidate && cachedCursor && cursorIsOnButton) { - const WebCore::IntRect& b = cachedCursor->bounds(cachedFrame); - viewInvalidateRect(b.x(), b.y(), b.right(), b.bottom()); - } -} - -// The caller has already determined that the desired document rect corresponds -// to the main picture, and not a layer -void scrollRectOnScreen(const IntRect& rect) -{ - if (rect.isEmpty()) - return; - SkRect visible; - calcOurContentVisibleRect(&visible); - int dx = 0; - int left = rect.x(); - int right = rect.right(); - if (left < visible.fLeft) { - dx = left - visible.fLeft; - // Only scroll right if the entire width can fit on screen. - } else if (right > visible.fRight && right - left < visible.width()) { - dx = right - visible.fRight; - } - int dy = 0; - int top = rect.y(); - int bottom = rect.bottom(); - if (top < visible.fTop) { - dy = top - visible.fTop; - // Only scroll down if the entire height can fit on screen - } else if (bottom > visible.fBottom && bottom - top < visible.height()) { - dy = bottom - visible.fBottom; - } - if ((dx|dy) == 0 || !scrollBy(dx, dy)) - return; - viewInvalidate(); -} - -void calcOurContentVisibleRect(SkRect* r) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass rectClass = env->FindClass("android/graphics/RectF"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(FFFF)V"); - jobject jRect = env->NewObject(rectClass, init, 0, 0, 0, 0); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_calcOurContentVisibleRectF, jRect); - r->fLeft = env->GetFloatField(jRect, m_javaGlue.m_rectFLeft); - r->fTop = env->GetFloatField(jRect, m_javaGlue.m_rectFTop); - r->fRight = r->fLeft + env->CallFloatMethod(jRect, m_javaGlue.m_rectFWidth); - r->fBottom = r->fTop + env->CallFloatMethod(jRect, m_javaGlue.m_rectFHeight); - env->DeleteLocalRef(rectClass); - env->DeleteLocalRef(jRect); - checkException(env); -} - -void resetCursorRing() -{ - m_ringAnimationEnd = 0; - m_viewImpl->m_hasCursorBounds = false; -} - -bool drawCursorPreamble(CachedRoot* root) -{ - const CachedFrame* frame; - const CachedNode* node = root->currentCursor(&frame); - if (!node) { - DBG_NAV_LOGV("%s", "!node"); - resetCursorRing(); - return false; - } - m_ring.setIsButton(node); - if (node->isHidden()) { - DBG_NAV_LOG("node->isHidden()"); - m_viewImpl->m_hasCursorBounds = false; - return false; - } -#if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer() && root->rootLayer()) { - LayerAndroid* layer = const_cast<LayerAndroid*>(root->rootLayer()); - SkRect visible; - calcOurContentVisibleRect(&visible); - layer->updateFixedLayersPositions(visible); - layer->updatePositions(); - } -#endif - setVisibleRect(root); - m_ring.m_root = root; - m_ring.m_frame = frame; - m_ring.m_node = node; - SkMSec time = SkTime::GetMSecs(); - m_ring.m_isPressed = time < m_ringAnimationEnd - && m_ringAnimationEnd != UINT_MAX; - return true; -} - -void drawCursorPostamble() -{ - if (m_ringAnimationEnd == UINT_MAX) - return; - SkMSec time = SkTime::GetMSecs(); - if (time < m_ringAnimationEnd) { - // views assume that inval bounds coordinates are non-negative - WebCore::IntRect invalBounds(0, 0, INT_MAX, INT_MAX); - invalBounds.intersect(m_ring.m_absBounds); - postInvalidateDelayed(m_ringAnimationEnd - time, invalBounds); - } else { - hideCursor(const_cast<CachedRoot*>(m_ring.m_root)); - } -} - -bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::IntRect& webViewRect, - int titleBarHeight, WebCore::IntRect& clip, float scale, int extras) -{ -#if USE(ACCELERATED_COMPOSITING) - if (!m_baseLayer || inFullScreenMode()) - return false; - - if (!m_glWebViewState) { - m_glWebViewState = new GLWebViewState(&m_viewImpl->gButtonMutex); - if (m_baseLayer->content()) { - SkRegion region; - SkIRect rect; - rect.set(0, 0, m_baseLayer->content()->width(), m_baseLayer->content()->height()); - region.setRect(rect); - m_glWebViewState->setBaseLayer(m_baseLayer, region, false, false); - } - } - - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - if (extras == DrawExtrasCursorRing) - resetCursorRing(); - return false; - } - DrawExtra* extra = 0; - switch (extras) { - case DrawExtrasFind: - extra = &m_findOnPage; - break; - case DrawExtrasSelection: - extra = &m_selectText; - break; - case DrawExtrasCursorRing: - if (drawCursorPreamble(root) && m_ring.setup()) { - if (!m_ring.m_isButton) - extra = &m_ring; - drawCursorPostamble(); - } - break; - default: - ; - } - - unsigned int pic = m_glWebViewState->currentPictureCounter(); - - SkPicture picture; - IntRect rect(0, 0, 0, 0); - bool allowSame = false; - m_glWebViewState->resetRings(); - if (extra) { - if (extra == &m_ring) { - m_glWebViewState->setRings(m_ring.rings(), m_ring.m_isPressed); - } else { - LayerAndroid mainPicture(m_navPictureUI); - PictureSet* content = m_baseLayer->content(); - SkCanvas* canvas = picture.beginRecording(content->width(), - content->height()); - extra->draw(canvas, &mainPicture, &rect); - picture.endRecording(); - } - } else if (extras == DrawExtrasCursorRing && m_ring.m_isButton) { - const CachedFrame* cachedFrame; - const CachedNode* cachedCursor = root->currentCursor(&cachedFrame); - if (cachedCursor) { - rect = cachedCursor->bounds(cachedFrame); - allowSame = true; - } - } - m_glWebViewState->setExtra(m_baseLayer, picture, rect, allowSame); - - LayerAndroid* compositeLayer = compositeRoot(); - if (compositeLayer) - compositeLayer->setExtra(extra); - - SkRect visibleRect; - calcOurContentVisibleRect(&visibleRect); - bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, invalRect, - webViewRect, titleBarHeight, clip, scale); - if (ret || m_glWebViewState->currentPictureCounter() != pic) - return true; -#endif - return false; -} - -PictureSet* draw(SkCanvas* canvas, SkColor bgColor, int extras, bool split) -{ - PictureSet* ret = 0; - if (!m_baseLayer) { - canvas->drawColor(bgColor); - return ret; - } - - // draw the content of the base layer first - PictureSet* content = m_baseLayer->content(); - int sc = canvas->save(SkCanvas::kClip_SaveFlag); - canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), - content->height()), SkRegion::kDifference_Op); - canvas->drawColor(bgColor); - canvas->restoreToCount(sc); - if (content->draw(canvas)) - ret = split ? new PictureSet(*content) : 0; - - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - if (extras == DrawExtrasCursorRing) - resetCursorRing(); - return ret; - } - LayerAndroid mainPicture(m_navPictureUI); - DrawExtra* extra = 0; - switch (extras) { - case DrawExtrasFind: - extra = &m_findOnPage; - break; - case DrawExtrasSelection: - extra = &m_selectText; - break; - case DrawExtrasCursorRing: - if (drawCursorPreamble(root) && m_ring.setup()) { - if (!m_ring.m_isButton) - extra = &m_ring; - drawCursorPostamble(); - } - break; - default: - ; - } - if (extra) { - IntRect dummy; // inval area, unused for now - extra->draw(canvas, &mainPicture, &dummy); - } -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* compositeLayer = compositeRoot(); - if (!compositeLayer) - return ret; - compositeLayer->setExtra(extra); - SkRect visible; - calcOurContentVisibleRect(&visible); - // call this to be sure we've adjusted for any scrolling or animations - // before we actually draw - compositeLayer->updateFixedLayersPositions(visible); - compositeLayer->updatePositions(); - // We have to set the canvas' matrix on the base layer - // (to have fixed layers work as intended) - SkAutoCanvasRestore restore(canvas, true); - m_baseLayer->setMatrix(canvas->getTotalMatrix()); - canvas->resetMatrix(); - m_baseLayer->draw(canvas); -#endif - return ret; -} - - -bool cursorIsTextInput(FrameCachePermission allowNewer) -{ - CachedRoot* root = getFrameCache(allowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursor = root->currentCursor(); - if (!cursor) { - DBG_NAV_LOG("!cursor"); - return false; - } - DBG_NAV_LOGD("%s", cursor->isTextInput() ? "true" : "false"); - return cursor->isTextInput(); -} - -void cursorRingBounds(WebCore::IntRect* bounds) -{ - DBG_NAV_LOGD("%s", ""); - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedFrame* cachedFrame; - const CachedNode* cachedNode = root->currentCursor(&cachedFrame); - if (cachedNode) { - *bounds = cachedNode->cursorRingBounds(cachedFrame); - DBG_NAV_LOGD("bounds={%d,%d,%d,%d}", bounds->x(), bounds->y(), - bounds->width(), bounds->height()); - return; - } - } - *bounds = WebCore::IntRect(0, 0, 0, 0); -} - -void fixCursor() -{ - m_viewImpl->gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_viewImpl->m_hasCursorBounds; - IntRect bounds = m_viewImpl->m_cursorBounds; - m_viewImpl->gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return; - int x, y; - const CachedFrame* frame; - const CachedNode* node = m_frameCacheUI->findAt(bounds, &frame, &x, &y, true); - if (!node) - return; - // require that node have approximately the same bounds (+/- 4) and the same - // center (+/- 2) - IntPoint oldCenter = IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); - IntRect newBounds = node->bounds(frame); - IntPoint newCenter = IntPoint(newBounds.x() + (newBounds.width() >> 1), - newBounds.y() + (newBounds.height() >> 1)); - DBG_NAV_LOGD("oldCenter=(%d,%d) newCenter=(%d,%d)" - " bounds=(%d,%d,w=%d,h=%d) newBounds=(%d,%d,w=%d,h=%d)", - oldCenter.x(), oldCenter.y(), newCenter.x(), newCenter.y(), - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); - if (abs(oldCenter.x() - newCenter.x()) > 2) - return; - if (abs(oldCenter.y() - newCenter.y()) > 2) - return; - if (abs(bounds.x() - newBounds.x()) > 4) - return; - if (abs(bounds.y() - newBounds.y()) > 4) - return; - if (abs(bounds.right() - newBounds.right()) > 4) - return; - if (abs(bounds.bottom() - newBounds.bottom()) > 4) - return; - DBG_NAV_LOGD("node=%p frame=%p x=%d y=%d bounds=(%d,%d,w=%d,h=%d)", - node, frame, x, y, bounds.x(), bounds.y(), bounds.width(), - bounds.height()); - m_frameCacheUI->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); -} - -CachedRoot* getFrameCache(FrameCachePermission allowNewer) -{ - if (!m_viewImpl->m_updatedFrameCache) { - DBG_NAV_LOGV("%s", "!m_viewImpl->m_updatedFrameCache"); - return m_frameCacheUI; - } - if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) { - DBG_NAV_LOGD("allowNewer==DontAllowNewer m_viewImpl->m_lastGeneration=%d" - " < m_generation=%d", m_viewImpl->m_lastGeneration, m_generation); - return m_frameCacheUI; - } - DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true"); - const CachedFrame* oldCursorFrame; - const CachedNode* oldCursorNode = m_frameCacheUI ? - m_frameCacheUI->currentCursor(&oldCursorFrame) : 0; -#if USE(ACCELERATED_COMPOSITING) - int layerId = -1; - if (oldCursorNode && oldCursorNode->isInLayer()) { - const LayerAndroid* cursorLayer = oldCursorFrame->layer(oldCursorNode) - ->layer(m_frameCacheUI->rootLayer()); - if (cursorLayer) - layerId = cursorLayer->uniqueId(); - } -#endif - // get id from old layer and use to find new layer - bool oldFocusIsTextInput = false; - void* oldFocusNodePointer = 0; - if (m_frameCacheUI) { - const CachedNode* oldFocus = m_frameCacheUI->currentFocus(); - if (oldFocus) { - oldFocusIsTextInput = oldFocus->isTextInput(); - oldFocusNodePointer = oldFocus->nodePointer(); - } - } - m_viewImpl->gFrameCacheMutex.lock(); - delete m_frameCacheUI; - SkSafeUnref(m_navPictureUI); - m_viewImpl->m_updatedFrameCache = false; - m_frameCacheUI = m_viewImpl->m_frameCacheKit; - m_navPictureUI = m_viewImpl->m_navPictureKit; - m_viewImpl->m_frameCacheKit = 0; - m_viewImpl->m_navPictureKit = 0; - m_viewImpl->gFrameCacheMutex.unlock(); - if (m_frameCacheUI) - m_frameCacheUI->setRootLayer(compositeRoot()); -#if USE(ACCELERATED_COMPOSITING) - if (layerId >= 0) { - SkRect visible; - calcOurContentVisibleRect(&visible); - LayerAndroid* layer = const_cast<LayerAndroid*>( - m_frameCacheUI->rootLayer()); - if (layer) { - layer->updateFixedLayersPositions(visible); - layer->updatePositions(); - } - } -#endif - fixCursor(); - if (oldFocusIsTextInput) { - const CachedNode* newFocus = m_frameCacheUI->currentFocus(); - if (newFocus && oldFocusNodePointer != newFocus->nodePointer() - && newFocus->isTextInput() - && newFocus != m_frameCacheUI->currentCursor()) { - // The focus has changed. We may need to update things. - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_domChangedFocus); - checkException(env); - } - } - if (oldCursorNode && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) - viewInvalidate(); // redraw in case cursor ring is still visible - return m_frameCacheUI; -} - -int getScaledMaxXScroll() -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxXScroll); - checkException(env); - return result; -} - -int getScaledMaxYScroll() -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxYScroll); - checkException(env); - return result; -} - -IntRect getVisibleRect() -{ - IntRect rect; - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject jRect = env->CallObjectMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getVisibleRect); - checkException(env); - rect.setX(env->GetIntField(jRect, m_javaGlue.m_rectLeft)); - checkException(env); - rect.setY(env->GetIntField(jRect, m_javaGlue.m_rectTop)); - checkException(env); - rect.setWidth(env->CallIntMethod(jRect, m_javaGlue.m_rectWidth)); - checkException(env); - rect.setHeight(env->CallIntMethod(jRect, m_javaGlue.m_rectHeight)); - checkException(env); - env->DeleteLocalRef(jRect); - checkException(env); - return rect; -} - -static CachedFrame::Direction KeyToDirection(int32_t keyCode) -{ - switch (keyCode) { - case AKEYCODE_DPAD_RIGHT: - DBG_NAV_LOGD("keyCode=%s", "right"); - return CachedFrame::RIGHT; - case AKEYCODE_DPAD_LEFT: - DBG_NAV_LOGD("keyCode=%s", "left"); - return CachedFrame::LEFT; - case AKEYCODE_DPAD_DOWN: - DBG_NAV_LOGD("keyCode=%s", "down"); - return CachedFrame::DOWN; - case AKEYCODE_DPAD_UP: - DBG_NAV_LOGD("keyCode=%s", "up"); - return CachedFrame::UP; - default: - DBG_NAV_LOGD("bad key %d sent", keyCode); - return CachedFrame::UNINITIALIZED; - } -} - -WTF::String imageURI(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - return root ? root->imageURI(x, y) : WTF::String(); -} - -bool cursorWantsKeyEvents() -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedNode* focus = root->currentCursor(); - if (focus) - return focus->wantsKeyEvents(); - } - return false; -} - - -/* returns true if the key had no effect (neither scrolled nor changed cursor) */ -bool moveCursor(int keyCode, int count, bool ignoreScroll) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return true; - } - - m_viewImpl->m_moveGeneration++; - CachedFrame::Direction direction = KeyToDirection(keyCode); - const CachedFrame* cachedFrame, * oldFrame = 0; - const CachedNode* cursor = root->currentCursor(&oldFrame); - WebCore::IntPoint cursorLocation = root->cursorLocation(); - DBG_NAV_LOGD("old cursor %d (nativeNode=%p) cursorLocation={%d, %d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : 0, cursorLocation.x(), cursorLocation.y()); - WebCore::IntRect visibleRect = setVisibleRect(root); - int xMax = getScaledMaxXScroll(); - int yMax = getScaledMaxYScroll(); - root->setMaxScroll(xMax, yMax); - const CachedNode* cachedNode = 0; - int dx = 0; - int dy = 0; - int counter = count; - while (--counter >= 0) { - WebCore::IntPoint scroll = WebCore::IntPoint(0, 0); - cachedNode = root->moveCursor(direction, &cachedFrame, &scroll); - dx += scroll.x(); - dy += scroll.y(); - } - DBG_NAV_LOGD("new cursor %d (nativeNode=%p) cursorLocation={%d, %d}" - "bounds={%d,%d,w=%d,h=%d}", cachedNode ? cachedNode->index() : 0, - cachedNode ? cachedNode->nodePointer() : 0, - root->cursorLocation().x(), root->cursorLocation().y(), - cachedNode ? cachedNode->bounds(cachedFrame).x() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).y() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).width() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).height() : 0); - // If !m_heightCanMeasure (such as in the browser), we want to scroll no - // matter what - if (!ignoreScroll && (!m_heightCanMeasure || - !cachedNode || - (cursor && cursor->nodePointer() == cachedNode->nodePointer()))) - { - if (count == 1 && dx != 0 && dy == 0 && -m_lastDx == dx && - SkTime::GetMSecs() - m_lastDxTime < 1000) - root->checkForJiggle(&dx); - DBG_NAV_LOGD("scrollBy %d,%d", dx, dy); - if ((dx | dy)) - this->scrollBy(dx, dy); - m_lastDx = dx; - m_lastDxTime = SkTime::GetMSecs(); - } - bool result = false; - if (cachedNode) { - showCursorUntimed(); - m_viewImpl->updateCursorBounds(root, cachedFrame, cachedNode); - root->setCursor(const_cast<CachedFrame*>(cachedFrame), - const_cast<CachedNode*>(cachedNode)); - const CachedNode* focus = root->currentFocus(); - bool clearTextEntry = cachedNode != focus && focus - && cachedNode->nodePointer() != focus->nodePointer() && focus->isTextInput(); - // Stop painting the caret if the old focus was a text input and so is the new cursor. - bool stopPaintingCaret = clearTextEntry && cachedNode->wantsKeyEvents(); - sendMoveMouseIfLatest(clearTextEntry, stopPaintingCaret); - } else { - int docHeight = root->documentHeight(); - int docWidth = root->documentWidth(); - if (visibleRect.bottom() + dy > docHeight) - dy = docHeight - visibleRect.bottom(); - else if (visibleRect.y() + dy < 0) - dy = -visibleRect.y(); - if (visibleRect.right() + dx > docWidth) - dx = docWidth - visibleRect.right(); - else if (visibleRect.x() < 0) - dx = -visibleRect.x(); - result = direction == CachedFrame::LEFT ? dx >= 0 : - direction == CachedFrame::RIGHT ? dx <= 0 : - direction == CachedFrame::UP ? dy >= 0 : dy <= 0; - } - return result; -} - -void notifyProgressFinished() -{ - DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); - rebuildWebTextView(); -#if DEBUG_NAV_UI - if (m_frameCacheUI) { - const CachedNode* focus = m_frameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : 0); - } -#endif -} - -const CachedNode* findAt(CachedRoot* root, const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* rxPtr, int* ryPtr) -{ - *rxPtr = 0; - *ryPtr = 0; - *framePtr = 0; - if (!root) - return 0; - setVisibleRect(root); - return root->findAt(rect, framePtr, rxPtr, ryPtr, true); -} - -IntRect setVisibleRect(CachedRoot* root) -{ - IntRect visibleRect = getVisibleRect(); - DBG_NAV_LOGD("getVisibleRect %d,%d,%d,%d", - visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height()); - root->setVisibleRect(visibleRect); - return visibleRect; -} - -void selectBestAt(const WebCore::IntRect& rect) -{ - const CachedFrame* frame; - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); - if (!node) { - DBG_NAV_LOGD("no nodes found root=%p", root); - root->rootHistory()->setMouseBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->setCursor(0, 0); - viewInvalidate(); - } else { - DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - WebCore::IntRect bounds = node->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - m_viewImpl->updateCursorBounds(root, frame, node); - showCursorTimed(); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - } - sendMoveMouseIfLatest(false, false); -} - -const CachedNode* m_cacheHitNode; -const CachedFrame* m_cacheHitFrame; - -bool pointInNavCache(int x, int y, int slop) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - return (m_cacheHitNode = findAt(root, rect, &m_cacheHitFrame, &rx, &ry)); -} - -bool motionUp(int x, int y, int slop) -{ - bool pageScrolled = false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* result = findAt(root, rect, &frame, &rx, &ry); - CachedHistory* history = root->rootHistory(); - if (!result) { - DBG_NAV_LOGD("no nodes found root=%p", root); - history->setNavBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); - int dx = root->checkForCenter(x, y); - if (dx) { - scrollBy(dx, 0); - pageScrolled = true; - } - sendMotionUp(frame ? (WebCore::Frame*) frame->framePointer() : 0, - 0, x, y); - viewInvalidate(); - return pageScrolled; - } - DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, - result->index(), x, y, rx, ry); - WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1); - history->setNavBounds(navBounds); - history->setMouseBounds(navBounds); - m_viewImpl->updateCursorBounds(root, frame, result); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(result)); - if (result->isSyntheticLink()) - overrideUrlLoading(result->getExport()); - else { - sendMotionUp( - (WebCore::Frame*) frame->framePointer(), - (WebCore::Node*) result->nodePointer(), rx, ry); - } - if (result->isTextInput() || result->isSelect() - || result->isContentEditable()) { - showCursorUntimed(); - } else - showCursorTimed(); - return pageScrolled; -} - -#if USE(ACCELERATED_COMPOSITING) -static const ScrollableLayerAndroid* findScrollableLayer( - const LayerAndroid* parent, int x, int y, SkIRect* foundBounds) { - SkRect bounds; - parent->bounds(&bounds); - // Check the parent bounds first; this will clip to within a masking layer's - // bounds. - if (parent->masksToBounds() && !bounds.contains(x, y)) - return 0; - // Move the hit test local to parent. - x -= bounds.fLeft; - y -= bounds.fTop; - int count = parent->countChildren(); - while (count--) { - const LayerAndroid* child = parent->getChild(count); - const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y, - foundBounds); - if (result) { - foundBounds->offset(bounds.fLeft, bounds.fTop); - if (parent->masksToBounds()) { - if (bounds.width() < foundBounds->width()) - foundBounds->fRight = foundBounds->fLeft + bounds.width(); - if (bounds.height() < foundBounds->height()) - foundBounds->fBottom = foundBounds->fTop + bounds.height(); - } - return result; - } - } - if (parent->contentIsScrollable()) { - foundBounds->set(0, 0, bounds.width(), bounds.height()); - return static_cast<const ScrollableLayerAndroid*>(parent); - } - return 0; -} -#endif - -int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds) -{ -#if USE(ACCELERATED_COMPOSITING) - const LayerAndroid* layerRoot = compositeRoot(); - if (!layerRoot) - return 0; - const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y, - bounds); - if (result) { - result->getScrollRect(layerRect); - return result->uniqueId(); - } -#endif - return 0; -} - -int getBlockLeftEdge(int x, int y, float scale) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (root) - return root->getBlockLeftEdge(x, y, scale); - return -1; -} - -void overrideUrlLoading(const WTF::String& url) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jstring jName = wtfStringToJstring(env, url); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_overrideLoading, jName); - env->DeleteLocalRef(jName); -} - -void setFindIsUp(bool up) -{ - DBG_NAV_LOGD("up=%d", up); - m_viewImpl->m_findIsUp = up; -} - -void setFindIsEmpty() -{ - DBG_NAV_LOG(""); - m_findOnPage.clearCurrentLocation(); -} - -void showCursorTimed() -{ - DBG_NAV_LOG(""); - m_ringAnimationEnd = SkTime::GetMSecs() + 500; - viewInvalidate(); -} - -void showCursorUntimed() -{ - DBG_NAV_LOG(""); - m_ring.m_isPressed = false; - m_ringAnimationEnd = UINT_MAX; - viewInvalidate(); -} - -void setHeightCanMeasure(bool measure) -{ - m_heightCanMeasure = measure; -} - -String getSelection() -{ - return m_selectText.getSelection(); -} - -void moveSelection(int x, int y) -{ - m_selectText.moveSelection(getVisibleRect(), x, y); -} - -IntPoint selectableText() -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return IntPoint(0, 0); - return m_selectText.selectableText(root); -} - -void selectAll() -{ - m_selectText.selectAll(); -} - -int selectionX() -{ - return m_selectText.selectionX(); -} - -int selectionY() -{ - return m_selectText.selectionY(); -} - -void resetSelection() -{ - m_selectText.reset(); -} - -bool startSelection(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return false; - return m_selectText.startSelection(root, getVisibleRect(), x, y); -} - -bool wordSelection(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return false; - return m_selectText.wordSelection(root, getVisibleRect(), x, y); -} - -bool extendSelection(int x, int y) -{ - m_selectText.extendSelection(getVisibleRect(), x, y); - return true; -} - -bool hitSelection(int x, int y) -{ - return m_selectText.hitSelection(x, y); -} - -void setExtendSelection() -{ - m_selectText.setExtendSelection(true); -} - -void setSelectionPointer(bool set, float scale, int x, int y) -{ - m_selectText.setDrawPointer(set); - if (!set) - return; - m_selectText.m_inverseScale = scale; - m_selectText.m_selectX = x; - m_selectText.m_selectY = y; -} - -void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr) -{ - DBG_NAV_LOGD("framePtr=%p nodePtr=%p", framePtr, nodePtr); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendMoveFocus, (jint) framePtr, (jint) nodePtr); - checkException(env); -} - -void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) -{ - DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMoveMouse, - (jint) framePtr, (jint) nodePtr, x, y); - checkException(env); -} - -void sendMoveMouseIfLatest(bool clearTextEntry, bool stopPaintingCaret) -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendMoveMouseIfLatest, clearTextEntry, stopPaintingCaret); - checkException(env); -} - -void sendMotionUp( - WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) -{ - m_viewImpl->m_touchGeneration = ++m_generation; - DBG_NAV_LOGD("m_generation=%d framePtr=%p nodePtr=%p x=%d y=%d", - m_generation, framePtr, nodePtr, x, y); - LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp, - m_generation, (jint) framePtr, (jint) nodePtr, x, y); - checkException(env); -} - -void findNext(bool forward) -{ - m_findOnPage.findNext(forward); - if (!m_findOnPage.currentMatchIsInLayer()) - scrollRectOnScreen(m_findOnPage.currentMatchBounds()); - viewInvalidate(); -} - -// With this call, WebView takes ownership of matches, and is responsible for -// deleting it. -void setMatches(WTF::Vector<MatchInfo>* matches, jboolean sameAsLastSearch) -{ - // If this search is the same as the last one, check against the old - // location to determine whether to scroll. If the same word is found - // in the same place, then do not scroll. - IntRect oldLocation; - bool checkAgainstOldLocation; - if (sameAsLastSearch && m_findOnPage.isCurrentLocationValid()) { - oldLocation = m_findOnPage.currentMatchBounds(); - checkAgainstOldLocation = true; - } else - checkAgainstOldLocation = false; - - m_findOnPage.setMatches(matches); - - if (!checkAgainstOldLocation - || oldLocation != m_findOnPage.currentMatchBounds()) { - // FIXME: Need to scroll if the match is in a layer. - if (!m_findOnPage.currentMatchIsInLayer()) - scrollRectOnScreen(m_findOnPage.currentMatchBounds()); - } - viewInvalidate(); -} - -int currentMatchIndex() -{ - return m_findOnPage.currentMatchIndex(); -} - -bool scrollBy(int dx, int dy) -{ - LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - bool result = env->CallBooleanMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_scrollBy, dx, dy, true); - checkException(env); - return result; -} - -bool hasCursorNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursorNode = root->currentCursor(); - DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p)", - cursorNode ? cursorNode->index() : -1, - cursorNode ? cursorNode->nodePointer() : 0); - return cursorNode; -} - -bool hasFocusNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* focusNode = root->currentFocus(); - DBG_NAV_LOGD("focusNode=%d (nodePointer=%p)", - focusNode ? focusNode->index() : -1, - focusNode ? focusNode->nodePointer() : 0); - return focusNode; -} - -void rebuildWebTextView() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_rebuildWebTextView); - checkException(env); -} - -void viewInvalidate() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidate); - checkException(env); -} - -void viewInvalidateRect(int l, int t, int r, int b) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b); - checkException(env); -} - -void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_postInvalidateDelayed, - delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom()); - checkException(env); -} - -bool inFullScreenMode() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jboolean result = env->CallBooleanMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_inFullScreenMode); - checkException(env); - return result; -} - -int moveGeneration() -{ - return m_viewImpl->m_moveGeneration; -} - -LayerAndroid* compositeRoot() const -{ - LOG_ASSERT(!m_baseLayer || m_baseLayer->countChildren() == 1, - "base layer can't have more than one child %s", __FUNCTION__); - if (m_baseLayer && m_baseLayer->countChildren() == 1) - return static_cast<LayerAndroid*>(m_baseLayer->getChild(0)); - else - return 0; -} - -#if ENABLE(ANDROID_OVERFLOW_SCROLL) -static void copyScrollPositionRecursive(const LayerAndroid* from, - LayerAndroid* root) -{ - if (!from || !root) - return; - for (int i = 0; i < from->countChildren(); i++) { - const LayerAndroid* l = from->getChild(i); - if (l->contentIsScrollable()) { - const SkPoint& pos = l->getPosition(); - LayerAndroid* match = root->findById(l->uniqueId()); - if (match && match->contentIsScrollable()) - match->setPosition(pos.fX, pos.fY); - } - copyScrollPositionRecursive(l, root); - } -} -#endif - -void setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndicator, - bool isPictureAfterFirstLayout) -{ -#if USE(ACCELERATED_COMPOSITING) - if (m_glWebViewState) - m_glWebViewState->setBaseLayer(layer, inval, showVisualIndicator, - isPictureAfterFirstLayout); -#endif - -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (layer) { - LayerAndroid* newCompositeRoot = static_cast<LayerAndroid*>(layer->getChild(0)); - copyScrollPositionRecursive(compositeRoot(), newCompositeRoot); - } -#endif - SkSafeUnref(m_baseLayer); - m_baseLayer = layer; - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return; - root->resetLayers(); - root->setRootLayer(compositeRoot()); -} - -void replaceBaseContent(PictureSet* set) -{ - if (!m_baseLayer) - return; - m_baseLayer->setContent(*set); - delete set; -} - -void copyBaseContentToPicture(SkPicture* picture) -{ - if (!m_baseLayer) - return; - PictureSet* content = m_baseLayer->content(); - m_baseLayer->drawCanvas(picture->beginRecording(content->width(), content->height(), - SkPicture::kUsePathBoundsForClip_RecordingFlag)); - picture->endRecording(); -} - -bool hasContent() { - if (!m_baseLayer) - return false; - return !m_baseLayer->content()->isEmpty(); -} - -void setFunctor(Functor* functor) { - delete m_glDrawFunctor; - m_glDrawFunctor = functor; -} - -Functor* getFunctor() { - return m_glDrawFunctor; -} - -private: // local state for WebView - // private to getFrameCache(); other functions operate in a different thread - CachedRoot* m_frameCacheUI; // navigation data ready for use - WebViewCore* m_viewImpl; - int m_generation; // associate unique ID with sent kit focus to match with ui - SkPicture* m_navPictureUI; - SkMSec m_ringAnimationEnd; - // Corresponds to the same-named boolean on the java side. - bool m_heightCanMeasure; - int m_lastDx; - SkMSec m_lastDxTime; - SelectText m_selectText; - FindOnPage m_findOnPage; - CursorRing m_ring; - BaseLayerAndroid* m_baseLayer; - Functor* m_glDrawFunctor; -#if USE(ACCELERATED_COMPOSITING) - GLWebViewState* m_glWebViewState; -#endif - const RenderSkinButton* m_buttonSkin; -}; // end of WebView class - - -/** - * This class holds a function pointer and parameters for calling drawGL into a specific - * viewport. The pointer to the Functor will be put on a framework display list to be called - * when the display list is replayed. - */ -class GLDrawFunctor : Functor { - public: - GLDrawFunctor(WebView* _wvInstance, - bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint), - WebCore::IntRect _viewRect, float _scale, int _extras) { - wvInstance = _wvInstance; - funcPtr = _funcPtr; - viewRect = _viewRect; - scale = _scale; - extras = _extras; - }; - status_t operator()(int messageId, void* data) { - if (viewRect.isEmpty()) { - // NOOP operation if viewport is empty - return 0; - } - - WebCore::IntRect inval; - int titlebarHeight = webViewRect.height() - viewRect.height(); - - uirenderer::DrawGlInfo* info = reinterpret_cast<uirenderer::DrawGlInfo*>(data); - WebCore::IntRect localViewRect = viewRect; - if (info->isLayer) - localViewRect.move(-1 * localViewRect.x(), -1 * localViewRect.y()); - - WebCore::IntRect clip(info->clipLeft, info->clipTop, - info->clipRight - info->clipLeft, - info->clipBottom - info->clipTop); - - bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, titlebarHeight, clip, scale, extras); - if (retVal) { - IntRect finalInval; - if (inval.isEmpty()) { - finalInval = webViewRect; - retVal = true; - } else { - finalInval.setX(webViewRect.x() + inval.x()); - finalInval.setY(webViewRect.y() + titlebarHeight + inval.y()); - finalInval.setWidth(inval.width()); - finalInval.setHeight(inval.height()); - } - info->dirtyLeft = finalInval.x(); - info->dirtyTop = finalInval.y(); - info->dirtyRight = finalInval.right(); - info->dirtyBottom = finalInval.bottom(); - } - // return 1 if invalidation needed, 0 otherwise - return retVal ? 1 : 0; - } - void updateRect(WebCore::IntRect& _viewRect) { - viewRect = _viewRect; - } - void updateViewRect(WebCore::IntRect& _viewRect) { - webViewRect = _viewRect; - } - private: - WebView* wvInstance; - bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, WebCore::IntRect&, int, WebCore::IntRect&, float, int); - WebCore::IntRect viewRect; - WebCore::IntRect webViewRect; - jfloat scale; - jint extras; -}; - -/* - * Native JNI methods - */ -static int nativeCacheHitFramePointer(JNIEnv *env, jobject obj) -{ - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitFrame->framePointer()); -} - -static jobject nativeCacheHitNodeBounds(JNIEnv *env, jobject obj) -{ - WebCore::IntRect bounds = GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->originalAbsoluteBounds(); - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, bounds.x(), - bounds.y(), bounds.right(), bounds.bottom()); - env->DeleteLocalRef(rectClass); - return rect; -} - -static int nativeCacheHitNodePointer(JNIEnv *env, jobject obj) -{ - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->nodePointer()); -} - -static bool nativeCacheHitIsPlugin(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->m_cacheHitNode->isPlugin(); -} - -static void nativeClearCursor(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearCursor(); -} - -static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, jstring drawableDir, - jobject jAssetManager) -{ - AssetManager* am = assetManagerForJavaObject(env, jAssetManager); - WTF::String dir = jstringToWtfString(env, drawableDir); - WebView* webview = new WebView(env, obj, viewImpl, dir, am); - // NEED THIS OR SOMETHING LIKE IT! - //Release(obj); -} - -static jint nativeCursorFramePointer(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - (void) root->currentCursor(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor() : 0; -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor(frame) : 0; -} - -static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedNode* cursor = root->currentCursor(frame); - if (cursor && cursor->wantsKeyEvents()) - return cursor; - return root->currentFocus(frame); -} - -static bool focusCandidateHasNextTextfield(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* cursor = root->currentCursor(); - if (!cursor || !cursor->isTextInput()) - cursor = root->currentFocus(); - if (!cursor || !cursor->isTextInput()) return false; - return root->nextTextField(cursor, 0); -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus() : 0; -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus(frame) : 0; -} - -static const CachedInput* getInputCandidate(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - cursor = root->currentFocus(&frame); - return cursor ? frame->textInput(cursor) : 0; -} - -static jboolean nativePageShouldHandleShiftAndArrows(JNIEnv *env, jobject obj) -{ - const CachedNode* focus = getFocusNode(env, obj); - if (!focus) return false; - // Plugins handle shift and arrows whether or not they have focus. - if (focus->isPlugin()) return true; - const CachedNode* cursor = getCursorNode(env, obj); - // ContentEditable nodes should only receive shift and arrows if they have - // both the cursor and the focus. - return cursor && cursor->nodePointer() == focus->nodePointer() - && cursor->isContentEditable(); -} - -static jobject nativeCursorNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, bounds.x(), - bounds.y(), bounds.right(), bounds.bottom()); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); -} - -static jobject nativeCursorPosition(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - const CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - WebCore::IntPoint pos = WebCore::IntPoint(0, 0); - if (root) - root->getSimulatedMousePosition(&pos); - jclass pointClass = env->FindClass("android/graphics/Point"); - jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); - jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); - env->DeleteLocalRef(pointClass); - return point; -} - -static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - return WebCore::IntRect(L, T, R - L, B - T); -} - -static bool nativeCursorIntersects(JNIEnv *env, jobject obj, jobject visRect) -{ - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - return node ? node->bounds(frame).intersects( - jrect_to_webrect(env, visRect)) : false; -} - -static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isAnchor() : false; -} - -static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isTextInput() : false; -} - -static jobject nativeCursorText(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getCursorNode(env, obj); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); -} - -static void nativeDebugDump(JNIEnv *env, jobject obj) -{ -#if DUMP_NAV_CACHE - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->debugDump(); -#endif -} - -static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, jint color, - jint extras, jboolean split) { - SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); - return reinterpret_cast<jint>(GET_NATIVE_VIEW(env, obj)->draw(canvas, color, extras, split)); -} - -static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, jobject jviewrect, - jfloat scale, jint extras) { - WebCore::IntRect viewRect; - if (jrect == NULL) { - viewRect = WebCore::IntRect(); - } else { - viewRect = jrect_to_webrect(env, jrect); - } - WebView *wvInstance = GET_NATIVE_VIEW(env, obj); - GLDrawFunctor* functor = new GLDrawFunctor(wvInstance, &android::WebView::drawGL, - viewRect, scale, extras); - wvInstance->setFunctor((Functor*) functor); - - WebCore::IntRect webViewRect; - if (jviewrect == NULL) { - webViewRect = WebCore::IntRect(); - } else { - webViewRect = jrect_to_webrect(env, jviewrect); - } - functor->updateViewRect(webViewRect); - - return (jint)functor; -} - -static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, jobject jviewrect) { - WebView *wvInstance = GET_NATIVE_VIEW(env, obj); - if (wvInstance != NULL) { - GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor(); - if (functor != NULL) { - WebCore::IntRect viewRect; - if (jrect == NULL) { - viewRect = WebCore::IntRect(); - } else { - viewRect = jrect_to_webrect(env, jrect); - } - functor->updateRect(viewRect); - - WebCore::IntRect webViewRect; - if (jviewrect == NULL) { - webViewRect = WebCore::IntRect(); - } else { - webViewRect = jrect_to_webrect(env, jviewrect); - } - functor->updateViewRect(webViewRect); - } - } -} - -static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj) -{ -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); - if (root) - return root->evaluateAnimations(); -#endif - return false; -} - -static void nativeSetBaseLayer(JNIEnv *env, jobject obj, jint layer, jobject inval, - jboolean showVisualIndicator, - jboolean isPictureAfterFirstLayout) -{ - BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer); - SkRegion invalRegion; - if (inval) - invalRegion = *GraphicsJNI::getNativeRegion(env, inval); - GET_NATIVE_VIEW(env, obj)->setBaseLayer(layerImpl, invalRegion, showVisualIndicator, - isPictureAfterFirstLayout); -} - -static void nativeReplaceBaseContent(JNIEnv *env, jobject obj, jint content) -{ - PictureSet* set = reinterpret_cast<PictureSet*>(content); - GET_NATIVE_VIEW(env, obj)->replaceBaseContent(set); -} - -static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pict) -{ - SkPicture* picture = GraphicsJNI::getNativePicture(env, pict); - GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture); -} - -static bool nativeHasContent(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->hasContent(); -} - -static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WTF::String uri = view->imageURI(x, y); - return wtfStringToJstring(env, uri); -} - -static jint nativeFocusCandidateFramePointer(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - (void) root->currentFocus(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); -} - -static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input && input->getType() == CachedInput::PASSWORD; -} - -static bool nativeFocusCandidateIsRtlText(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->isRtlText() : false; -} - -static bool nativeFocusCandidateIsTextInput(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - return node ? node->isTextInput() : false; -} - -static jint nativeFocusCandidateMaxLength(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->maxLength() : false; -} - -static jint nativeFocusCandidateIsAutoComplete(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->autoComplete() : false; -} - -static jobject nativeFocusCandidateName(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - const WTF::String& name = input->name(); - return wtfStringToJstring(env, name); -} - -static jobject createJavaRect(JNIEnv* env, int x, int y, int right, int bottom) -{ - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, x, y, right, bottom); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jobject nativeFocusCandidateNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getFocusCandidate(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - return createJavaRect(env, bounds.x(), bounds.y(), bounds.right(), bounds.bottom()); -} - -static jobject nativeFocusCandidatePaddingRect(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - // Note that the Java Rect is being used to pass four integers, rather than - // being used as an actual rectangle. - return createJavaRect(env, input->paddingLeft(), input->paddingTop(), - input->paddingRight(), input->paddingBottom()); -} - -static jint nativeFocusCandidatePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); -} - -static jobject nativeFocusCandidateText(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj, 0); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); -} - -static int nativeFocusCandidateLineHeight(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->lineHeight() : 0; -} - -static jfloat nativeFocusCandidateTextSize(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->textSize() : 0.f; -} - -static int nativeFocusCandidateType(JNIEnv *env, jobject obj) -{ - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return CachedInput::NONE; - - if (input->isTextArea()) - return CachedInput::TEXT_AREA; - - return input->getType(); -} - -static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusNode(env, obj); - return node ? node->isPlugin() : false; -} - -static jobject nativeFocusNodeBounds(JNIEnv *env, jobject obj) -{ - const CachedFrame* frame; - const CachedNode* node = getFocusNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, bounds.x(), - bounds.y(), bounds.right(), bounds.bottom()); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jint nativeFocusNodePointer(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusNode(env, obj); - return node ? reinterpret_cast<int>(node->nodePointer()) : 0; -} - -static bool nativeCursorWantsKeyEvents(JNIEnv* env, jobject jwebview) { - WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->cursorWantsKeyEvents(); -} - -static void nativeHideCursor(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->hideCursor(); -} - -static void nativeInstrumentReport(JNIEnv *env, jobject obj) -{ -#ifdef ANDROID_INSTRUMENT - TimeCounter::reportNow(); -#endif -} - -static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->selectBestAt(rect); -} - -static void nativeSelectAt(JNIEnv *env, jobject obj, jint x, jint y) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = IntRect(x, y , 1, 1); - view->selectBestAt(rect); - if (view->hasCursorNode()) - view->showCursorUntimed(); -} - -static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer) -{ - SkRect r; -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* layer = (LayerAndroid*) jlayer; - r = layer->bounds(); -#else - r.setEmpty(); -#endif - SkIRect irect; - r.round(&irect); - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, - irect.fRight, irect.fBottom); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect) -{ - SkIRect irect = jrect_to_webrect(env, jrect); -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); - if (root) { - SkRect rect; - rect.set(irect); - rect = root->subtractLayers(rect); - rect.round(&irect); - } -#endif - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, - irect.fRight, irect.fBottom); - env->DeleteLocalRef(rectClass); - return rect; -} - -static jint nativeTextGeneration(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->textGeneration() : 0; -} - -static bool nativePointInNavCache(JNIEnv *env, jobject obj, - int x, int y, int slop) -{ - return GET_NATIVE_VIEW(env, obj)->pointInNavCache(x, y, slop); -} - -static bool nativeMotionUp(JNIEnv *env, jobject obj, - int x, int y, int slop) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->motionUp(x, y, slop); -} - -static bool nativeHasCursorNode(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->hasCursorNode(); -} - -static bool nativeHasFocusNode(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->hasFocusNode(); -} - -static bool nativeMoveCursor(JNIEnv *env, jobject obj, - int key, int count, bool ignoreScroll) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->moveCursor(key, count, ignoreScroll); -} - -static void nativeRecordButtons(JNIEnv* env, jobject obj, bool hasFocus, - bool pressed, bool invalidate) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->nativeRecordButtons(hasFocus, pressed, invalidate); -} - -static void nativeSetFindIsUp(JNIEnv *env, jobject obj, jboolean isUp) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->setFindIsUp(isUp); -} - -static void nativeSetFindIsEmpty(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->setFindIsEmpty(); -} - -static void nativeShowCursorTimed(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->showCursorTimed(); -} - -static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure"); - view->setHeightCanMeasure(measure); -} - -static jobject nativeGetCursorRingBounds(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect; - view->cursorRingBounds(&webRect); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.right(), webRect.bottom()); - env->DeleteLocalRef(rectClass); - return rect; -} - -static int nativeFindAll(JNIEnv *env, jobject obj, jstring findLower, - jstring findUpper, jboolean sameAsLastSearch) -{ - // If one or the other is null, do not search. - if (!(findLower && findUpper)) - return 0; - // Obtain the characters for both the lower case string and the upper case - // string representing the same word. - const jchar* findLowerChars = env->GetStringChars(findLower, 0); - const jchar* findUpperChars = env->GetStringChars(findUpper, 0); - // If one or the other is null, do not search. - if (!(findLowerChars && findUpperChars)) { - if (findLowerChars) - env->ReleaseStringChars(findLower, findLowerChars); - if (findUpperChars) - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindAll"); - CachedRoot* root = view->getFrameCache(WebView::AllowNewer); - if (!root) { - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - int length = env->GetStringLength(findLower); - // If the lengths of the strings do not match, then they are not the same - // word, so do not search. - if (!length || env->GetStringLength(findUpper) != length) { - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return 0; - } - int width = root->documentWidth(); - int height = root->documentHeight(); - // Create a FindCanvas, which allows us to fake draw into it so we can - // figure out where our search string is rendered (and how many times). - FindCanvas canvas(width, height, (const UChar*) findLowerChars, - (const UChar*) findUpperChars, length << 1); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); - canvas.setBitmapDevice(bitmap); - root->draw(canvas); - WTF::Vector<MatchInfo>* matches = canvas.detachMatches(); - // With setMatches, the WebView takes ownership of matches - view->setMatches(matches, sameAsLastSearch); - - env->ReleaseStringChars(findLower, findLowerChars); - env->ReleaseStringChars(findUpper, findUpperChars); - checkException(env); - return canvas.found(); -} - -static void nativeFindNext(JNIEnv *env, jobject obj, bool forward) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindNext"); - view->findNext(forward); -} - -static int nativeFindIndex(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeFindIndex"); - return view->currentMatchIndex(); -} - -static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring updatedText, jint generation) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in nativeUpdateCachedTextfield"); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return; - const CachedNode* cachedFocusNode = root->currentFocus(); - if (!cachedFocusNode || !cachedFocusNode->isTextInput()) - return; - WTF::String webcoreString = jstringToWtfString(env, updatedText); - (const_cast<CachedNode*>(cachedFocusNode))->setExport(webcoreString); - root->setTextGeneration(generation); - checkException(env); -} - -static jint nativeGetBlockLeftEdge(JNIEnv *env, jobject obj, jint x, jint y, - jfloat scale) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - if (!view) - return -1; - return view->getBlockLeftEdge(x, y, scale); -} - -static void nativeDestroy(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOGD("nativeDestroy view: %p", view); - LOG_ASSERT(view, "view not set in nativeDestroy"); - delete view; -} - -static void nativeStopGL(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->stopGL(); -} - -static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* current = root->currentCursor(); - if (!current || !current->isTextInput()) - current = root->currentFocus(); - if (!current || !current->isTextInput()) - return false; - const CachedFrame* frame; - const CachedNode* next = root->nextTextField(current, &frame); - if (!next) - return false; - const WebCore::IntRect& bounds = next->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - view->getWebViewCore()->updateCursorBounds(root, frame, next); - view->showCursorUntimed(); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(next)); - view->sendMoveFocus(static_cast<WebCore::Frame*>(frame->framePointer()), - static_cast<WebCore::Node*>(next->nodePointer())); - if (!next->isInLayer()) - view->scrollRectOnScreen(bounds); - view->getWebViewCore()->m_moveGeneration++; - return true; -} - -static int nativeMoveGeneration(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - if (!view) - return 0; - return view->moveGeneration(); -} - -static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y) -{ - GET_NATIVE_VIEW(env, obj)->moveSelection(x, y); -} - -static void nativeResetSelection(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->resetSelection(); -} - -static jobject nativeSelectableText(JNIEnv* env, jobject obj) -{ - IntPoint pos = GET_NATIVE_VIEW(env, obj)->selectableText(); - jclass pointClass = env->FindClass("android/graphics/Point"); - jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); - jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); - env->DeleteLocalRef(pointClass); - return point; -} - -static void nativeSelectAll(JNIEnv* env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->selectAll(); -} - -static void nativeSetExtendSelection(JNIEnv *env, jobject obj) -{ - GET_NATIVE_VIEW(env, obj)->setExtendSelection(); -} - -static jboolean nativeStartSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->startSelection(x, y); -} - -static jboolean nativeWordSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->wordSelection(x, y); -} - -static void nativeExtendSelection(JNIEnv *env, jobject obj, int x, int y) -{ - GET_NATIVE_VIEW(env, obj)->extendSelection(x, y); -} - -static jobject nativeGetSelection(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - String selection = view->getSelection(); - return wtfStringToJstring(env, selection); -} - -static jboolean nativeHitSelection(JNIEnv *env, jobject obj, int x, int y) -{ - return GET_NATIVE_VIEW(env, obj)->hitSelection(x, y); -} - -static jint nativeSelectionX(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->selectionX(); -} - -static jint nativeSelectionY(JNIEnv *env, jobject obj) -{ - return GET_NATIVE_VIEW(env, obj)->selectionY(); -} - -static void nativeSetSelectionPointer(JNIEnv *env, jobject obj, jboolean set, - jfloat scale, jint x, jint y) -{ - GET_NATIVE_VIEW(env, obj)->setSelectionPointer(set, scale, x, y); -} - -#ifdef ANDROID_DUMP_DISPLAY_TREE -static void dumpToFile(const char text[], void* file) { - fwrite(text, 1, strlen(text), reinterpret_cast<FILE*>(file)); - fwrite("\n", 1, 1, reinterpret_cast<FILE*>(file)); -} -#endif - -static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) -{ -#ifdef ANDROID_DUMP_DISPLAY_TREE - WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - - if (view && view->getWebViewCore()) { - FILE* file = fopen(DISPLAY_TREE_LOG_FILE, "w"); - if (file) { - SkFormatDumper dumper(dumpToFile, file); - // dump the URL - if (jurl) { - const char* str = env->GetStringUTFChars(jurl, 0); - SkDebugf("Dumping %s to %s\n", str, DISPLAY_TREE_LOG_FILE); - dumpToFile(str, file); - env->ReleaseStringUTFChars(jurl, str); - } - // now dump the display tree - SkDumpCanvas canvas(&dumper); - // this will playback the picture into the canvas, which will - // spew its contents to the dumper - view->draw(&canvas, 0, 0, false); - // we're done with the file now - fwrite("\n", 1, 1, file); - fclose(file); - } -#if USE(ACCELERATED_COMPOSITING) - const LayerAndroid* rootLayer = view->compositeRoot(); - if (rootLayer) { - FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w"); - if (file) { - rootLayer->dumpLayers(file, 0); - fclose(file); - } - } -#endif - } -#endif -} - -static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y, - jobject rect, jobject bounds) -{ - WebView* view = GET_NATIVE_VIEW(env, jwebview); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - SkIRect nativeRect, nativeBounds; - int id = view->scrollableLayer(x, y, &nativeRect, &nativeBounds); - if (rect) - GraphicsJNI::irect_to_jrect(nativeRect, env, rect); - if (bounds) - GraphicsJNI::irect_to_jrect(nativeBounds, env, bounds); - return id; -} - -static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, - jint y) -{ -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - WebView* view = GET_NATIVE_VIEW(env, obj); - LayerAndroid* root = view->compositeRoot(); - if (!root) - return false; - LayerAndroid* layer = root->findById(layerId); - if (!layer || !layer->contentIsScrollable()) - return false; - return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); -#endif - return false; -} - -static void nativeSetExpandedTileBounds(JNIEnv*, jobject, jboolean enabled) -{ - TilesManager::instance()->setExpandedTileBounds(enabled); -} - -/* - * JNI registration - */ -static JNINativeMethod gJavaWebViewMethods[] = { - { "nativeCacheHitFramePointer", "()I", - (void*) nativeCacheHitFramePointer }, - { "nativeCacheHitIsPlugin", "()Z", - (void*) nativeCacheHitIsPlugin }, - { "nativeCacheHitNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeCacheHitNodeBounds }, - { "nativeCacheHitNodePointer", "()I", - (void*) nativeCacheHitNodePointer }, - { "nativeClearCursor", "()V", - (void*) nativeClearCursor }, - { "nativeCreate", "(ILjava/lang/String;Landroid/content/res/AssetManager;)V", - (void*) nativeCreate }, - { "nativeCursorFramePointer", "()I", - (void*) nativeCursorFramePointer }, - { "nativePageShouldHandleShiftAndArrows", "()Z", - (void*) nativePageShouldHandleShiftAndArrows }, - { "nativeCursorNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeCursorNodeBounds }, - { "nativeCursorNodePointer", "()I", - (void*) nativeCursorNodePointer }, - { "nativeCursorIntersects", "(Landroid/graphics/Rect;)Z", - (void*) nativeCursorIntersects }, - { "nativeCursorIsAnchor", "()Z", - (void*) nativeCursorIsAnchor }, - { "nativeCursorIsTextInput", "()Z", - (void*) nativeCursorIsTextInput }, - { "nativeCursorPosition", "()Landroid/graphics/Point;", - (void*) nativeCursorPosition }, - { "nativeCursorText", "()Ljava/lang/String;", - (void*) nativeCursorText }, - { "nativeCursorWantsKeyEvents", "()Z", - (void*)nativeCursorWantsKeyEvents }, - { "nativeDebugDump", "()V", - (void*) nativeDebugDump }, - { "nativeDestroy", "()V", - (void*) nativeDestroy }, - { "nativeDraw", "(Landroid/graphics/Canvas;IIZ)I", - (void*) nativeDraw }, - { "nativeGetDrawGLFunction", "(Landroid/graphics/Rect;Landroid/graphics/Rect;FI)I", - (void*) nativeGetDrawGLFunction }, - { "nativeUpdateDrawGLFunction", "(Landroid/graphics/Rect;Landroid/graphics/Rect;)V", - (void*) nativeUpdateDrawGLFunction }, - { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", - (void*) nativeDumpDisplayTree }, - { "nativeEvaluateLayersAnimations", "()Z", - (void*) nativeEvaluateLayersAnimations }, - { "nativeExtendSelection", "(II)V", - (void*) nativeExtendSelection }, - { "nativeFindAll", "(Ljava/lang/String;Ljava/lang/String;Z)I", - (void*) nativeFindAll }, - { "nativeFindNext", "(Z)V", - (void*) nativeFindNext }, - { "nativeFindIndex", "()I", - (void*) nativeFindIndex}, - { "nativeFocusCandidateFramePointer", "()I", - (void*) nativeFocusCandidateFramePointer }, - { "nativeFocusCandidateHasNextTextfield", "()Z", - (void*) focusCandidateHasNextTextfield }, - { "nativeFocusCandidateIsPassword", "()Z", - (void*) nativeFocusCandidateIsPassword }, - { "nativeFocusCandidateIsRtlText", "()Z", - (void*) nativeFocusCandidateIsRtlText }, - { "nativeFocusCandidateIsTextInput", "()Z", - (void*) nativeFocusCandidateIsTextInput }, - { "nativeFocusCandidateLineHeight", "()I", - (void*) nativeFocusCandidateLineHeight }, - { "nativeFocusCandidateMaxLength", "()I", - (void*) nativeFocusCandidateMaxLength }, - { "nativeFocusCandidateIsAutoComplete", "()Z", - (void*) nativeFocusCandidateIsAutoComplete }, - { "nativeFocusCandidateName", "()Ljava/lang/String;", - (void*) nativeFocusCandidateName }, - { "nativeFocusCandidateNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeFocusCandidateNodeBounds }, - { "nativeFocusCandidatePaddingRect", "()Landroid/graphics/Rect;", - (void*) nativeFocusCandidatePaddingRect }, - { "nativeFocusCandidatePointer", "()I", - (void*) nativeFocusCandidatePointer }, - { "nativeFocusCandidateText", "()Ljava/lang/String;", - (void*) nativeFocusCandidateText }, - { "nativeFocusCandidateTextSize", "()F", - (void*) nativeFocusCandidateTextSize }, - { "nativeFocusCandidateType", "()I", - (void*) nativeFocusCandidateType }, - { "nativeFocusIsPlugin", "()Z", - (void*) nativeFocusIsPlugin }, - { "nativeFocusNodeBounds", "()Landroid/graphics/Rect;", - (void*) nativeFocusNodeBounds }, - { "nativeFocusNodePointer", "()I", - (void*) nativeFocusNodePointer }, - { "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetCursorRingBounds }, - { "nativeGetSelection", "()Ljava/lang/String;", - (void*) nativeGetSelection }, - { "nativeHasCursorNode", "()Z", - (void*) nativeHasCursorNode }, - { "nativeHasFocusNode", "()Z", - (void*) nativeHasFocusNode }, - { "nativeHideCursor", "()V", - (void*) nativeHideCursor }, - { "nativeHitSelection", "(II)Z", - (void*) nativeHitSelection }, - { "nativeImageURI", "(II)Ljava/lang/String;", - (void*) nativeImageURI }, - { "nativeInstrumentReport", "()V", - (void*) nativeInstrumentReport }, - { "nativeLayerBounds", "(I)Landroid/graphics/Rect;", - (void*) nativeLayerBounds }, - { "nativeMotionUp", "(III)Z", - (void*) nativeMotionUp }, - { "nativeMoveCursor", "(IIZ)Z", - (void*) nativeMoveCursor }, - { "nativeMoveCursorToNextTextInput", "()Z", - (void*) nativeMoveCursorToNextTextInput }, - { "nativeMoveGeneration", "()I", - (void*) nativeMoveGeneration }, - { "nativeMoveSelection", "(II)V", - (void*) nativeMoveSelection }, - { "nativePointInNavCache", "(III)Z", - (void*) nativePointInNavCache }, - { "nativeRecordButtons", "(ZZZ)V", - (void*) nativeRecordButtons }, - { "nativeResetSelection", "()V", - (void*) nativeResetSelection }, - { "nativeSelectableText", "()Landroid/graphics/Point;", - (void*) nativeSelectableText }, - { "nativeSelectAll", "()V", - (void*) nativeSelectAll }, - { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V", - (void*) nativeSelectBestAt }, - { "nativeSelectAt", "(II)V", - (void*) nativeSelectAt }, - { "nativeSelectionX", "()I", - (void*) nativeSelectionX }, - { "nativeSelectionY", "()I", - (void*) nativeSelectionY }, - { "nativeSetExtendSelection", "()V", - (void*) nativeSetExtendSelection }, - { "nativeSetFindIsEmpty", "()V", - (void*) nativeSetFindIsEmpty }, - { "nativeSetFindIsUp", "(Z)V", - (void*) nativeSetFindIsUp }, - { "nativeSetHeightCanMeasure", "(Z)V", - (void*) nativeSetHeightCanMeasure }, - { "nativeSetBaseLayer", "(ILandroid/graphics/Region;ZZ)V", - (void*) nativeSetBaseLayer }, - { "nativeReplaceBaseContent", "(I)V", - (void*) nativeReplaceBaseContent }, - { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V", - (void*) nativeCopyBaseContentToPicture }, - { "nativeHasContent", "()Z", - (void*) nativeHasContent }, - { "nativeSetSelectionPointer", "(ZFII)V", - (void*) nativeSetSelectionPointer }, - { "nativeShowCursorTimed", "()V", - (void*) nativeShowCursorTimed }, - { "nativeStartSelection", "(II)Z", - (void*) nativeStartSelection }, - { "nativeStopGL", "()V", - (void*) nativeStopGL }, - { "nativeSubtractLayers", "(Landroid/graphics/Rect;)Landroid/graphics/Rect;", - (void*) nativeSubtractLayers }, - { "nativeTextGeneration", "()I", - (void*) nativeTextGeneration }, - { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", - (void*) nativeUpdateCachedTextfield }, - { "nativeWordSelection", "(II)Z", - (void*) nativeWordSelection }, - { "nativeGetBlockLeftEdge", "(IIF)I", - (void*) nativeGetBlockLeftEdge }, - { "nativeScrollableLayer", "(IILandroid/graphics/Rect;Landroid/graphics/Rect;)I", - (void*) nativeScrollableLayer }, - { "nativeScrollLayer", "(III)Z", - (void*) nativeScrollLayer }, - { "nativeSetExpandedTileBounds", "(Z)V", - (void*) nativeSetExpandedTileBounds }, -}; - -int registerWebView(JNIEnv* env) -{ - jclass clazz = env->FindClass("android/webkit/WebView"); - LOG_ASSERT(clazz, "Unable to find class android/webkit/WebView"); - gWebViewField = env->GetFieldID(clazz, "mNativeClass", "I"); - LOG_ASSERT(gWebViewField, "Unable to find android/webkit/WebView.mNativeClass"); - env->DeleteLocalRef(clazz); - - return jniRegisterNativeMethods(env, "android/webkit/WebView", gJavaWebViewMethods, NELEM(gJavaWebViewMethods)); -} - -} // namespace android diff --git a/WebKit/android/plugins/ANPBitmapInterface.cpp b/WebKit/android/plugins/ANPBitmapInterface.cpp deleted file mode 100644 index 4c6ad7c..0000000 --- a/WebKit/android/plugins/ANPBitmapInterface.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include "SkColorPriv.h" - -static bool anp_getPixelPacking(ANPBitmapFormat fmt, ANPPixelPacking* packing) { - switch (fmt) { - case kRGBA_8888_ANPBitmapFormat: - if (packing) { - packing->AShift = SK_A32_SHIFT; - packing->ABits = SK_A32_BITS; - packing->RShift = SK_R32_SHIFT; - packing->RBits = SK_R32_BITS; - packing->GShift = SK_G32_SHIFT; - packing->GBits = SK_G32_BITS; - packing->BShift = SK_B32_SHIFT; - packing->BBits = SK_B32_BITS; - } - return true; - case kRGB_565_ANPBitmapFormat: - if (packing) { - packing->AShift = 0; - packing->ABits = 0; - packing->RShift = SK_R16_SHIFT; - packing->RBits = SK_R16_BITS; - packing->GShift = SK_G16_SHIFT; - packing->GBits = SK_G16_BITS; - packing->BShift = SK_B16_SHIFT; - packing->BBits = SK_B16_BITS; - } - return true; - default: - break; - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPBitmapInterfaceV0_Init(ANPInterface* value) { - ANPBitmapInterfaceV0* i = reinterpret_cast<ANPBitmapInterfaceV0*>(value); - - ASSIGN(i, getPixelPacking); -} diff --git a/WebKit/android/plugins/ANPCanvasInterface.cpp b/WebKit/android/plugins/ANPCanvasInterface.cpp deleted file mode 100644 index d6d89ff..0000000 --- a/WebKit/android/plugins/ANPCanvasInterface.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" - -static ANPCanvas* anp_newCanvas(const ANPBitmap* bitmap) { - SkBitmap bm; - return new ANPCanvas(*SkANP::SetBitmap(&bm, *bitmap)); -} - -static void anp_deleteCanvas(ANPCanvas* canvas) { - delete canvas; -} - -static void anp_save(ANPCanvas* canvas) { - canvas->skcanvas->save(); -} - -static void anp_restore(ANPCanvas* canvas) { - canvas->skcanvas->restore(); -} - -static void anp_translate(ANPCanvas* canvas, float tx, float ty) { - canvas->skcanvas->translate(SkFloatToScalar(tx), SkFloatToScalar(ty)); -} - -static void anp_scale(ANPCanvas* canvas, float sx, float sy) { - canvas->skcanvas->scale(SkFloatToScalar(sx), SkFloatToScalar(sy)); -} - -static void anp_rotate(ANPCanvas* canvas, float degrees) { - canvas->skcanvas->rotate(SkFloatToScalar(degrees)); -} - -static void anp_skew(ANPCanvas* canvas, float kx, float ky) { - canvas->skcanvas->skew(SkFloatToScalar(kx), SkFloatToScalar(ky)); -} - -static void anp_clipRect(ANPCanvas* canvas, const ANPRectF* rect) { - SkRect r; - canvas->skcanvas->clipRect(*SkANP::SetRect(&r, *rect)); -} - -static void anp_clipPath(ANPCanvas* canvas, const ANPPath* path) { - canvas->skcanvas->clipPath(*path); -} -static void anp_concat(ANPCanvas* canvas, const ANPMatrix* matrix) { - canvas->skcanvas->concat(*matrix); -} - -static void anp_getTotalMatrix(ANPCanvas* canvas, ANPMatrix* matrix) { - const SkMatrix& src = canvas->skcanvas->getTotalMatrix(); - *matrix = *reinterpret_cast<const ANPMatrix*>(&src); -} - -static bool anp_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* r, - bool antialias) { - SkRect bounds; - if (canvas->skcanvas->getClipBounds(&bounds, - antialias ? SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) { - SkANP::SetRect(r, bounds); - return true; - } - return false; -} - -static bool anp_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* r) { - const SkRegion& clip = canvas->skcanvas->getTotalClip(); - if (!clip.isEmpty()) { - SkANP::SetRect(r, clip.getBounds()); - return true; - } - return false; -} - -static void anp_drawColor(ANPCanvas* canvas, ANPColor color) { - canvas->skcanvas->drawColor(color); -} - -static void anp_drawPaint(ANPCanvas* canvas, const ANPPaint* paint) { - canvas->skcanvas->drawPaint(*paint); -} - -static void anp_drawLine(ANPCanvas* canvas, float x0, float y0, - float x1, float y1, const ANPPaint* paint) { - canvas->skcanvas->drawLine(SkFloatToScalar(x0), SkFloatToScalar(y0), - SkFloatToScalar(x1), SkFloatToScalar(y1), *paint); -} - -static void anp_drawRect(ANPCanvas* canvas, const ANPRectF* rect, - const ANPPaint* paint) { - SkRect r; - canvas->skcanvas->drawRect(*SkANP::SetRect(&r, *rect), *paint); -} - -static void anp_drawOval(ANPCanvas* canvas, const ANPRectF* rect, - const ANPPaint* paint) { - SkRect r; - canvas->skcanvas->drawOval(*SkANP::SetRect(&r, *rect), *paint); -} - -static void anp_drawPath(ANPCanvas* canvas, const ANPPath* path, - const ANPPaint* paint) { - canvas->skcanvas->drawPath(*path, *paint); -} - -static void anp_drawText(ANPCanvas* canvas, const void* text, uint32_t length, - float x, float y, const ANPPaint* paint) { - canvas->skcanvas->drawText(text, length, - SkFloatToScalar(x), SkFloatToScalar(y), - *paint); -} - -static void anp_drawPosText(ANPCanvas* canvas, const void* text, - uint32_t byteLength, const float xy[], const ANPPaint* paint) { - canvas->skcanvas->drawPosText(text, byteLength, - reinterpret_cast<const SkPoint*>(xy), *paint); -} - -static void anp_drawBitmap(ANPCanvas* canvas, const ANPBitmap* bitmap, - float x, float y, const ANPPaint* paint) { - SkBitmap bm; - canvas->skcanvas->drawBitmap(*SkANP::SetBitmap(&bm, *bitmap), - SkFloatToScalar(x), SkFloatToScalar(y), - paint); -} - -static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap, - const ANPRectI* src, const ANPRectF* dst, - const ANPPaint* paint) { - SkBitmap bm; - SkRect dstR; - SkIRect srcR, *srcPtr = NULL; - - if (src) { - srcPtr = SkANP::SetRect(&srcR, *src); - } - canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap), srcPtr, - *SkANP::SetRect(&dstR, *dst), paint); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPCanvasInterfaceV0_Init(ANPInterface* value) { - ANPCanvasInterfaceV0* i = reinterpret_cast<ANPCanvasInterfaceV0*>(value); - - ASSIGN(i, newCanvas); - ASSIGN(i, deleteCanvas); - ASSIGN(i, save); - ASSIGN(i, restore); - ASSIGN(i, translate); - ASSIGN(i, scale); - ASSIGN(i, rotate); - ASSIGN(i, skew); - ASSIGN(i, clipRect); - ASSIGN(i, clipPath); - ASSIGN(i, concat); - ASSIGN(i, getTotalMatrix); - ASSIGN(i, getLocalClipBounds); - ASSIGN(i, getDeviceClipBounds); - ASSIGN(i, drawColor); - ASSIGN(i, drawPaint); - ASSIGN(i, drawLine); - ASSIGN(i, drawRect); - ASSIGN(i, drawOval); - ASSIGN(i, drawPath); - ASSIGN(i, drawText); - ASSIGN(i, drawPosText); - ASSIGN(i, drawBitmap); - ASSIGN(i, drawBitmapRect); -} diff --git a/WebKit/android/plugins/ANPEventInterface.cpp b/WebKit/android/plugins/ANPEventInterface.cpp deleted file mode 100644 index 2fdf159..0000000 --- a/WebKit/android/plugins/ANPEventInterface.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include "WebViewCore.h" -#include "PluginView.h" -#include "PluginWidgetAndroid.h" - -#include "JavaSharedClient.h" - -using namespace android; - -struct WrappedANPEvent { - WebViewCore* fWVC; - PluginWidgetAndroid* fPWA; - ANPEvent fEvent; -}; - -/* Its possible we may be called after the plugin that initiated the event - has been torn-down. Thus we check that the assicated webviewcore and - pluginwidget are still active before dispatching the event. - */ -static void send_anpevent(void* data) { - WrappedANPEvent* wrapper = static_cast<WrappedANPEvent*>(data); - WebViewCore* core = wrapper->fWVC; - PluginWidgetAndroid* widget = wrapper->fPWA; - - // be sure we're still alive before delivering the event - if (WebViewCore::isInstance(core) && core->isPlugin(widget)) { - widget->sendEvent(wrapper->fEvent); - } - delete wrapper; -} - -static void anp_postEvent(NPP instance, const ANPEvent* event) { - if (instance && instance->ndata && event) { - PluginView* pluginView = static_cast<PluginView*>(instance->ndata); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - WebViewCore* wvc = pluginWidget->webViewCore(); - - WrappedANPEvent* wrapper = new WrappedANPEvent; - // recored these, and recheck that they are valid before delivery - // in send_anpevent - wrapper->fWVC = pluginWidget->webViewCore(); - wrapper->fPWA = pluginWidget; - // make a copy of the event - wrapper->fEvent = *event; - JavaSharedClient::EnqueueFunctionPtr(send_anpevent, wrapper); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPEventInterfaceV0_Init(ANPInterface* value) { - ANPEventInterfaceV0* i = reinterpret_cast<ANPEventInterfaceV0*>(value); - - ASSIGN(i, postEvent); -} diff --git a/WebKit/android/plugins/ANPKeyCodes.h b/WebKit/android/plugins/ANPKeyCodes.h deleted file mode 100644 index 969679f..0000000 --- a/WebKit/android/plugins/ANPKeyCodes.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2008, 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 ANPKeyCodes_DEFINED -#define ANPKeyCodes_DEFINED - -/* List the key codes that are set to a plugin in the ANPKeyEvent. - - These exactly match the values in android/view/KeyEvent.java and the - corresponding .h file android/keycodes.h. -*/ -enum ANPKeyCodes { - kUnknown_ANPKeyCode = 0, - - kSoftLeft_ANPKeyCode = 1, - kSoftRight_ANPKeyCode = 2, - kHome_ANPKeyCode = 3, - kBack_ANPKeyCode = 4, - kCall_ANPKeyCode = 5, - kEndCall_ANPKeyCode = 6, - k0_ANPKeyCode = 7, - k1_ANPKeyCode = 8, - k2_ANPKeyCode = 9, - k3_ANPKeyCode = 10, - k4_ANPKeyCode = 11, - k5_ANPKeyCode = 12, - k6_ANPKeyCode = 13, - k7_ANPKeyCode = 14, - k8_ANPKeyCode = 15, - k9_ANPKeyCode = 16, - kStar_ANPKeyCode = 17, - kPound_ANPKeyCode = 18, - kDpadUp_ANPKeyCode = 19, - kDpadDown_ANPKeyCode = 20, - kDpadLeft_ANPKeyCode = 21, - kDpadRight_ANPKeyCode = 22, - kDpadCenter_ANPKeyCode = 23, - kVolumeUp_ANPKeyCode = 24, - kVolumeDown_ANPKeyCode = 25, - kPower_ANPKeyCode = 26, - kCamera_ANPKeyCode = 27, - kClear_ANPKeyCode = 28, - kA_ANPKeyCode = 29, - kB_ANPKeyCode = 30, - kC_ANPKeyCode = 31, - kD_ANPKeyCode = 32, - kE_ANPKeyCode = 33, - kF_ANPKeyCode = 34, - kG_ANPKeyCode = 35, - kH_ANPKeyCode = 36, - kI_ANPKeyCode = 37, - kJ_ANPKeyCode = 38, - kK_ANPKeyCode = 39, - kL_ANPKeyCode = 40, - kM_ANPKeyCode = 41, - kN_ANPKeyCode = 42, - kO_ANPKeyCode = 43, - kP_ANPKeyCode = 44, - kQ_ANPKeyCode = 45, - kR_ANPKeyCode = 46, - kS_ANPKeyCode = 47, - kT_ANPKeyCode = 48, - kU_ANPKeyCode = 49, - kV_ANPKeyCode = 50, - kW_ANPKeyCode = 51, - kX_ANPKeyCode = 52, - kY_ANPKeyCode = 53, - kZ_ANPKeyCode = 54, - kComma_ANPKeyCode = 55, - kPeriod_ANPKeyCode = 56, - kAltLeft_ANPKeyCode = 57, - kAltRight_ANPKeyCode = 58, - kShiftLeft_ANPKeyCode = 59, - kShiftRight_ANPKeyCode = 60, - kTab_ANPKeyCode = 61, - kSpace_ANPKeyCode = 62, - kSym_ANPKeyCode = 63, - kExplorer_ANPKeyCode = 64, - kEnvelope_ANPKeyCode = 65, - kNewline_ANPKeyCode = 66, - kDel_ANPKeyCode = 67, - kGrave_ANPKeyCode = 68, - kMinus_ANPKeyCode = 69, - kEquals_ANPKeyCode = 70, - kLeftBracket_ANPKeyCode = 71, - kRightBracket_ANPKeyCode = 72, - kBackslash_ANPKeyCode = 73, - kSemicolon_ANPKeyCode = 74, - kApostrophe_ANPKeyCode = 75, - kSlash_ANPKeyCode = 76, - kAt_ANPKeyCode = 77, - kNum_ANPKeyCode = 78, - kHeadSetHook_ANPKeyCode = 79, - kFocus_ANPKeyCode = 80, - kPlus_ANPKeyCode = 81, - kMenu_ANPKeyCode = 82, - kNotification_ANPKeyCode = 83, - kSearch_ANPKeyCode = 84, - kMediaPlayPause_ANPKeyCode = 85, - kMediaStop_ANPKeyCode = 86, - kMediaNext_ANPKeyCode = 87, - kMediaPrevious_ANPKeyCode = 88, - kMediaRewind_ANPKeyCode = 89, - kMediaFastForward_ANPKeyCode = 90, - kMute_ANPKeyCode = 91, - kPageUp_ANPKeyCode = 92, - kPageDown_ANPKeyCode = 93, - kPictsymbols_ANPKeyCode = 94, - kSwitchCharset_ANPKeyCode = 95, - kButtonA_ANPKeyCode = 96, - kButtonB_ANPKeyCode = 97, - kButtonC_ANPKeyCode = 98, - kButtonX_ANPKeyCode = 99, - kButtonY_ANPKeyCode = 100, - kButtonZ_ANPKeyCode = 101, - kButtonL1_ANPKeyCode = 102, - kButtonR1_ANPKeyCode = 103, - kButtonL2_ANPKeyCode = 104, - kButtonR2_ANPKeyCode = 105, - kButtonThumbL_ANPKeyCode = 106, - kButtonThumbR_ANPKeyCode = 107, - kButtonStart_ANPKeyCode = 108, - kButtonSelect_ANPKeyCode = 109, - kButtonMode_ANPKeyCode = 110, - kEscape_ANPKeyCode = 111, - kForwardDel_ANPKeyCode = 112, - kCtrlLeft_ANPKeyCode = 113, - kCtrlRight_ANPKeyCode = 114, - kCapsLock_ANPKeyCode = 115, - kScrollLock_ANPKeyCode = 116, - kMetaLeft_ANPKeyCode = 117, - kMetaRight_ANPKeyCode = 118, - kFunction_ANPKeyCode = 119, - kSysRq_ANPKeyCode = 120, - kBreak_ANPKeyCode = 121, - kMoveHome_ANPKeyCode = 122, - kMoveEnd_ANPKeyCode = 123, - kInsert_ANPKeyCode = 124, - kForward_ANPKeyCode = 125, - kMediaPlay_ANPKeyCode = 126, - kMediaPause_ANPKeyCode = 127, - kMediaClose_ANPKeyCode = 128, - kMediaEject_ANPKeyCode = 129, - kMediaRecord_ANPKeyCode = 130, - kF1_ANPKeyCode = 131, - kF2_ANPKeyCode = 132, - kF3_ANPKeyCode = 133, - kF4_ANPKeyCode = 134, - kF5_ANPKeyCode = 135, - kF6_ANPKeyCode = 136, - kF7_ANPKeyCode = 137, - kF8_ANPKeyCode = 138, - kF9_ANPKeyCode = 139, - kF10_ANPKeyCode = 140, - kF11_ANPKeyCode = 141, - kF12_ANPKeyCode = 142, - kNumLock_ANPKeyCode = 143, - kNumPad0_ANPKeyCode = 144, - kNumPad1_ANPKeyCode = 145, - kNumPad2_ANPKeyCode = 146, - kNumPad3_ANPKeyCode = 147, - kNumPad4_ANPKeyCode = 148, - kNumPad5_ANPKeyCode = 149, - kNumPad6_ANPKeyCode = 150, - kNumPad7_ANPKeyCode = 151, - kNumPad8_ANPKeyCode = 152, - kNumPad9_ANPKeyCode = 153, - kNumPadDivide_ANPKeyCode = 154, - kNumPadMultiply_ANPKeyCode = 155, - kNumPadSubtract_ANPKeyCode = 156, - kNumPadAdd_ANPKeyCode = 157, - kNumPadDot_ANPKeyCode = 158, - kNumPadComma_ANPKeyCode = 159, - kNumPadEnter_ANPKeyCode = 160, - kNumPadEquals_ANPKeyCode = 161, - kNumPadLeftParen_ANPKeyCode = 162, - kNumPadRightParen_ANPKeyCode = 163, - kVolumeMute_ANPKeyCode = 164, - kInfo_ANPKeyCode = 165, - kChannelUp_ANPKeyCode = 166, - kChannelDown_ANPKeyCode = 167, - kZoomIn_ANPKeyCode = 168, - kZoomOut_ANPKeyCode = 169, - kTv_ANPKeyCode = 170, - kWindow_ANPKeyCode = 171, - kGuide_ANPKeyCode = 172, - kDvr_ANPKeyCode = 173, - kBookmark_ANPKeyCode = 174, - kCaptions_ANPKeyCode = 175, - kSettings_ANPKeyCode = 176, - kTvPower_ANPKeyCode = 177, - kTvInput_ANPKeyCode = 178, - kStbPower_ANPKeyCode = 179, - kStbInput_ANPKeyCode = 180, - kAvrPower_ANPKeyCode = 181, - kAvrInput_ANPKeyCode = 182, - kProgRed_ANPKeyCode = 183, - kProgGreen_ANPKeyCode = 184, - kProgYellow_ANPKeyCode = 185, - kProgBlue_ANPKeyCode = 186, - kAppSwitch_ANPKeyCode = 187, - - // NOTE: If you add a new keycode here you must also add it to several other files. - // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. -}; - -#endif diff --git a/WebKit/android/plugins/ANPLogInterface.cpp b/WebKit/android/plugins/ANPLogInterface.cpp deleted file mode 100644 index 23a4ed6..0000000 --- a/WebKit/android/plugins/ANPLogInterface.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2008, 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 "webkitPlugin" - -#include "utils/Log.h" -#include "android_npapi.h" -#include <stdarg.h> - -static void anp_log(ANPLogType logType, const char format[], ...) { - va_list args; - va_start(args, format); - - android_LogPriority priority; - switch (logType) { - case kError_ANPLogType: - priority = ANDROID_LOG_ERROR; - break; - case kWarning_ANPLogType: - priority = ANDROID_LOG_WARN; - break; - case kDebug_ANPLogType: - priority = ANDROID_LOG_DEBUG; - break; - default: - priority = ANDROID_LOG_UNKNOWN; - break; - } - LOG_PRI_VA(priority, "plugin", format, args); - - va_end(args); -} - -void ANPLogInterfaceV0_Init(ANPInterface* value) { - ANPLogInterfaceV0* i = reinterpret_cast<ANPLogInterfaceV0*>(value); - - i->log = anp_log; -} diff --git a/WebKit/android/plugins/ANPMatrixInterface.cpp b/WebKit/android/plugins/ANPMatrixInterface.cpp deleted file mode 100644 index f322315..0000000 --- a/WebKit/android/plugins/ANPMatrixInterface.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" - -#ifdef SK_SCALAR_IS_FIXED -static void fromFloat(SkScalar dst[], const float src[], int n) { - for (int i = 0; i < n; i++) { - dst[i] = SkFloatToScalar(src[i]); - } -} - -static void toFloat(float dst[], const SkScalar src[], int n) { - for (int i = 0; i < n; i++) { - dst[i] = SkScalarToFloat(src[i]); - } -} -#endif - -static ANPMatrix* anp_newMatrix() { - return new ANPMatrix; -} - -static void anp_deleteMatrix(ANPMatrix* matrix) { - delete matrix; -} - -static ANPMatrixFlag anp_getFlags(const ANPMatrix* matrix) { - return matrix->getType(); -} - -static void anp_copy(ANPMatrix* dst, const ANPMatrix* src) { - *dst = *src; -} - -static void anp_get3x3(const ANPMatrix* matrix, float dst[9]) { - for (int i = 0; i < 9; i++) { - dst[i] = SkScalarToFloat(matrix->get(i)); - } -} - -static void anp_set3x3(ANPMatrix* matrix, const float src[9]) { - for (int i = 0; i < 9; i++) { - matrix->set(i, SkFloatToScalar(src[i])); - } -} - -static void anp_setIdentity(ANPMatrix* matrix) { - matrix->reset(); -} - -static void anp_preTranslate(ANPMatrix* matrix, float tx, float ty) { - matrix->preTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty)); -} - -static void anp_postTranslate(ANPMatrix* matrix, float tx, float ty) { - matrix->postTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty)); -} - -static void anp_preScale(ANPMatrix* matrix, float sx, float sy) { - matrix->preScale(SkFloatToScalar(sx), SkFloatToScalar(sy)); -} - -static void anp_postScale(ANPMatrix* matrix, float sx, float sy) { - matrix->postScale(SkFloatToScalar(sx), SkFloatToScalar(sy)); -} - -static void anp_preSkew(ANPMatrix* matrix, float kx, float ky) { - matrix->preSkew(SkFloatToScalar(kx), SkFloatToScalar(ky)); -} - -static void anp_postSkew(ANPMatrix* matrix, float kx, float ky) { - matrix->postSkew(SkFloatToScalar(kx), SkFloatToScalar(ky)); -} - -static void anp_preRotate(ANPMatrix* matrix, float degrees) { - matrix->preRotate(SkFloatToScalar(degrees)); -} - -static void anp_postRotate(ANPMatrix* matrix, float degrees) { - matrix->postRotate(SkFloatToScalar(degrees)); -} - -static void anp_preConcat(ANPMatrix* matrix, const ANPMatrix* other) { - matrix->preConcat(*other); -} - -static void anp_postConcat(ANPMatrix* matrix, const ANPMatrix* other) { - matrix->postConcat(*other); -} - -static bool anp_invert(ANPMatrix* dst, const ANPMatrix* src) { - return src->invert(dst); -} - -static void anp_mapPoints(ANPMatrix* matrix, float dst[], const float src[], - int32_t count) { -#ifdef SK_SCALAR_IS_FLOAT - matrix->mapPoints(reinterpret_cast<SkPoint*>(dst), - reinterpret_cast<const SkPoint*>(src), count); -#else - const int N = 64; - SkPoint tmp[N]; - do { - int n = count; - if (n > N) { - n = N; - } - fromFloat(&tmp[0].fX, src, n*2); - matrix->mapPoints(tmp, n); - toFloat(dst, &tmp[0].fX, n*2); - count -= n; - } while (count > 0); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPMatrixInterfaceV0_Init(ANPInterface* value) { - ANPMatrixInterfaceV0* i = reinterpret_cast<ANPMatrixInterfaceV0*>(value); - - ASSIGN(i, newMatrix); - ASSIGN(i, deleteMatrix); - ASSIGN(i, getFlags); - ASSIGN(i, copy); - ASSIGN(i, get3x3); - ASSIGN(i, set3x3); - ASSIGN(i, setIdentity); - ASSIGN(i, preTranslate); - ASSIGN(i, postTranslate); - ASSIGN(i, preScale); - ASSIGN(i, postScale); - ASSIGN(i, preSkew); - ASSIGN(i, postSkew); - ASSIGN(i, preRotate); - ASSIGN(i, postRotate); - ASSIGN(i, preConcat); - ASSIGN(i, postConcat); - ASSIGN(i, invert); - ASSIGN(i, mapPoints); -} diff --git a/WebKit/android/plugins/ANPOpenGLInterface.cpp b/WebKit/android/plugins/ANPOpenGLInterface.cpp deleted file mode 100644 index 839ec17..0000000 --- a/WebKit/android/plugins/ANPOpenGLInterface.cpp +++ /dev/null @@ -1,121 +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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" - -#include "ANPOpenGL_npapi.h" -#include "PluginView.h" -#include "PluginWidgetAndroid.h" -#include "MediaLayer.h" -#include "WebViewCore.h" -#include "Frame.h" -#include "Page.h" -#include "Chrome.h" -#include "ChromeClient.h" - -using namespace android; - -static WebCore::PluginView* pluginViewForInstance(NPP instance) { - if (instance && instance->ndata) - return static_cast<WebCore::PluginView*>(instance->ndata); - return WebCore::PluginView::currentPluginView(); -} - -static EGLContext anp_acquireContext(NPP instance) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer(); - - if (!mediaLayer) - return EGL_NO_CONTEXT; - - return mediaLayer->getTexture()->producerAcquireContext(); -} - -static ANPTextureInfo anp_lockTexture(NPP instance) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer(); - WebCore::DoubleBufferedTexture* texture = mediaLayer->getTexture(); - - // lock the texture and cache the internal info - WebCore::TextureInfo* info = texture->producerLock(); - mediaLayer->setCurrentTextureInfo(info); - - ANPTextureInfo anpInfo; - anpInfo.textureId = info->m_textureId; - anpInfo.width = (int32_t) info->m_width; - anpInfo.height = (int32_t) info->m_height; - anpInfo.internalFormat = info->m_internalFormat; - return anpInfo; -} - -static void anp_releaseTexture(NPP instance, const ANPTextureInfo* textureInfo) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer(); - WebCore::DoubleBufferedTexture* texture = mediaLayer->getTexture(); - - //copy the info into our internal structure - WebCore::TextureInfo* info = mediaLayer->getCurrentTextureInfo(); - info->m_textureId = textureInfo->textureId; - info->m_width = textureInfo->width; - info->m_height = textureInfo->height; - info->m_internalFormat = textureInfo->internalFormat; - - texture->producerReleaseAndSwap(); - - // invalidate the java view so that this content is drawn - pluginWidget->viewInvalidate(); -} - -static void anp_invertPluginContent(NPP instance, bool isContentInverted) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer(); - - mediaLayer->invertContents(isContentInverted); - - //force the layer to sync to the UI thread - WebViewCore* wvc = pluginWidget->webViewCore(); - if (wvc) - wvc->mainFrame()->page()->chrome()->client()->scheduleCompositingLayerSync(); -} - - - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPOpenGLInterfaceV0_Init(ANPInterface* v) { - ANPOpenGLInterfaceV0* i = reinterpret_cast<ANPOpenGLInterfaceV0*>(v); - - ASSIGN(i, acquireContext); - ASSIGN(i, lockTexture); - ASSIGN(i, releaseTexture); - ASSIGN(i, invertPluginContent); -} diff --git a/WebKit/android/plugins/ANPOpenGL_npapi.h b/WebKit/android/plugins/ANPOpenGL_npapi.h deleted file mode 100644 index 5aabbc4..0000000 --- a/WebKit/android/plugins/ANPOpenGL_npapi.h +++ /dev/null @@ -1,63 +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 ANPOpenGL_npapi_H -#define ANPOpenGL_npapi_H - -#include "android_npapi.h" -#include <EGL/egl.h> -#include <GLES2/gl2.h> - -/** - * TODO should we not use EGL and GL data types for ABI safety? - */ -struct ANPTextureInfo { - GLuint textureId; - uint32_t width; - uint32_t height; - GLenum internalFormat; -}; - -struct ANPOpenGLInterfaceV0 : ANPInterface { - /** - */ - EGLContext (*acquireContext)(NPP instance); - - /** - */ - ANPTextureInfo (*lockTexture)(NPP instance); - - /** - */ - void (*releaseTexture)(NPP instance, const ANPTextureInfo*); - - /** - * Invert the contents of the plugin on the y-axis. - * default is to not be inverted (i.e. use OpenGL coordinates) - */ - void (*invertPluginContent)(NPP instance, bool isContentInverted); -}; - -#endif //ANPOpenGL_npapi_H diff --git a/WebKit/android/plugins/ANPPaintInterface.cpp b/WebKit/android/plugins/ANPPaintInterface.cpp deleted file mode 100644 index 5c59df9..0000000 --- a/WebKit/android/plugins/ANPPaintInterface.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include "SkTypeface.h" - -static ANPPaint* anp_newPaint() { - return new ANPPaint; -} - -static void anp_deletePaint(ANPPaint* paint) { - delete paint; -} - -static ANPPaintFlags anp_getFlags(const ANPPaint* paint) { - return paint->getFlags(); -} - -static void anp_setFlags(ANPPaint* paint, ANPPaintFlags flags) { - paint->setFlags(flags); -} - -static ANPColor anp_getColor(const ANPPaint* paint) { - return paint->getColor(); -} - -static void anp_setColor(ANPPaint* paint, ANPColor color) { - paint->setColor(color); -} - -static ANPPaintStyle anp_getStyle(const ANPPaint* paint) { - return paint->getStyle(); -} - -static void anp_setStyle(ANPPaint* paint, ANPPaintStyle style) { - paint->setStyle(static_cast<SkPaint::Style>(style)); -} - -static float anp_getStrokeWidth(const ANPPaint* paint) { - return SkScalarToFloat(paint->getStrokeWidth()); -} - -static float anp_getStrokeMiter(const ANPPaint* paint) { - return SkScalarToFloat(paint->getStrokeMiter()); -} - -static ANPPaintCap anp_getStrokeCap(const ANPPaint* paint) { - return paint->getStrokeCap(); -} - -static ANPPaintJoin anp_getStrokeJoin(const ANPPaint* paint) { - return paint->getStrokeJoin(); -} - -static void anp_setStrokeWidth(ANPPaint* paint, float width) { - paint->setStrokeWidth(SkFloatToScalar(width)); -} - -static void anp_setStrokeMiter(ANPPaint* paint, float miter) { - paint->setStrokeMiter(SkFloatToScalar(miter)); -} - -static void anp_setStrokeCap(ANPPaint* paint, ANPPaintCap cap) { - paint->setStrokeCap(static_cast<SkPaint::Cap>(cap)); -} - -static void anp_setStrokeJoin(ANPPaint* paint, ANPPaintJoin join) { - paint->setStrokeJoin(static_cast<SkPaint::Join>(join)); -} - -static ANPTextEncoding anp_getTextEncoding(const ANPPaint* paint) { - return paint->getTextEncoding(); -} - -static ANPPaintAlign anp_getTextAlign(const ANPPaint* paint) { - return paint->getTextAlign(); -} - -static float anp_getTextSize(const ANPPaint* paint) { - return SkScalarToFloat(paint->getTextSize()); -} - -static float anp_getTextScaleX(const ANPPaint* paint) { - return SkScalarToFloat(paint->getTextScaleX()); -} - -static float anp_getTextSkewX(const ANPPaint* paint) { - return SkScalarToFloat(paint->getTextSkewX()); -} - -static ANPTypeface* anp_getTypeface(const ANPPaint* paint) { - return reinterpret_cast<ANPTypeface*>(paint->getTypeface()); -} - -static void anp_setTextEncoding(ANPPaint* paint, ANPTextEncoding encoding) { - paint->setTextEncoding(static_cast<SkPaint::TextEncoding>(encoding)); -} - -static void anp_setTextAlign(ANPPaint* paint, ANPPaintAlign align) { - paint->setTextAlign(static_cast<SkPaint::Align>(align)); -} - -static void anp_setTextSize(ANPPaint* paint, float textSize) { - paint->setTextSize(SkFloatToScalar(textSize)); -} - -static void anp_setTextScaleX(ANPPaint* paint, float scaleX) { - paint->setTextScaleX(SkFloatToScalar(scaleX)); -} - -static void anp_setTextSkewX(ANPPaint* paint, float skewX) { - paint->setTextSkewX(SkFloatToScalar(skewX)); -} - -static void anp_setTypeface(ANPPaint* paint, ANPTypeface* tf) { - paint->setTypeface(tf); -} - -static float anp_measureText(ANPPaint* paint, const void* text, - uint32_t byteLength, ANPRectF* bounds) { - SkScalar w = paint->measureText(text, byteLength, - reinterpret_cast<SkRect*>(bounds)); - return SkScalarToFloat(w); -} - -/** Return the number of unichars specifed by the text. - If widths is not null, returns the array of advance widths for each - unichar. - If bounds is not null, returns the array of bounds for each unichar. - */ -static int anp_getTextWidths(ANPPaint* paint, const void* text, - uint32_t byteLength, float widths[], ANPRectF bounds[]) { - return paint->getTextWidths(text, byteLength, widths, - reinterpret_cast<SkRect*>(bounds)); -} - -static float anp_getFontMetrics(ANPPaint* paint, ANPFontMetrics* metrics) { - SkPaint::FontMetrics fm; - SkScalar spacing = paint->getFontMetrics(&fm); - if (metrics) { - metrics->fTop = SkScalarToFloat(fm.fTop); - metrics->fAscent = SkScalarToFloat(fm.fAscent); - metrics->fDescent = SkScalarToFloat(fm.fDescent); - metrics->fBottom = SkScalarToFloat(fm.fBottom); - metrics->fLeading = SkScalarToFloat(fm.fLeading); - } - return SkScalarToFloat(spacing); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPPaintInterfaceV0_Init(ANPInterface* value) { - ANPPaintInterfaceV0* i = reinterpret_cast<ANPPaintInterfaceV0*>(value); - - ASSIGN(i, newPaint); - ASSIGN(i, deletePaint); - ASSIGN(i, getFlags); - ASSIGN(i, setFlags); - ASSIGN(i, getColor); - ASSIGN(i, setColor); - ASSIGN(i, getStyle); - ASSIGN(i, setStyle); - ASSIGN(i, getStrokeWidth); - ASSIGN(i, getStrokeMiter); - ASSIGN(i, getStrokeCap); - ASSIGN(i, getStrokeJoin); - ASSIGN(i, setStrokeWidth); - ASSIGN(i, setStrokeMiter); - ASSIGN(i, setStrokeCap); - ASSIGN(i, setStrokeJoin); - ASSIGN(i, getTextEncoding); - ASSIGN(i, getTextAlign); - ASSIGN(i, getTextSize); - ASSIGN(i, getTextScaleX); - ASSIGN(i, getTextSkewX); - ASSIGN(i, getTypeface); - ASSIGN(i, setTextEncoding); - ASSIGN(i, setTextAlign); - ASSIGN(i, setTextSize); - ASSIGN(i, setTextScaleX); - ASSIGN(i, setTextSkewX); - ASSIGN(i, setTypeface); - ASSIGN(i, measureText); - ASSIGN(i, getTextWidths); - ASSIGN(i, getFontMetrics); -} diff --git a/WebKit/android/plugins/ANPPathInterface.cpp b/WebKit/android/plugins/ANPPathInterface.cpp deleted file mode 100644 index 69cabcf..0000000 --- a/WebKit/android/plugins/ANPPathInterface.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" - -static ANPPath* anp_newPath() { - return new ANPPath; -} - -static void anp_deletePath(ANPPath* path) { - delete path; -} - -static void anp_copy(ANPPath* dst, const ANPPath* src) { - *dst = *src; -} - -static bool anp_equal(const ANPPath* p0, const ANPPath* p1) { - return *p0 == *p1; -} - -static void anp_reset(ANPPath* path) { - path->reset(); -} - -static bool anp_isEmpty(const ANPPath* path) { - return path->isEmpty(); -} - -static void anp_getBounds(const ANPPath* path, ANPRectF* bounds) { - SkANP::SetRect(bounds, path->getBounds()); -} - -static void anp_moveTo(ANPPath* path, float x, float y) { - path->moveTo(SkFloatToScalar(x), SkFloatToScalar(y)); -} - -static void anp_lineTo(ANPPath* path, float x, float y) { - path->lineTo(SkFloatToScalar(x), SkFloatToScalar(y)); -} - -static void anp_quadTo(ANPPath* path, float x0, float y0, float x1, float y1) { - path->quadTo(SkFloatToScalar(x0), SkFloatToScalar(y0), - SkFloatToScalar(x1), SkFloatToScalar(y1)); -} - -static void anp_cubicTo(ANPPath* path, float x0, float y0, - float x1, float y1, float x2, float y2) { - path->cubicTo(SkFloatToScalar(x0), SkFloatToScalar(y0), - SkFloatToScalar(x1), SkFloatToScalar(y1), - SkFloatToScalar(x2), SkFloatToScalar(y2)); -} - -static void anp_close(ANPPath* path) { - path->close(); -} - -static void anp_offset(ANPPath* path, float dx, float dy, ANPPath* dst) { - path->offset(SkFloatToScalar(dx), SkFloatToScalar(dy), dst); -} - -static void anp_transform(ANPPath* src, const ANPMatrix* matrix, - ANPPath* dst) { - src->transform(*matrix, dst); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPPathInterfaceV0_Init(ANPInterface* value) { - ANPPathInterfaceV0* i = reinterpret_cast<ANPPathInterfaceV0*>(value); - - ASSIGN(i, newPath); - ASSIGN(i, deletePath); - ASSIGN(i, copy); - ASSIGN(i, equal); - ASSIGN(i, reset); - ASSIGN(i, isEmpty); - ASSIGN(i, getBounds); - ASSIGN(i, moveTo); - ASSIGN(i, lineTo); - ASSIGN(i, quadTo); - ASSIGN(i, cubicTo); - ASSIGN(i, close); - ASSIGN(i, offset); - ASSIGN(i, transform); -} diff --git a/WebKit/android/plugins/ANPSoundInterface.cpp b/WebKit/android/plugins/ANPSoundInterface.cpp deleted file mode 100644 index c238872..0000000 --- a/WebKit/android/plugins/ANPSoundInterface.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "android_npapi.h" - -#include "SkTypes.h" -#include "media/AudioTrack.h" - -#include <system/audio.h> - -struct ANPAudioTrack { - void* mUser; - ANPAudioCallbackProc mProc; - android::AudioTrack* mTrack; -}; - -static ANPSampleFormat toANPFormat(int fm) { - switch (fm) { - case AUDIO_FORMAT_PCM_16_BIT: - return kPCM16Bit_ANPSampleFormat; - case AUDIO_FORMAT_PCM_8_BIT: - return kPCM8Bit_ANPSampleFormat; - default: - return kUnknown_ANPSamleFormat; - } -} - -static int fromANPFormat(ANPSampleFormat fm) { - switch (fm) { - case kPCM16Bit_ANPSampleFormat: - return AUDIO_FORMAT_PCM_16_BIT; - case kPCM8Bit_ANPSampleFormat: - return AUDIO_FORMAT_PCM_8_BIT; - default: - return AUDIO_FORMAT_INVALID; - } -} - -static void callbackProc(int event, void* user, void* info) { - ANPAudioTrack* track = reinterpret_cast<ANPAudioTrack*>(user); - - switch (event) { - case android::AudioTrack::EVENT_MORE_DATA: { - ANPAudioBuffer dst; - android::AudioTrack::Buffer* src; - - src = reinterpret_cast<android::AudioTrack::Buffer*>(info); - dst.bufferData = src->raw; - dst.channelCount = src->channelCount; - dst.format = toANPFormat(src->format); - dst.size = src->size; - track->mProc(kMoreData_ANPAudioEvent, track->mUser, &dst); - // return the updated size field - src->size = dst.size; - break; - } - case android::AudioTrack::EVENT_UNDERRUN: - track->mProc(kUnderRun_ANPAudioEvent, track->mUser, NULL); - break; - default: - SkDebugf("------ unknown audio event for plugin %d\n", event); - break; - } -} - -static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate, - ANPSampleFormat format, - int channelCount, - ANPAudioCallbackProc proc, - void* user) { - - ANPAudioTrack* track = new ANPAudioTrack; - - track->mUser = user; - track->mProc = proc; - track->mTrack = new android::AudioTrack(AUDIO_STREAM_MUSIC, - sampleRate, - fromANPFormat(format), - (channelCount > 1) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, - 0, // frameCount - 0, // flags - callbackProc, - track, - 0); - - if (track->mTrack->initCheck() != 0) { // failure - delete track->mTrack; - delete track; - track = NULL; - } - return track; -} - -static void ANPDeleteTrack(ANPAudioTrack* track) { - if (track) { - delete track->mTrack; - delete track; - } -} - -static void ANPTrackStart(ANPAudioTrack* track) { - track->mTrack->start(); -} - -static void ANPTrackPause(ANPAudioTrack* track) { - track->mTrack->pause(); -} - -static void ANPTrackStop(ANPAudioTrack* track) { - track->mTrack->stop(); -} - -static bool ANPTrackIsStopped(ANPAudioTrack* track) { - return track->mTrack->stopped(); -} - -static uint32_t ANPTrackLatency(ANPAudioTrack* track) { - return track->mTrack->latency(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void ANPAudioTrackInterfaceV0_Init(ANPInterface* value) { - ANPAudioTrackInterfaceV0* si = reinterpret_cast<ANPAudioTrackInterfaceV0*>(value); - si->newTrack = ANPCreateTrack; - si->deleteTrack = ANPDeleteTrack; - si->start = ANPTrackStart; - si->pause = ANPTrackPause; - si->stop = ANPTrackStop; - si->isStopped = ANPTrackIsStopped; -} - -void ANPAudioTrackInterfaceV1_Init(ANPInterface* value) { - // initialize the functions from the previous interface - ANPAudioTrackInterfaceV0_Init(value); - // add any new functions or override existing functions - ANPAudioTrackInterfaceV1* si = reinterpret_cast<ANPAudioTrackInterfaceV1*>(value); - si->trackLatency = ANPTrackLatency; -} diff --git a/WebKit/android/plugins/ANPSurfaceInterface.cpp b/WebKit/android/plugins/ANPSurfaceInterface.cpp deleted file mode 100644 index 4b99b31..0000000 --- a/WebKit/android/plugins/ANPSurfaceInterface.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "ANPSurface_npapi.h" - -#include "PluginView.h" -#include "PluginWidgetAndroid.h" -#include "SkANP.h" -#include "android_graphics.h" -#include <JNIUtility.h> -#include <surfaceflinger/Surface.h> -#include <ui/Rect.h> -#include <ui/Region.h> -#include <utils/RefBase.h> - -using namespace android; - -// used to cache JNI method and field IDs for Surface Objects -static struct ANPSurfaceInterfaceJavaGlue { - bool initialized; - jmethodID getSurfaceHolder; - jmethodID getSurface; - jfieldID surfacePointer; -} gSurfaceJavaGlue; - -static inline sp<Surface> getSurface(JNIEnv* env, jobject view) { - if (!env || !view) { - return NULL; - } - - if (!gSurfaceJavaGlue.initialized) { - - jclass surfaceViewClass = env->FindClass("android/view/SurfaceView"); - gSurfaceJavaGlue.getSurfaceHolder = env->GetMethodID(surfaceViewClass, "getHolder", - "()Landroid/view/SurfaceHolder;"); - - jclass surfaceHolderClass = env->FindClass("android/view/SurfaceHolder"); - gSurfaceJavaGlue.getSurface = env->GetMethodID(surfaceHolderClass, "getSurface", - "()Landroid/view/Surface;"); - - jclass surfaceClass = env->FindClass("android/view/Surface"); - gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass, - ANDROID_VIEW_SURFACE_JNI_ID, "I"); - - env->DeleteLocalRef(surfaceClass); - env->DeleteLocalRef(surfaceViewClass); - env->DeleteLocalRef(surfaceHolderClass); - - gSurfaceJavaGlue.initialized = true; - } - - jobject holder = env->CallObjectMethod(view, gSurfaceJavaGlue.getSurfaceHolder); - jobject surface = env->CallObjectMethod(holder, gSurfaceJavaGlue.getSurface); - jint surfacePointer = env->GetIntField(surface, gSurfaceJavaGlue.surfacePointer); - - env->DeleteLocalRef(holder); - env->DeleteLocalRef(surface); - - return sp<Surface>((Surface*) surfacePointer); -} - -static inline ANPBitmapFormat convertPixelFormat(PixelFormat format) { - switch (format) { - case PIXEL_FORMAT_RGBA_8888: return kRGBA_8888_ANPBitmapFormat; - case PIXEL_FORMAT_RGB_565: return kRGB_565_ANPBitmapFormat; - default: return kUnknown_ANPBitmapFormat; - } -} - -static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) { - if (!bitmap || !surfaceView) { - return false; - } - - sp<Surface> surface = getSurface(env, surfaceView); - - if (!bitmap || !Surface::isValid(surface)) { - return false; - } - - Region dirtyRegion; - if (dirtyRect) { - Rect rect(dirtyRect->left, dirtyRect->top, dirtyRect->right, dirtyRect->bottom); - if (!rect.isEmpty()) { - dirtyRegion.set(rect); - } - } else { - dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); - } - - Surface::SurfaceInfo info; - status_t err = surface->lock(&info, &dirtyRegion); - if (err < 0) { - return false; - } - - // the surface may have expanded the dirty region so we must to pass that - // information back to the plugin. - if (dirtyRect) { - Rect dirtyBounds = dirtyRegion.getBounds(); - dirtyRect->left = dirtyBounds.left; - dirtyRect->right = dirtyBounds.right; - dirtyRect->top = dirtyBounds.top; - dirtyRect->bottom = dirtyBounds.bottom; - } - - ssize_t bpr = info.s * bytesPerPixel(info.format); - - bitmap->format = convertPixelFormat(info.format); - bitmap->width = info.w; - bitmap->height = info.h; - bitmap->rowBytes = bpr; - - if (info.w > 0 && info.h > 0) { - bitmap->baseAddr = info.bits; - } else { - bitmap->baseAddr = NULL; - return false; - } - - return true; -} - -static void anp_unlock(JNIEnv* env, jobject surfaceView) { - if (!surfaceView) { - return; - } - - sp<Surface> surface = getSurface(env, surfaceView); - - if (!Surface::isValid(surface)) { - return; - } - - surface->unlockAndPost(); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPSurfaceInterfaceV0_Init(ANPInterface* value) { - ANPSurfaceInterfaceV0* i = reinterpret_cast<ANPSurfaceInterfaceV0*>(value); - - ASSIGN(i, lock); - ASSIGN(i, unlock); - - // setup the java glue struct - gSurfaceJavaGlue.initialized = false; -} diff --git a/WebKit/android/plugins/ANPSurface_npapi.h b/WebKit/android/plugins/ANPSurface_npapi.h deleted file mode 100644 index 910a948..0000000 --- a/WebKit/android/plugins/ANPSurface_npapi.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 ANPSurface_npapi_H -#define ANPSurface_npapi_H - -#include "android_npapi.h" -#include <jni.h> - -struct ANPSurfaceInterfaceV0 : ANPInterface { - /** Locks the surface from manipulation by other threads and provides a bitmap - to be written to. The dirtyRect param specifies which portion of the - bitmap will be written to. If the dirtyRect is NULL then the entire - surface will be considered dirty. If the lock was successful the function - will return true and the bitmap will be set to point to a valid bitmap. - If not the function will return false and the bitmap will be set to NULL. - */ - bool (*lock)(JNIEnv* env, jobject surface, ANPBitmap* bitmap, ANPRectI* dirtyRect); - /** Given a locked surface handle (i.e. result of a successful call to lock) - the surface is unlocked and the contents of the bitmap, specifically - those inside the dirtyRect are written to the screen. - */ - void (*unlock)(JNIEnv* env, jobject surface); -}; - -#endif //ANPSurface_npapi_H diff --git a/WebKit/android/plugins/ANPSystemInterface.cpp b/WebKit/android/plugins/ANPSystemInterface.cpp deleted file mode 100644 index 7199635..0000000 --- a/WebKit/android/plugins/ANPSystemInterface.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" - -#include "ANPSystem_npapi.h" -#include "Frame.h" -#include "JavaSharedClient.h" -#include "PluginClient.h" -#include "PluginPackage.h" -#include "PluginView.h" -#include "PluginWidgetAndroid.h" -#include "Settings.h" -#include "SkString.h" -#include "WebViewCore.h" -#include <wtf/text/CString.h> - -#include <dirent.h> - -//#define PLUGIN_DEBUG_LOCAL // controls the printing of log messages -#include "PluginDebugAndroid.h" - -static const char* gApplicationDataDir = NULL; -static const char* gApplicationDataDirIncognito = NULL; - -using namespace android; - -static WebCore::PluginView* pluginViewForInstance(NPP instance) { - if (instance && instance->ndata) - return static_cast<WebCore::PluginView*>(instance->ndata); - return WebCore::PluginView::currentPluginView(); -} - -static const char* anp_getApplicationDataDirectory() { - if (NULL == gApplicationDataDir) { - PluginClient* client = JavaSharedClient::GetPluginClient(); - if (!client) - return NULL; - - WTF::String path = client->getPluginSharedDataDirectory(); - int length = path.length(); - if (length == 0) - return NULL; - - char* storage = (char*) malloc(length + 1); - if (NULL == storage) - return NULL; - - memcpy(storage, path.utf8().data(), length); - storage[length] = '\0'; - - static const char incognitoPath[] = "/incognito_plugins"; - char* incognitoStorage = (char*) malloc(length + strlen(incognitoPath) + 1); - - strcpy(incognitoStorage, storage); - strcat(incognitoStorage, incognitoPath); - - // save this assignment for last, so that if multiple threads call us - // (which should never happen), we never return an incomplete global. - // At worst, we would allocate storage for the path twice. - gApplicationDataDir = storage; - gApplicationDataDirIncognito = incognitoStorage; - } - - return gApplicationDataDir; -} - -static const char* anp_getApplicationDataDirectoryV2(NPP instance) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - - if (NULL == gApplicationDataDir) { - anp_getApplicationDataDirectory(); - } - - WebCore::Settings* settings = pluginWidget->webViewCore()->mainFrame()->settings(); - if (settings && settings->privateBrowsingEnabled()) { - // if this is an incognito view then check the path to see if it exists - // and if it is a directory, otherwise if it does not exist create it. - struct stat st; - if (stat(gApplicationDataDirIncognito, &st) == 0) { - if (!S_ISDIR(st.st_mode)) { - return NULL; - } - } else { - if (mkdir(gApplicationDataDirIncognito, S_IRWXU) != 0) { - return NULL; - } - } - - return gApplicationDataDirIncognito; - } - - return gApplicationDataDir; -} - -static jclass anp_loadJavaClass(NPP instance, const char* className) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - - jclass result; - result = pluginWidget->webViewCore()->getPluginClass(pluginView->plugin()->path(), - className); - return result; -} - -static void anp_setPowerState(NPP instance, ANPPowerState powerState) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - - pluginWidget->setPowerState(powerState); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPSystemInterfaceV0_Init(ANPInterface* v) { - ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(v); - - ASSIGN(i, getApplicationDataDirectory); - ASSIGN(i, loadJavaClass); -} - -void ANPSystemInterfaceV1_Init(ANPInterface* v) { - // initialize the functions from the previous interface - ANPSystemInterfaceV0_Init(v); - // add any new functions or override existing functions - ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(v); - ASSIGN(i, setPowerState); -} - -void ANPSystemInterfaceV2_Init(ANPInterface* v) { - // initialize the functions from the previous interface - ANPSystemInterfaceV1_Init(v); - // add any new functions or override existing functions - ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(v); - i->getApplicationDataDirectory = anp_getApplicationDataDirectoryV2; -} - -/////////////////////////////////////////////////////////////////////////////// - -static bool isDirectory(const char* path) { - struct stat st; - return stat(path, &st) == 0 && S_ISDIR(st.st_mode); -} - -static void removeDirectory(const char* path) { - // create a pointer to a directory - DIR *dir = NULL; - dir = opendir(path); - if (!dir) - return; - - struct dirent* entry = 0; - while ((entry = readdir(dir))) { // while there is still something in the directory to list - if (!entry) - return; - - if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name)) { - PLUGIN_LOG(". file: %s", entry->d_name); - continue; - } - - // concatenate the strings to get the complete path - static const char separator[] = "/"; - char* file = (char*) malloc(strlen(path) + strlen(separator) + strlen(entry->d_name) + 1); - strcpy(file, path); - strcat(file, separator); - strcat(file, entry->d_name); - - if (isDirectory(file) == true) { - PLUGIN_LOG("remove dir: %s", file); - removeDirectory(file); - } else { // it's a file, we can use remove - PLUGIN_LOG("remove file: %s", file); - remove(file); - } - - free(file); - } - - // clean up - closedir (dir); // close the directory - rmdir(path); // delete the directory -} - -void ANPSystemInterface_CleanupIncognito() { - PLUGIN_LOG("cleanup incognito plugin directory"); - - if (gApplicationDataDirIncognito == NULL) - anp_getApplicationDataDirectory(); - if (gApplicationDataDirIncognito == NULL) - return; - - // check to see if the directory exists and if so delete it - if (isDirectory(gApplicationDataDirIncognito)) - removeDirectory(gApplicationDataDirIncognito); -} diff --git a/WebKit/android/plugins/ANPSystem_npapi.h b/WebKit/android/plugins/ANPSystem_npapi.h deleted file mode 100644 index 835bc7c..0000000 --- a/WebKit/android/plugins/ANPSystem_npapi.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 ANPSystem_npapi_H -#define ANPSystem_npapi_H - -#include "android_npapi.h" -#include <jni.h> - -struct ANPSystemInterfaceV0 : ANPInterface { - /** Return the path name for the current Application's plugin data directory, - or NULL if not supported - */ - const char* (*getApplicationDataDirectory)(); - - /** A helper function to load java classes from the plugin's apk. The - function looks for a class given the fully qualified and null terminated - string representing the className. For example, - - const char* className = "com.android.mypackage.MyClass"; - - If the class cannot be found or there is a problem loading the class - NULL will be returned. - */ - jclass (*loadJavaClass)(NPP instance, const char* className); -}; - -enum ANPPowerStates { - kDefault_ANPPowerState = 0, - kScreenOn_ANPPowerState = 1 -}; -typedef int32_t ANPPowerState; - -struct ANPSystemInterfaceV1 : ANPSystemInterfaceV0 { - void (*setPowerState)(NPP instance, ANPPowerState powerState); -}; - -struct ANPSystemInterfaceV2 : ANPInterface { - /** Return the path name for the current Application's plugin data directory, - or NULL if not supported. This directory will change depending on whether - or not the plugin is found within an incognito tab. - */ - const char* (*getApplicationDataDirectory)(NPP instance); - - // redeclaration of existing features - jclass (*loadJavaClass)(NPP instance, const char* className); - void (*setPowerState)(NPP instance, ANPPowerState powerState); -}; - -#endif //ANPSystem_npapi_H diff --git a/WebKit/android/plugins/ANPTypefaceInterface.cpp b/WebKit/android/plugins/ANPTypefaceInterface.cpp deleted file mode 100644 index 99734a7..0000000 --- a/WebKit/android/plugins/ANPTypefaceInterface.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include "SkFontHost.h" - -static ANPTypeface* anp_createFromName(const char name[], ANPTypefaceStyle s) { - SkTypeface* tf = SkTypeface::CreateFromName(name, - static_cast<SkTypeface::Style>(s)); - return reinterpret_cast<ANPTypeface*>(tf); -} - -static ANPTypeface* anp_createFromTypeface(const ANPTypeface* family, - ANPTypefaceStyle s) { - SkTypeface* tf = SkTypeface::CreateFromTypeface(family, - static_cast<SkTypeface::Style>(s)); - return reinterpret_cast<ANPTypeface*>(tf); -} - -static int32_t anp_getRefCount(const ANPTypeface* tf) { - return tf ? tf->getRefCnt() : 0; -} - -static void anp_ref(ANPTypeface* tf) { - SkSafeRef(tf); -} - -static void anp_unref(ANPTypeface* tf) { - SkSafeUnref(tf); -} - -static ANPTypefaceStyle anp_getStyle(const ANPTypeface* tf) { - SkTypeface::Style s = tf ? tf->style() : SkTypeface::kNormal; - return static_cast<ANPTypefaceStyle>(s); -} - -static int32_t anp_getFontPath(const ANPTypeface* tf, char fileName[], - int32_t length, int32_t* index) { - size_t size = SkFontHost::GetFileName(SkTypeface::UniqueID(tf), fileName, - length, index); - return static_cast<int32_t>(size); -} - -static const char* gFontDir; -#define FONT_DIR_SUFFIX "/fonts/" - -static const char* anp_getFontDirectoryPath() { - if (NULL == gFontDir) { - const char* root = getenv("ANDROID_ROOT"); - size_t len = strlen(root); - char* storage = (char*)malloc(len + sizeof(FONT_DIR_SUFFIX)); - if (NULL == storage) { - return NULL; - } - memcpy(storage, root, len); - memcpy(storage + len, FONT_DIR_SUFFIX, sizeof(FONT_DIR_SUFFIX)); - // save this assignment for last, so that if multiple threads call us - // (which should never happen), we never return an incomplete global. - // At worst, we would allocate storage for the path twice. - gFontDir = storage; - } - return gFontDir; -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPTypefaceInterfaceV0_Init(ANPInterface* v) { - ANPTypefaceInterfaceV0* i = reinterpret_cast<ANPTypefaceInterfaceV0*>(v); - - ASSIGN(i, createFromName); - ASSIGN(i, createFromTypeface); - ASSIGN(i, getRefCount); - ASSIGN(i, ref); - ASSIGN(i, unref); - ASSIGN(i, getStyle); - ASSIGN(i, getFontPath); - ASSIGN(i, getFontDirectoryPath); -} diff --git a/WebKit/android/plugins/ANPVideoInterface.cpp b/WebKit/android/plugins/ANPVideoInterface.cpp deleted file mode 100644 index 8eb9846..0000000 --- a/WebKit/android/plugins/ANPVideoInterface.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "ANPVideo_npapi.h" -#include "SkANP.h" - -#include "PluginView.h" -#include "PluginWidgetAndroid.h" -#include "MediaLayer.h" - -static WebCore::PluginView* pluginViewForInstance(NPP instance) { - if (instance && instance->ndata) - return static_cast<WebCore::PluginView*>(instance->ndata); - return WebCore::PluginView::currentPluginView(); -} - -static WebCore::MediaLayer* mediaLayerForInstance(NPP instance) { - WebCore::PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - return pluginWidget->getLayer(); -} - -static ANativeWindow* anp_acquireNativeWindow(NPP instance) { - WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance); - - return mediaLayer->acquireNativeWindowForVideo(); -} - -static void anp_setWindowDimensions(NPP instance, const ANativeWindow* window, - const ANPRectF* dimensions) { - - WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance); - if (!mediaLayer) - return; - - SkRect rect; - mediaLayer->setWindowDimensionsForVideo(window, *SkANP::SetRect(&rect, *dimensions)); -} - - -static void anp_releaseNativeWindow(NPP instance, ANativeWindow* window) { - WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance); - if (!mediaLayer) - return; - - mediaLayer->releaseNativeWindowForVideo(window); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPVideoInterfaceV0_Init(ANPInterface* value) { - ANPVideoInterfaceV0* i = reinterpret_cast<ANPVideoInterfaceV0*>(value); - - ASSIGN(i, acquireNativeWindow); - ASSIGN(i, setWindowDimensions); - ASSIGN(i, releaseNativeWindow); -} diff --git a/WebKit/android/plugins/ANPVideo_npapi.h b/WebKit/android/plugins/ANPVideo_npapi.h deleted file mode 100644 index 18e0231..0000000 --- a/WebKit/android/plugins/ANPVideo_npapi.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, 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 ANPVideo_npapi_H -#define ANPVideo_npapi_H - -#include "android_npapi.h" -#include <android/native_window.h> - -struct ANPVideoInterfaceV0 : ANPInterface { - - /** - * Constructs a new native window to be used for rendering video content. - * - * Subsequent calls will produce new windows, but may also return NULL after - * n attempts if the browser has reached it's limit. Further, if the browser - * is unable to acquire the window quickly it may also return NULL in order - * to not prevent the plugin from executing. A subsequent call will then - * return the window if it is avaiable. - * - * NOTE: The hardware may fail if you try to decode more than the allowable - * number of videos supported on that device. - */ - ANativeWindow* (*acquireNativeWindow)(NPP instance); - - /** - * Sets the rectangle that specifies where the video content is to be drawn. - * The dimensions are in document space. Further, if the rect is NULL the - * browser will not attempt to draw the window, therefore do not set the - * dimensions until you queue the first buffer in the window. - */ - void (*setWindowDimensions)(NPP instance, const ANativeWindow* window, const ANPRectF* dimensions); - - /** - */ - void (*releaseNativeWindow)(NPP instance, ANativeWindow* window); -}; - -#endif //ANPVideo_npapi_H diff --git a/WebKit/android/plugins/ANPWindowInterface.cpp b/WebKit/android/plugins/ANPWindowInterface.cpp deleted file mode 100644 index a74616c..0000000 --- a/WebKit/android/plugins/ANPWindowInterface.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include "WebViewCore.h" -#include "PluginView.h" -#include "PluginWidgetAndroid.h" - -static PluginView* pluginViewForInstance(NPP instance) { - if (instance && instance->ndata) - return static_cast<PluginView*>(instance->ndata); - return PluginView::currentPluginView(); -} - -static void anp_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count) { - PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - pluginWidget->setVisibleRects(rects, count); -} - -static void anp_clearVisibleRects(NPP instance) { - anp_setVisibleRects(instance, NULL, 0); -} - -static void anp_showKeyboard(NPP instance, bool value) { - PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - if(pluginWidget->hasFocus()) - pluginWidget->webViewCore()->requestKeyboard(value); -} - -static void anp_requestFullScreen(NPP instance) { - PluginView* pluginView = pluginViewForInstance(instance); - // call focusPluginElement() so that the pluginView receives keyboard events - pluginView->focusPluginElement(); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - pluginWidget->requestFullScreen(); -} - -static void anp_exitFullScreen(NPP instance) { - PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - pluginWidget->exitFullScreen(true); -} - -static void anp_requestCenterFitZoom(NPP instance) { - PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - pluginWidget->requestCenterFitZoom(); -} - -static ANPRectI anp_visibleRect(NPP instance) { - PluginView* pluginView = pluginViewForInstance(instance); - PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); - return pluginWidget->visibleRect(); -} - -/////////////////////////////////////////////////////////////////////////////// - -#define ASSIGN(obj, name) (obj)->name = anp_##name - -void ANPWindowInterfaceV0_Init(ANPInterface* value) { - ANPWindowInterfaceV0* i = reinterpret_cast<ANPWindowInterfaceV0*>(value); - - ASSIGN(i, setVisibleRects); - ASSIGN(i, clearVisibleRects); - ASSIGN(i, showKeyboard); - ASSIGN(i, requestFullScreen); - ASSIGN(i, exitFullScreen); - ASSIGN(i, requestCenterFitZoom); -} - -void ANPWindowInterfaceV1_Init(ANPInterface* value) { - // initialize the functions from the previous interface - ANPWindowInterfaceV0_Init(value); - // add any new functions or override existing functions - ANPWindowInterfaceV1* i = reinterpret_cast<ANPWindowInterfaceV1*>(value); - ASSIGN(i, visibleRect); -} diff --git a/WebKit/android/plugins/PluginDebugAndroid.cpp b/WebKit/android/plugins/PluginDebugAndroid.cpp deleted file mode 100644 index 3958714..0000000 --- a/WebKit/android/plugins/PluginDebugAndroid.cpp +++ /dev/null @@ -1,137 +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. - */ - -#include "PluginDebugAndroid.h" -#include "utils/Log.h" -#include "utils/SystemClock.h" -#include <stdarg.h> - -#define ARRAY_COUNT(array) static_cast<int32_t>(sizeof(array) / sizeof(array[0])) - -// used for key, mouse, and touch inputs -static const char* const inputActions[] = { - "down", - "up", - "move", /* touch only */ - "cancel", /* touch only */ - "longPress", /* touch only */ - "doubleTap" /* touch only */ -}; - -static const char* const lifecycleActions[] = { - "kPause_ANPLifecycleAction", - "kResume_ANPLifecycleAction", - "kGainFocus_ANPLifecycleAction", - "kLoseFocus_ANPLifecycleAction", - "kFreeMemory_ANPLifecycleAction", - "kOnLoad_ANPLifecycleAction", - "kEnterFullScreen_ANPLifecycleAction", - "kExitFullScreen_ANPLifecycleAction", - "kOnScreen_ANPLifecycleAction", - "kOffScreen_ANPLifecycleAction" -}; - -void anp_logPlugin(const char format[], ...) { - va_list args; - va_start(args, format); - LOG_PRI_VA(ANDROID_LOG_DEBUG, "webkit_plugin", format, args); - va_end(args); -} - -void anp_logPluginEvent(void* npp, const ANPEvent* evt, int16_t returnVal, int elapsedTime) { - - switch(evt->eventType) { - - case kNull_ANPEventType: - PLUGIN_LOG("%p EVENT::NULL", npp); - break; - - case kKey_ANPEventType: - if(evt->data.key.action < ARRAY_COUNT(inputActions)) { - anp_logPlugin("%p EVENT::KEY[%d] time=%d action=%s code=%d vcode=%d unichar=%d repeat=%d mods=%x", - npp, returnVal, elapsedTime, inputActions[evt->data.key.action], - evt->data.key.nativeCode, evt->data.key.virtualCode, - evt->data.key.unichar, evt->data.key.repeatCount, - evt->data.key.modifiers); - } else { - PLUGIN_LOG("%p EVENT::KEY[%d] unknown action", npp, returnVal); - } - break; - - case kMouse_ANPEventType: - if(evt->data.mouse.action < ARRAY_COUNT(inputActions)) { - anp_logPlugin("%p EVENT::MOUSE[%d] time=%d action=%s [%d %d]", npp, - returnVal, elapsedTime, inputActions[evt->data.mouse.action], - evt->data.touch.x, evt->data.touch.y); - } else { - anp_logPlugin("%p EVENT::MOUSE[%d] unknown action", npp, returnVal); - } - break; - - case kTouch_ANPEventType: - if(evt->data.touch.action < ARRAY_COUNT(inputActions)) { - - anp_logPlugin("%p EVENT::TOUCH[%d] time=%d action=%s [%d %d]", - npp, returnVal, elapsedTime, - inputActions[evt->data.touch.action], evt->data.touch.x, - evt->data.touch.y); - } else { - anp_logPlugin("%p EVENT::TOUCH[%d] unknown action", npp, returnVal); - } - break; - - case kDraw_ANPEventType: - if (evt->data.draw.model == kBitmap_ANPDrawingModel) { - anp_logPlugin("%p EVENT::DRAW bitmap time=%d format=%d clip=[%d,%d,%d,%d]", - npp, elapsedTime, evt->data.draw.data.bitmap.format, - evt->data.draw.clip.left, evt->data.draw.clip.top, - evt->data.draw.clip.right, evt->data.draw.clip.bottom); - } else if (evt->data.draw.model == kOpenGL_ANPDrawingModel) { - anp_logPlugin("%p EVENT::DRAW openGL time=%d dimensions=[%d,%d]", - npp, elapsedTime, evt->data.draw.data.surface.width, - evt->data.draw.data.surface.height); - } else { - anp_logPlugin("%p EVENT::DRAW unknown drawing model", npp); - } - break; - - case kLifecycle_ANPEventType: - if(evt->data.lifecycle.action < ARRAY_COUNT(lifecycleActions)) { - anp_logPlugin("%p EVENT::LIFECYCLE time=%d action=%s", npp, elapsedTime, - lifecycleActions[evt->data.lifecycle.action]); - } else { - anp_logPlugin("%p EVENT::LIFECYCLE unknown action", npp); - } - break; - - case kCustom_ANPEventType: - anp_logPlugin("%p EVENT::CUSTOM time=%d", npp, elapsedTime); - break; - - default: - anp_logPlugin("%p EVENT::UNKNOWN", npp); - break; - } -} diff --git a/WebKit/android/plugins/PluginDebugAndroid.h b/WebKit/android/plugins/PluginDebugAndroid.h deleted file mode 100644 index 5002882..0000000 --- a/WebKit/android/plugins/PluginDebugAndroid.h +++ /dev/null @@ -1,58 +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 PLUGIN_DEBUG_ANDROID_H__ -#define PLUGIN_DEBUG_ANDROID_H__ - -#include "android_npapi.h" - -// Define PLUGIN_DEBUG_LOCAL in an individual C++ file to enable for -// that file only. - -// Define PLUGIN_DEBUG_GLOBAL to 1 to turn plug-in debug for all -// Android plug-in code in this directory. -#define PLUGIN_DEBUG_GLOBAL 0 - -#if PLUGIN_DEBUG_GLOBAL || defined(PLUGIN_DEBUG_LOCAL) -# define PLUGIN_LOG(FORMAT, ARGS...) do { anp_logPlugin(FORMAT, ## ARGS); } while(0) -# define PLUGIN_LOG_EVENT(NPP, EVT, RET, TIME) do { anp_logPluginEvent(NPP, EVT, RET, TIME); } while(0) - -/* Logs the given character array and optional arguments. All log entries use - the DEBUG priority and use the same "webkit_plugin" log tag. - */ -void anp_logPlugin(const char format[], ...); -/* Logs a user readable description of a plugin event. The relevant contents of - each event are logged, as well as the value returned by the plugin instance - and how long the instance took to process the event (in milliseconds). - */ -void anp_logPluginEvent(void* npp, const ANPEvent* event, int16_t returnVal, int elapsedTime); - -#else -# define PLUGIN_LOG(A, B...) do { } while(0) -# define PLUGIN_LOG_EVENT(NPP, EVT, RET, TIME) do { } while(0) - -#endif - -#endif // defined(PLUGIN_DEBUG_ANDROID_H__) diff --git a/WebKit/android/plugins/PluginTimer.cpp b/WebKit/android/plugins/PluginTimer.cpp deleted file mode 100644 index dfa7272..0000000 --- a/WebKit/android/plugins/PluginTimer.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2008 Google Inc. All rights reserved. - * - * 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 "PluginTimer.h" -#include "RefPtr.h" - -namespace WebCore { - - static uint32_t gTimerID; - - PluginTimer::PluginTimer(PluginTimer** list, NPP instance, bool repeat, - void (*timerFunc)(NPP npp, uint32_t timerID)) - : m_list(list), - m_instance(instance), - m_timerFunc(timerFunc), - m_repeat(repeat), - m_unscheduled(false) - { - m_timerID = ++gTimerID; - - m_next = *list; - if (m_next) { - m_next->m_prev = this; - } - m_prev = 0; - *list = this; - relaxAdoptionRequirement(); - } - - PluginTimer::~PluginTimer() - { - if (m_next) { - m_next->m_prev = m_prev; - } - if (m_prev) { - m_prev->m_next = m_next; - } else { - *m_list = m_next; - } - } - - void PluginTimer::fired() - { - // ensure the timer cannot be deleted until this method completes - RefPtr<PluginTimer> protector(this); - - if (!m_unscheduled) - m_timerFunc(m_instance, m_timerID); - - // remove the timer if it is a one-shot timer (!m_repeat) or if is a - // repeating timer that has been unscheduled. In either case we must - // ensure that the refcount is 2 or greater since the PluginTimerList - // could have been deleted by the timerFunc and we must ensure that we - // do not double delete. - if ((!m_repeat || m_unscheduled) && refCount() > 1) - deref(); // mark the timer for deletion as it is no longer needed - } - - // may return null if timerID is not found - PluginTimer* PluginTimer::Find(PluginTimer* list, uint32_t timerID) - { - PluginTimer* curr = list; - while (curr) { - if (curr->m_timerID == timerID) { - break; - } - curr = curr->m_next; - } - return curr; - } - - /////////////////////////////////////////////////////////////////////////// - - PluginTimerList::~PluginTimerList() - { - PluginTimer* curr = m_list; - PluginTimer* next; - while (curr) { - next = curr->next(); - curr->deref(); - curr = next; - } - } - - uint32_t PluginTimerList::schedule(NPP instance, uint32_t interval, bool repeat, - void (*proc)(NPP npp, uint32_t timerID)) - { - PluginTimer* timer = new PluginTimer(&m_list, instance, repeat, proc); - - double dinterval = interval * 0.001; // milliseconds to seconds - if (repeat) { - timer->startRepeating(dinterval); - } else { - timer->startOneShot(dinterval); - } - return timer->timerID(); - } - - void PluginTimerList::unschedule(NPP instance, uint32_t timerID) - { - // Although it looks like simply deleting the timer would work here - // (stop() will be executed by the dtor), we cannot do this, as - // the plugin can call us while we are in the fired() method, - // (when we execute the timerFunc callback). Deleting the object - // we are in would then be a rather bad move... - PluginTimer* timer = PluginTimer::Find(m_list, timerID); - if (timer) - timer->unschedule(); - } - -} // namespace WebCore diff --git a/WebKit/android/plugins/PluginTimer.h b/WebKit/android/plugins/PluginTimer.h deleted file mode 100644 index 20c0816..0000000 --- a/WebKit/android/plugins/PluginTimer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2008 Google Inc. All rights reserved. - * - * 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 PluginTimer_H -#define PluginTimer_H - -#include "RefCounted.h" -#include "Timer.h" -#include "npapi.h" - -namespace WebCore { - - class PluginTimerList; - - class PluginTimer : public TimerBase, public RefCounted<PluginTimer> { - public: - PluginTimer(PluginTimer** list, NPP instance, bool repeat, - void (*proc)(NPP npp, uint32_t timerID)); - virtual ~PluginTimer(); - - uint32_t timerID() const { return m_timerID; } - - void unschedule() { m_unscheduled = true; } - - static PluginTimer* Find(PluginTimer* list, uint32_t timerID); - - private: - // override from TimerBase - virtual void fired(); - - PluginTimer* next() const { return m_next; } - friend class PluginTimerList; - - PluginTimer** m_list; - PluginTimer* m_prev; - PluginTimer* m_next; - NPP m_instance; - void (*m_timerFunc)(NPP, uint32_t); - uint32_t m_timerID; - bool m_repeat; - bool m_unscheduled; - }; - - class PluginTimerList { - public: - PluginTimerList() : m_list(0) {} - ~PluginTimerList(); - - uint32_t schedule(NPP instance, uint32_t interval, bool repeat, - void (*proc)(NPP npp, uint32_t timerID)); - void unschedule(NPP instance, uint32_t timerID); - - private: - PluginTimer* m_list; - }; - -} // namespace WebCore - -#endif diff --git a/WebKit/android/plugins/PluginViewBridgeAndroid.cpp b/WebKit/android/plugins/PluginViewBridgeAndroid.cpp deleted file mode 100644 index 2be9dc3..0000000 --- a/WebKit/android/plugins/PluginViewBridgeAndroid.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2008, 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 "PluginViewBridgeAndroid.h" - -namespace WebCore { - - void PluginViewBridgeAndroid::draw(GraphicsContext* gc, - const IntRect& rect) {} - - bool PluginViewBridgeAndroid::forPluginView() const { - return true; - } - -} diff --git a/WebKit/android/plugins/PluginViewBridgeAndroid.h b/WebKit/android/plugins/PluginViewBridgeAndroid.h deleted file mode 100644 index 5d16f46..0000000 --- a/WebKit/android/plugins/PluginViewBridgeAndroid.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. All rights reserved. - * - * 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 PluginViewBridgeAndroid_H -#define PluginViewBridgeAndroid_H - -#include "PluginView.h" -#include "WebCoreViewBridge.h" - -namespace WebCore { - - // (Dummy for now) WebCoreViewBridge associated with a PluginView Widget. - class PluginViewBridgeAndroid : public WebCoreViewBridge { - public: - PluginViewBridgeAndroid() {} - - // overrides - virtual void draw(GraphicsContext* gc, const IntRect& rect); - virtual bool forPluginView() const; - }; - -} // namespace WebCore - -#endif diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp deleted file mode 100644 index b8a10cc..0000000 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright 2008, 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 "PluginWidgetAndroid.h" - -#if ENABLE(TOUCH_EVENTS) -#include "ChromeClient.h" -#endif -#include "Document.h" -#include "Element.h" -#include "Frame.h" -#include "Page.h" -#include "PluginPackage.h" -#include "PluginView.h" -#include "PluginWidgetAndroid.h" -#include "ScrollView.h" -#include "SkANP.h" -#include "SkFlipPixelRef.h" -#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 -#define DEBUG_EVENTS 0 // logs event contents, return value, and processing time -#define DEBUG_VISIBLE_RECTS 0 // temporary debug printfs and fixes - -// this include statement must follow the declaration of PLUGIN_DEBUG_LOCAL -#include "PluginDebugAndroid.h" - -PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) - : m_pluginView(view) { - m_flipPixelRef = NULL; - m_core = NULL; - m_drawingModel = kBitmap_ANPDrawingModel; - m_eventFlags = 0; - m_pluginWindow = NULL; - m_requestedVisibleRectCount = 0; - m_requestedVisibleRect.setEmpty(); - m_visibleDocRect.setEmpty(); - m_pluginBounds.setEmpty(); - m_hasFocus = false; - m_isFullScreen = false; - m_visible = false; - m_cachedZoomLevel = 0; - m_embeddedView = NULL; - m_embeddedViewAttached = false; - m_acceptEvents = false; - m_isSurfaceClippedOut = false; - m_layer = 0; - m_powerState = kDefault_ANPPowerState; -} - -PluginWidgetAndroid::~PluginWidgetAndroid() { - PLUGIN_LOG("%p Deleting Plugin", m_pluginView->instance()); - m_acceptEvents = false; - if (m_core) { - setPowerState(kDefault_ANPPowerState); - m_core->removePlugin(this); - if (m_isFullScreen) { - exitFullScreen(true); - } - if (m_embeddedView) { - m_core->destroySurface(m_embeddedView); - } - } - - // cleanup any remaining JNI References - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (m_embeddedView) { - env->DeleteGlobalRef(m_embeddedView); - } - - SkSafeUnref(m_flipPixelRef); - - if (m_layer) - m_layer->unref(); -} - -void PluginWidgetAndroid::init(android::WebViewCore* core) { - m_core = core; - m_core->addPlugin(this); - m_acceptEvents = true; - PLUGIN_LOG("%p Initialized Plugin", m_pluginView->instance()); -} - -static SkBitmap::Config computeConfig(bool isTransparent) { - return isTransparent ? SkBitmap::kARGB_8888_Config - : SkBitmap::kRGB_565_Config; -} - -void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { - - // store the reference locally for easy lookup - m_pluginWindow = window; - - // make a copy of the previous bounds - SkIRect oldPluginBounds = m_pluginBounds; - - // keep a local copy of the plugin bounds because the m_pluginWindow pointer - // gets updated values prior to this method being called - m_pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->x + m_pluginWindow->width, - m_pluginWindow->y + m_pluginWindow->height); - - PLUGIN_LOG("%p PluginBounds (%d,%d,%d,%d)", m_pluginView->instance(), - m_pluginBounds.fLeft, m_pluginBounds.fTop, - m_pluginBounds.fRight, m_pluginBounds.fBottom); - - const bool boundsChanged = m_pluginBounds != oldPluginBounds; - - //TODO hack to ensure that we grab the most recent screen dimensions and scale - ANPRectI screenCoords; - m_core->getVisibleScreen(screenCoords); - float scale = m_core->scale(); - bool scaleChanged = m_cachedZoomLevel != scale; - setVisibleScreen(screenCoords, scale); - - // if the scale changed then setVisibleScreen will call this function and - // this call will potentially fire a duplicate draw event - if (!scaleChanged) { - sendSizeAndVisibilityEvents(boundsChanged); - } - layoutSurface(boundsChanged); - - if (m_drawingModel != kSurface_ANPDrawingModel) { - SkSafeUnref(m_flipPixelRef); - m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent), - window->width, window->height); - } -} - -bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { - - if (model == kOpenGL_ANPDrawingModel && m_layer == 0) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject webview = m_core->getWebViewJavaObject(); - jobject weakWebViewRef = 0; - if (webview) - weakWebViewRef = env->NewWeakGlobalRef(webview); - m_layer = new WebCore::MediaLayer(weakWebViewRef); - } - else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) { - m_layer->unref(); - m_layer = 0; - } - - if (m_drawingModel != model) { - // Trigger layer computation in RenderLayerCompositor - m_pluginView->getElement()->setNeedsStyleRecalc(SyntheticStyleChange); - } - - m_drawingModel = model; - return true; -} - -// returned rect is in the page coordinate -bool PluginWidgetAndroid::isDirty(SkIRect* rect) const { - // nothing to report if we haven't had setWindow() called yet - if (NULL == m_flipPixelRef) { - return false; - } - - const SkRegion& dirty = m_flipPixelRef->dirtyRgn(); - if (dirty.isEmpty()) { - return false; - } else { - if (rect) { - *rect = dirty.getBounds(); - rect->offset(m_pluginWindow->x, m_pluginWindow->y); - } - return true; - } -} - -void PluginWidgetAndroid::inval(const WebCore::IntRect& rect, - bool signalRedraw) { - // nothing to do if we haven't had setWindow() called yet. m_flipPixelRef - // will also be null if this is a Surface model. - if (NULL == m_flipPixelRef) { - return; - } - - m_flipPixelRef->inval(rect); - - if (signalRedraw && m_flipPixelRef->isDirty()) { - m_core->invalPlugin(this); - } -} - -void PluginWidgetAndroid::viewInvalidate() { - WebCore::IntRect rect(m_pluginBounds.fLeft, m_pluginBounds.fTop, - m_pluginBounds.width(), m_pluginBounds.height()); - m_core->viewInvalidate(rect); -} - -void PluginWidgetAndroid::draw(SkCanvas* canvas) { - if (NULL == m_flipPixelRef || !m_flipPixelRef->isDirty()) { - return; - } - - SkAutoFlipUpdate update(m_flipPixelRef); - const SkBitmap& bitmap = update.bitmap(); - const SkRegion& dirty = update.dirty(); - - ANPEvent event; - SkANP::InitEvent(&event, kDraw_ANPEventType); - - event.data.draw.model = m_drawingModel; - SkANP::SetRect(&event.data.draw.clip, dirty.getBounds()); - - switch (m_drawingModel) { - case kBitmap_ANPDrawingModel: { - WebCore::PluginPackage* pkg = m_pluginView->plugin(); - NPP instance = m_pluginView->instance(); - - if (SkANP::SetBitmap(&event.data.draw.data.bitmap, - bitmap) && - pkg->pluginFuncs()->event(instance, &event)) { - - if (canvas && m_pluginWindow) { - SkBitmap bm(bitmap); - bm.setPixelRef(m_flipPixelRef); - canvas->drawBitmap(bm, 0, 0); - } - } - break; - } - default: - break; - } -} - -void PluginWidgetAndroid::setSurfaceClip(const SkIRect& clip) { - - if (m_drawingModel != kSurface_ANPDrawingModel) - return; - - /* don't display surfaces that are either entirely clipped or only 1x1 in - size. It appears that when an element is absolutely positioned and has - been completely clipped in CSS that webkit still sends a clip of 1x1. - */ - bool clippedOut = (clip.width() <= 1 && clip.height() <= 1); - if(clippedOut != m_isSurfaceClippedOut) { - m_isSurfaceClippedOut = clippedOut; - layoutSurface(); - } -} - -void PluginWidgetAndroid::layoutSurface(bool pluginBoundsChanged) { - - if (m_drawingModel != kSurface_ANPDrawingModel) - return; - if (!m_pluginWindow) - return; - - - bool displayPlugin = m_pluginView->isVisible() && !m_isSurfaceClippedOut; - PLUGIN_LOG("%p DisplayPlugin[%d] visible=[%d] clipped=[%d]", - m_pluginView->instance(), displayPlugin, - m_pluginView->isVisible(), m_isSurfaceClippedOut); - - // if the surface does not exist then create a new surface - if (!m_embeddedView && displayPlugin) { - - WebCore::PluginPackage* pkg = m_pluginView->plugin(); - NPP instance = m_pluginView->instance(); - - jobject pluginSurface; - pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue, - static_cast<void*>(&pluginSurface)); - - jobject tempObj = m_core->addSurface(pluginSurface, - m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->width, m_pluginWindow->height); - - if (tempObj) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - m_embeddedView = env->NewGlobalRef(tempObj); - m_embeddedViewAttached = true; - } - // if the view is unattached but visible then attach it - } else if (m_embeddedView && !m_embeddedViewAttached && displayPlugin && !m_isFullScreen) { - m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->width, m_pluginWindow->height); - m_embeddedViewAttached = true; - // if the view is attached but invisible then remove it - } else if (m_embeddedView && m_embeddedViewAttached && !displayPlugin) { - m_core->destroySurface(m_embeddedView); - m_embeddedViewAttached = false; - // if the plugin's bounds have changed and it's visible then update it - } else if (pluginBoundsChanged && displayPlugin && !m_isFullScreen) { - m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->width, m_pluginWindow->height); - - } -} - -int16_t PluginWidgetAndroid::sendEvent(const ANPEvent& evt) { - if (!m_acceptEvents) - return 0; - WebCore::PluginPackage* pkg = m_pluginView->plugin(); - NPP instance = m_pluginView->instance(); - // "missing" plugins won't have these - if (pkg && instance) { - - // if the plugin is gaining focus then update our state now to allow - // the plugin's event handler to perform actions that require focus - if (evt.eventType == kLifecycle_ANPEventType && - evt.data.lifecycle.action == kGainFocus_ANPLifecycleAction) { - m_hasFocus = true; - } - -#if DEBUG_EVENTS - SkMSec startTime = SkTime::GetMSecs(); -#endif - - // make a localCopy since the actual plugin may not respect its constness, - // and so we don't want our caller to have its param modified - ANPEvent localCopy = evt; - int16_t result = pkg->pluginFuncs()->event(instance, &localCopy); - -#if DEBUG_EVENTS - SkMSec endTime = SkTime::GetMSecs(); - PLUGIN_LOG_EVENT(instance, &evt, result, endTime - startTime); -#endif - - // if the plugin is losing focus then delay the update of our state - // until after we notify the plugin and allow them to perform actions - // that may require focus - if (evt.eventType == kLifecycle_ANPEventType && - evt.data.lifecycle.action == kLoseFocus_ANPLifecycleAction) { - m_hasFocus = false; - } - - return result; - } - return 0; -} - -void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) { - - // if there are no differences then immediately return - if (m_eventFlags == flags) { - return; - } - - Document* doc = m_pluginView->parentFrame()->document(); -#if ENABLE(TOUCH_EVENTS) - if((m_eventFlags ^ flags) & kTouch_ANPEventFlag) { - if (flags & kTouch_ANPEventFlag) - doc->addListenerTypeIfNeeded(eventNames().touchstartEvent); - } -#endif - - m_eventFlags = flags; -} - -bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) { - return m_eventFlags & flag; -} - -void PluginWidgetAndroid::sendSizeAndVisibilityEvents(const bool updateDimensions) { - // TODO update the bitmap size based on the zoom? (for kBitmap_ANPDrawingModel) - - const float zoomLevel = m_core->scale(); - - // notify the plugin of the new size - if (m_drawingModel == kOpenGL_ANPDrawingModel && updateDimensions && m_pluginWindow) { - PLUGIN_LOG("%s (%d,%d)[%f]", __FUNCTION__, m_pluginWindow->width, - m_pluginWindow->height, zoomLevel); - ANPEvent event; - SkANP::InitEvent(&event, kDraw_ANPEventType); - event.data.draw.model = kOpenGL_ANPDrawingModel; - event.data.draw.data.surface.width = m_pluginWindow->width * zoomLevel; - event.data.draw.data.surface.height = m_pluginWindow->height * zoomLevel; - sendEvent(event); - } - - bool visible = SkIRect::Intersects(m_visibleDocRect, m_pluginBounds); - if(m_visible != visible) { - -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%p changeVisiblity[%d] pluginBounds(%d,%d,%d,%d)", - m_pluginView->instance(), visible, - m_pluginBounds.fLeft, m_pluginBounds.fTop, - m_pluginBounds.fRight, m_pluginBounds.fBottom); -#endif - - // change the visibility - m_visible = visible; - // send the event - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = visible ? kOnScreen_ANPLifecycleAction - : kOffScreen_ANPLifecycleAction; - sendEvent(event); - } -} - -void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float zoom) { -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%s (%d,%d,%d,%d)[%f]", __FUNCTION__, visibleDocRect.left, - visibleDocRect.top, visibleDocRect.right, - visibleDocRect.bottom, zoom); -#endif - int oldScreenW = m_visibleDocRect.width(); - int oldScreenH = m_visibleDocRect.height(); - - const bool zoomChanged = m_cachedZoomLevel != zoom; - - // make local copies of the parameters - m_cachedZoomLevel = zoom; - m_visibleDocRect.set(visibleDocRect.left, - visibleDocRect.top, - visibleDocRect.right, - visibleDocRect.bottom); - - int newScreenW = m_visibleDocRect.width(); - int newScreenH = m_visibleDocRect.height(); - - // if the screen dimensions have changed by more than 5 pixels in either - // direction then recompute the plugin's visible rectangle - if (abs(oldScreenW - newScreenW) > 5 || abs(oldScreenH - newScreenH) > 5) { - PLUGIN_LOG("%s VisibleDoc old=[%d,%d] new=[%d,%d] ", __FUNCTION__, - oldScreenW, oldScreenH, newScreenW, newScreenH); - computeVisiblePluginRect(); - } - - sendSizeAndVisibilityEvents(zoomChanged); -} - -ANPRectI PluginWidgetAndroid::visibleRect() { - - SkIRect visibleRect; - visibleRect.setEmpty(); - - // compute the interesection of the visible screen and the plugin - bool visible = visibleRect.intersect(m_visibleDocRect, m_pluginBounds); - if (visible) { - // convert from absolute coordinates to the plugin's relative coordinates - visibleRect.offset(-m_pluginBounds.fLeft, -m_pluginBounds.fTop); - } - - // convert from SkRect to ANPRect - ANPRectI result; - memcpy(&result, &visibleRect, sizeof(ANPRectI)); - return result; -} - -void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) { -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%s count=%d", __FUNCTION__, count); -#endif - // ensure the count does not exceed our allocated space - if (count > MAX_REQUESTED_RECTS) - count = MAX_REQUESTED_RECTS; - - // store the values in member variables - m_requestedVisibleRectCount = count; - memcpy(m_requestedVisibleRects, rects, count * sizeof(rects[0])); - -#if DEBUG_VISIBLE_RECTS // FIXME: this fixes bad data from the plugin - // take it out once plugin supplies better data - for (int index = 0; index < count; index++) { - PLUGIN_LOG("%s [%d](%d,%d,%d,%d)", __FUNCTION__, index, - m_requestedVisibleRects[index].left, - m_requestedVisibleRects[index].top, - m_requestedVisibleRects[index].right, - m_requestedVisibleRects[index].bottom); - if (m_requestedVisibleRects[index].left == - m_requestedVisibleRects[index].right) { - m_requestedVisibleRects[index].right += 1; - } - if (m_requestedVisibleRects[index].top == - m_requestedVisibleRects[index].bottom) { - m_requestedVisibleRects[index].bottom += 1; - } - } -#endif - computeVisiblePluginRect(); -} - -void PluginWidgetAndroid::computeVisiblePluginRect() { - - // ensure the visibleDocRect has been set (i.e. not equal to zero) - if (m_visibleDocRect.isEmpty() || !m_pluginWindow || m_requestedVisibleRectCount < 1) - return; - - // create a rect that will contain as many of the rects that will fit on screen - SkIRect visibleRect; - visibleRect.setEmpty(); - - for (int counter = 0; counter < m_requestedVisibleRectCount; counter++) { - - ANPRectI* rect = &m_requestedVisibleRects[counter]; - - // create skia rect for easier manipulation and convert it to page coordinates - SkIRect pluginRect; - pluginRect.set(rect->left, rect->top, rect->right, rect->bottom); - pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y); - - // ensure the rect falls within the plugin's bounds - if (!m_pluginBounds.contains(pluginRect)) { -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%s (%d,%d,%d,%d) !contain (%d,%d,%d,%d)", __FUNCTION__, - m_pluginBounds.fLeft, m_pluginBounds.fTop, - m_pluginBounds.fRight, m_pluginBounds.fBottom, - pluginRect.fLeft, pluginRect.fTop, - pluginRect.fRight, pluginRect.fBottom); - // assume that the desired outcome is to clamp to the container - if (pluginRect.intersect(m_pluginBounds)) { - visibleRect = pluginRect; - } -#endif - continue; - } - - // combine this new rect with the higher priority rects - pluginRect.join(visibleRect); - - // check to see if the new rect could be made to fit within the screen - // bounds. If this is the highest priority rect then attempt to center - // even if it doesn't fit on the screen. - if (counter > 0 && (m_visibleDocRect.width() < pluginRect.width() || - m_visibleDocRect.height() < pluginRect.height())) - break; - - // set the new visible rect - visibleRect = pluginRect; - } - - m_requestedVisibleRect = visibleRect; - scrollToVisiblePluginRect(); -} - -void PluginWidgetAndroid::scrollToVisiblePluginRect() { - - if (!m_hasFocus || m_requestedVisibleRect.isEmpty() || m_visibleDocRect.isEmpty()) { -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%s call m_hasFocus=%d m_requestedVisibleRect.isEmpty()=%d" - " m_visibleDocRect.isEmpty()=%d", __FUNCTION__, m_hasFocus, - m_requestedVisibleRect.isEmpty(), m_visibleDocRect.isEmpty()); -#endif - return; - } - // if the entire rect is already visible then we don't need to scroll - if (m_visibleDocRect.contains(m_requestedVisibleRect)) - return; - - // find the center of the visibleRect in document coordinates - int rectCenterX = m_requestedVisibleRect.fLeft + m_requestedVisibleRect.width()/2; - int rectCenterY = m_requestedVisibleRect.fTop + m_requestedVisibleRect.height()/2; - - // find document coordinates for center of the visible screen - int visibleDocCenterX = m_visibleDocRect.fLeft + m_visibleDocRect.width()/2; - int visibleDocCenterY = m_visibleDocRect.fTop + m_visibleDocRect.height()/2; - - //compute the delta of the two points and scale to screen coordinates - int deltaX = rectCenterX - visibleDocCenterX; - int deltaY = rectCenterY - visibleDocCenterY; - - ScrollView* scrollView = m_pluginView->parent(); - android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView); -#if DEBUG_VISIBLE_RECTS - PLUGIN_LOG("%s call scrollBy (%d,%d)", __FUNCTION__, deltaX, deltaY); -#endif - core->scrollTo(rectCenterX, rectCenterY, true); -} - -void PluginWidgetAndroid::requestFullScreen() { - if (m_isFullScreen) { - return; - } - - if (!m_embeddedView && m_drawingModel == kOpenGL_ANPDrawingModel) { - WebCore::PluginPackage* pkg = m_pluginView->plugin(); - NPP instance = m_pluginView->instance(); - - jobject pluginSurface; - pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue, - static_cast<void*>(&pluginSurface)); - - // create the surface, but do not add it to the view hierarchy - jobject tempObj = m_core->createSurface(pluginSurface); - - if (tempObj) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - m_embeddedView = env->NewGlobalRef(tempObj); - m_embeddedViewAttached = false; - } - } - - if (!m_embeddedView) { - return; - } - - // send event to notify plugin of full screen change - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kEnterFullScreen_ANPLifecycleAction; - sendEvent(event); - - // remove the embedded surface from the view hierarchy - if (m_drawingModel != kOpenGL_ANPDrawingModel) - m_core->destroySurface(m_embeddedView); - - // add the full screen view - m_core->showFullScreenPlugin(m_embeddedView, m_pluginView->instance()); - m_isFullScreen = true; -} - -void PluginWidgetAndroid::exitFullScreen(bool pluginInitiated) { - if (!m_isFullScreen || !m_embeddedView) { - return; - } - - // remove the full screen surface from the view hierarchy - if (pluginInitiated) { - m_core->hideFullScreenPlugin(); - } - - // add the embedded view back - if (m_drawingModel != kOpenGL_ANPDrawingModel) - m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->width, m_pluginWindow->height); - - // send event to notify plugin of full screen change - ANPEvent event; - SkANP::InitEvent(&event, kLifecycle_ANPEventType); - event.data.lifecycle.action = kExitFullScreen_ANPLifecycleAction; - sendEvent(event); - - m_isFullScreen = false; -} - -void PluginWidgetAndroid::requestCenterFitZoom() { - m_core->centerFitRect(m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->width, m_pluginWindow->height); -} - -void PluginWidgetAndroid::setPowerState(ANPPowerState powerState) { - if(m_powerState == powerState) - return; - - // cleanup the old power state - switch (m_powerState) { - case kDefault_ANPPowerState: - break; - case kScreenOn_ANPPowerState: - m_core->keepScreenOn(false); - break; - } - - // setup the new power state - switch (powerState) { - case kDefault_ANPPowerState: - break; - case kScreenOn_ANPPowerState: - m_core->keepScreenOn(true); - break; - } - - m_powerState = powerState; -} - diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h deleted file mode 100644 index 5d586b1..0000000 --- a/WebKit/android/plugins/PluginWidgetAndroid.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2008, 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 PluginWidgetAndroid_H -#define PluginWidgetAndroid_H - -#include "android_npapi.h" -#include "ANPSystem_npapi.h" -#include "IntPoint.h" -#include "IntRect.h" -#include "MediaLayer.h" -#include "SkRect.h" -#include <jni.h> - -namespace WebCore { - class PluginView; -} - -namespace android { - class PluginSurface; - class WebViewCore; -} - -class SkCanvas; -class SkFlipPixelRef; - -/* - This is our extended state in a PluginView. This object is created and - kept insync with the PluginView, but is also available to WebViewCore - to allow its draw() method to be called from outside of the PluginView. - */ -struct PluginWidgetAndroid { - // initialize with our host pluginview. This will delete us when it is - // destroyed. - PluginWidgetAndroid(WebCore::PluginView* view); - ~PluginWidgetAndroid(); - - WebCore::PluginView* pluginView() const { return m_pluginView; } - - // Needed by PluginSurface to manage the java SurfaceView. - android::WebViewCore* webViewCore() const { return m_core; } - - /* Can't determine our core at construction time, so PluginView calls this - as soon as it has a parent. - */ - void init(android::WebViewCore*); - /* Called each time the PluginView gets a new size or position. - */ - void setWindow(NPWindow* window, bool isTransparent); - - /* Called whenever the plugin itself requests a new drawing model. If the - hardware does not support the requested model then false is returned, - otherwise true is returned. - */ - bool setDrawingModel(ANPDrawingModel); - - /* Called to check if the plugin is running in "windowed" mode (i.e. surface - view). - */ - bool isSurfaceDrawingModel() const { return kSurface_ANPDrawingModel == m_drawingModel; } - - bool isOpenGLDrawingModel() const { return kOpenGL_ANPDrawingModel == m_drawingModel; } - - /* Returns true (and optionally updates rect with the dirty bounds in the - page coordinate) if the plugin has invalidate us. - */ - bool isDirty(SkIRect* dirtyBounds = NULL) const; - /* Called by PluginView to invalidate a portion of the plugin area (in - local plugin coordinates). If signalRedraw is true, this also triggers - a subsequent call to draw(NULL). - */ - void inval(const WebCore::IntRect&, bool signalRedraw); - - /* 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); - - /* Send this event to the plugin instance. A non-zero value will be - returned if the plugin handled the event. - */ - int16_t sendEvent(const ANPEvent&); - - /* Update the plugins event flags. If a flag is set to true then the plugin - wants to be notified of events of this type. - */ - void updateEventFlags(ANPEventFlags); - - /* Called to check if a plugin wants to accept a given event type. It - returns true if the plugin wants the events and false otherwise. - */ - bool isAcceptingEvent(ANPEventFlag); - - /* Notify the plugin of the currently visible screen coordinates (document - space) and the current zoom level. - */ - void setVisibleScreen(const ANPRectI& visibleScreenRect, float zoom); - - /** Returns a rectangle representing the visible area of the plugin on - screen. The coordinates are relative to the size of the plugin in the - document and will not be negative or exceed the plugin's size. - */ - ANPRectI visibleRect(); - - /** Registers a set of rectangles that the plugin would like to keep on - screen. The rectangles are listed in order of priority with the highest - priority rectangle in location rects[0]. The browser will attempt to keep - as many of the rectangles on screen as possible and will scroll them into - view in response to the invocation of this method and other various events. - The count specifies how many rectangles are in the array. If the count is - zero it signals the plugin that any existing rectangles should be cleared - and no rectangles will be tracked. - */ - void setVisibleRects(const ANPRectI rects[], int32_t count); - - /** Called when a plugin wishes to enter into full screen mode. It invokes - the plugin's Java class (defined in the plugin's apk manifest), which is - called asynchronously and provides a View to be displayed full screen. - */ - void requestFullScreen(); - - /** Called when a plugin wishes to exit from full screen mode. As a result, - the plugin's full-screen view is discarded by the view system. It is also - called in order to notify the native code that the browser has discarded - the view. - */ - void exitFullScreen(bool pluginInitiated); - - bool inFullScreen() { return m_isFullScreen; } - - /** Called to check if a plugin currently has document focus, which is - required for certain operations (e.g. show/hide keyboard). It returns - true if the plugin currently has focus and false otherwise. - */ - bool hasFocus() const { return m_hasFocus; } - - /** Called to ensure the surface is being correctly displayed within the - view hierarchy. For instance, if the visibility of the plugin has - changed then we need to ensure the surface is added or removed from the - view system. - */ - void layoutSurface(bool pluginBoundsChanged = false); - - /** send the surface the currently visible portion of the plugin. This is not - the portion of the plugin visible on the screen but rather the portion of - the plugin that is not obscured by other HTML content. - */ - void setSurfaceClip(const SkIRect& clip); - - /** Called when a plugin wishes to be zoomed and centered in the current view. - */ - void requestCenterFitZoom(); - - WebCore::MediaLayer* getLayer() const { return m_layer; } - - void setPowerState(ANPPowerState powerState); - - void viewInvalidate(); - -private: - void computeVisiblePluginRect(); - void scrollToVisiblePluginRect(); - void sendSizeAndVisibilityEvents(const bool updateDimensions); - - WebCore::MediaLayer* m_layer; - - WebCore::PluginView* m_pluginView; - android::WebViewCore* m_core; - SkFlipPixelRef* m_flipPixelRef; - ANPDrawingModel m_drawingModel; - ANPEventFlags m_eventFlags; - NPWindow* m_pluginWindow; - SkIRect m_pluginBounds; // relative to the page - SkIRect m_visibleDocRect; // relative to the page - SkIRect m_requestedVisibleRect; // relative to the page - bool m_hasFocus; - bool m_isFullScreen; - bool m_visible; - float m_cachedZoomLevel; // used for comparison only - jobject m_embeddedView; - bool m_embeddedViewAttached; - bool m_acceptEvents; - bool m_isSurfaceClippedOut; - ANPPowerState m_powerState; - - /* We limit the number of rectangles to minimize storage and ensure adequate - speed. - */ - enum { - MAX_REQUESTED_RECTS = 5, - }; - - ANPRectI m_requestedVisibleRects[MAX_REQUESTED_RECTS]; - int32_t m_requestedVisibleRectCount; -}; - -#endif diff --git a/WebKit/android/plugins/SkANP.cpp b/WebKit/android/plugins/SkANP.cpp deleted file mode 100644 index 720387d..0000000 --- a/WebKit/android/plugins/SkANP.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2008, 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. - */ - -// must include config.h first for webkit to fiddle with new/delete -#include "config.h" -#include "SkANP.h" -#include <wtf/CurrentTime.h> - -SkRect* SkANP::SetRect(SkRect* dst, const ANPRectF& src) { - dst->set(SkFloatToScalar(src.left), - SkFloatToScalar(src.top), - SkFloatToScalar(src.right), - SkFloatToScalar(src.bottom)); - return dst; -} - -SkIRect* SkANP::SetRect(SkIRect* dst, const ANPRectI& src) { - dst->set(src.left, src.top, src.right, src.bottom); - return dst; -} - -ANPRectI* SkANP::SetRect(ANPRectI* dst, const SkIRect& src) { - dst->left = src.fLeft; - dst->top = src.fTop; - dst->right = src.fRight; - dst->bottom = src.fBottom; - return dst; -} - -ANPRectF* SkANP::SetRect(ANPRectF* dst, const SkRect& src) { - dst->left = SkScalarToFloat(src.fLeft); - dst->top = SkScalarToFloat(src.fTop); - dst->right = SkScalarToFloat(src.fRight); - dst->bottom = SkScalarToFloat(src.fBottom); - return dst; -} - -SkBitmap* SkANP::SetBitmap(SkBitmap* dst, const ANPBitmap& src) { - SkBitmap::Config config = SkBitmap::kNo_Config; - - switch (src.format) { - case kRGBA_8888_ANPBitmapFormat: - config = SkBitmap::kARGB_8888_Config; - break; - case kRGB_565_ANPBitmapFormat: - config = SkBitmap::kRGB_565_Config; - break; - default: - break; - } - - dst->setConfig(config, src.width, src.height, src.rowBytes); - dst->setPixels(src.baseAddr); - return dst; -} - -bool SkANP::SetBitmap(ANPBitmap* dst, const SkBitmap& src) { - if (!(dst->baseAddr = src.getPixels())) { - SkDebugf("SkANP::SetBitmap - getPixels() returned null\n"); - return false; - } - - switch (src.config()) { - case SkBitmap::kARGB_8888_Config: - dst->format = kRGBA_8888_ANPBitmapFormat; - break; - case SkBitmap::kRGB_565_Config: - dst->format = kRGB_565_ANPBitmapFormat; - break; - default: - SkDebugf("SkANP::SetBitmap - unsupported src.config %d\n", src.config()); - return false; - } - - dst->width = src.width(); - dst->height = src.height(); - dst->rowBytes = src.rowBytes(); - return true; -} - -void SkANP::InitEvent(ANPEvent* event, ANPEventType et) { - event->inSize = sizeof(ANPEvent); - event->eventType = et; -} diff --git a/WebKit/android/plugins/SkANP.h b/WebKit/android/plugins/SkANP.h deleted file mode 100644 index 5c2a936..0000000 --- a/WebKit/android/plugins/SkANP.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2008, 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 SkANP_DEFINED -#define SkANP_DEFINED - -#include "android_npapi.h" -#include "SkCanvas.h" -#include "SkMatrix.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "SkTypeface.h" - -struct ANPMatrix : SkMatrix { -}; - -struct ANPPath : SkPath { -}; - -struct ANPPaint : SkPaint { -}; - -struct ANPTypeface : SkTypeface { -}; - -struct ANPCanvas { - SkCanvas* skcanvas; - - // draw into the specified bitmap - explicit ANPCanvas(const SkBitmap& bm) { - skcanvas = new SkCanvas(bm); - } - - // redirect all drawing to the specific SkCanvas - explicit ANPCanvas(SkCanvas* other) { - skcanvas = other; - skcanvas->ref(); - } - - ~ANPCanvas() { - skcanvas->unref(); - } -}; - -class SkANP { -public: - static SkRect* SetRect(SkRect* dst, const ANPRectF& src); - static SkIRect* SetRect(SkIRect* dst, const ANPRectI& src); - static ANPRectI* SetRect(ANPRectI* dst, const SkIRect& src); - static ANPRectF* SetRect(ANPRectF* dst, const SkRect& src); - static SkBitmap* SetBitmap(SkBitmap* dst, const ANPBitmap& src); - static bool SetBitmap(ANPBitmap* dst, const SkBitmap& src); - - static void InitEvent(ANPEvent* event, ANPEventType et); -}; - -#endif diff --git a/WebKit/android/plugins/SurfaceCallback.h b/WebKit/android/plugins/SurfaceCallback.h deleted file mode 100644 index 945fc3f..0000000 --- a/WebKit/android/plugins/SurfaceCallback.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2008 Google Inc. All rights reserved. - * - * 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 SurfaceCallback_H -#define SurfaceCallback_H - -namespace android { - - class SurfaceCallback { - public: - virtual ~SurfaceCallback() {} - virtual void surfaceCreated() = 0; - virtual void surfaceChanged(int format, int width, int height) = 0; - virtual void surfaceDestroyed() = 0; - }; - -} // namespace android - -#endif diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h deleted file mode 100644 index b0c3765..0000000 --- a/WebKit/android/plugins/android_npapi.h +++ /dev/null @@ -1,987 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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. - */ - -/* Defines the android-specific types and functions as part of npapi - - In particular, defines the window and event types that are passed to - NPN_GetValue, NPP_SetWindow and NPP_HandleEvent. - - To minimize what native libraries the plugin links against, some - functionality is provided via function-ptrs (e.g. time, sound) - */ - -#ifndef android_npapi_H -#define android_npapi_H - -#include <stdint.h> - -#include "npapi.h" - -/////////////////////////////////////////////////////////////////////////////// -// General types - -enum ANPBitmapFormats { - kUnknown_ANPBitmapFormat = 0, - kRGBA_8888_ANPBitmapFormat = 1, - kRGB_565_ANPBitmapFormat = 2 -}; -typedef int32_t ANPBitmapFormat; - -struct ANPPixelPacking { - uint8_t AShift; - uint8_t ABits; - uint8_t RShift; - uint8_t RBits; - uint8_t GShift; - uint8_t GBits; - uint8_t BShift; - uint8_t BBits; -}; - -struct ANPBitmap { - void* baseAddr; - ANPBitmapFormat format; - int32_t width; - int32_t height; - int32_t rowBytes; -}; - -struct ANPRectF { - float left; - float top; - float right; - float bottom; -}; - -struct ANPRectI { - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -}; - -struct ANPCanvas; -struct ANPMatrix; -struct ANPPaint; -struct ANPPath; -struct ANPRegion; -struct ANPTypeface; - -enum ANPMatrixFlags { - kIdentity_ANPMatrixFlag = 0, - kTranslate_ANPMatrixFlag = 0x01, - kScale_ANPMatrixFlag = 0x02, - kAffine_ANPMatrixFlag = 0x04, - kPerspective_ANPMatrixFlag = 0x08, -}; -typedef uint32_t ANPMatrixFlag; - -/////////////////////////////////////////////////////////////////////////////// -// NPN_GetValue - -/** queries for a specific ANPInterface. - - Maybe called with NULL for the NPP instance - - NPN_GetValue(inst, interface_enum, ANPInterface*) - */ -#define kLogInterfaceV0_ANPGetValue ((NPNVariable)1000) -#define kAudioTrackInterfaceV0_ANPGetValue ((NPNVariable)1001) -#define kCanvasInterfaceV0_ANPGetValue ((NPNVariable)1002) -#define kMatrixInterfaceV0_ANPGetValue ((NPNVariable)1003) -#define kPaintInterfaceV0_ANPGetValue ((NPNVariable)1004) -#define kPathInterfaceV0_ANPGetValue ((NPNVariable)1005) -#define kTypefaceInterfaceV0_ANPGetValue ((NPNVariable)1006) -#define kWindowInterfaceV0_ANPGetValue ((NPNVariable)1007) -#define kBitmapInterfaceV0_ANPGetValue ((NPNVariable)1008) -#define kSurfaceInterfaceV0_ANPGetValue ((NPNVariable)1009) -#define kSystemInterfaceV0_ANPGetValue ((NPNVariable)1010) -#define kEventInterfaceV0_ANPGetValue ((NPNVariable)1011) - -#define kAudioTrackInterfaceV1_ANPGetValue ((NPNVariable)1012) -#define kOpenGLInterfaceV0_ANPGetValue ((NPNVariable)1013) -#define kWindowInterfaceV1_ANPGetValue ((NPNVariable)1014) -#define kVideoInterfaceV0_ANPGetValue ((NPNVariable)1015) -#define kSystemInterfaceV1_ANPGetValue ((NPNVariable)1016) - -#define kSystemInterfaceV2_ANPGetValue ((NPNVariable)1017) - -/** queries for the drawing models supported on this device. - - NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits) - */ -#define kSupportedDrawingModel_ANPGetValue ((NPNVariable)2000) - -/** queries for the context (android.content.Context) of the plugin. If no - instance is specified the application's context is returned. If the instance - is given then the context returned is identical to the context used to - create the webview in which that instance resides. - - NOTE: Holding onto a non-application context after your instance has been - destroyed will cause a memory leak. Refer to the android documentation to - determine what context is best suited for your particular scenario. - - NPN_GetValue(inst, kJavaContext_ANPGetValue, jobject context) - */ -#define kJavaContext_ANPGetValue ((NPNVariable)2001) - -/////////////////////////////////////////////////////////////////////////////// -// NPN_SetValue - -/** Request to set the drawing model. SetValue will return false if the drawing - model is not supported or has insufficient information for configuration. - - NPN_SetValue(inst, kRequestDrawingModel_ANPSetValue, (void*)foo_ANPDrawingModel) - */ -#define kRequestDrawingModel_ANPSetValue ((NPPVariable)1000) - -/** These are used as bitfields in ANPSupportedDrawingModels_EnumValue, - and as-is in ANPRequestDrawingModel_EnumValue. The drawing model determines - how to interpret the ANPDrawingContext provided in the Draw event and how - to interpret the NPWindow->window field. - */ -enum ANPDrawingModels { - /** Draw into a bitmap from the browser thread in response to a Draw event. - NPWindow->window is reserved (ignore) - */ - kBitmap_ANPDrawingModel = 1 << 0, - /** Draw into a surface (e.g. raster, openGL, etc.) using the Java surface - interface. When this model is used the browser will invoke the Java - class specified in the plugin's apk manifest. From that class the browser - will invoke the appropriate method to return an an instance of a android - Java View. The instance is then embedded in the html. The plugin can then - manipulate the view as it would any normal Java View in android. - - Unlike the bitmap model, a surface model is opaque so no html content - behind the plugin will be visible. Unless the plugin needs to be - transparent the surface model should be chosen over the bitmap model as - it will have better performance. - - Further, a plugin can manipulate some surfaces in native code using the - ANPSurfaceInterface. This interface can be used to manipulate Java - objects that extend Surface.class by allowing them to access the - surface's underlying bitmap in native code. For instance, if a raster - surface is used the plugin can lock, draw directly into the bitmap, and - unlock the surface in native code without making JNI calls to the Java - surface object. - */ - kSurface_ANPDrawingModel = 1 << 1, - kOpenGL_ANPDrawingModel = 1 << 2, -}; -typedef int32_t ANPDrawingModel; - -/** Request to receive/disable events. If the pointer is NULL then all flags will - be disabled. Otherwise, the event type will be enabled iff its corresponding - bit in the EventFlags bit field is set. - - NPN_SetValue(inst, ANPAcceptEvents, (void*)EventFlags) - */ -#define kAcceptEvents_ANPSetValue ((NPPVariable)1001) - -/** The EventFlags are a set of bits used to determine which types of events the - plugin wishes to receive. For example, if the value is 0x03 then both key - and touch events will be provided to the plugin. - */ -enum ANPEventFlag { - kKey_ANPEventFlag = 0x01, - kTouch_ANPEventFlag = 0x02, -}; -typedef uint32_t ANPEventFlags; - -/////////////////////////////////////////////////////////////////////////////// -// NPP_GetValue - -/** Requests that the plugin return a java surface to be displayed. This will - only be used if the plugin has choosen the kSurface_ANPDrawingModel. - - NPP_GetValue(inst, kJavaSurface_ANPGetValue, jobject surface) - */ -#define kJavaSurface_ANPGetValue ((NPPVariable)2000) - - -/////////////////////////////////////////////////////////////////////////////// -// ANDROID INTERFACE DEFINITIONS - -/** Interfaces provide additional functionality to the plugin via function ptrs. - Once an interface is retrieved, it is valid for the lifetime of the plugin - (just like browserfuncs). - - All ANPInterfaces begin with an inSize field, which must be set by the - caller (plugin) with the number of bytes allocated for the interface. - e.g. SomeInterface si; si.inSize = sizeof(si); browser->getvalue(..., &si); - */ -struct ANPInterface { - uint32_t inSize; // size (in bytes) of this struct -}; - -enum ANPLogTypes { - kError_ANPLogType = 0, // error - kWarning_ANPLogType = 1, // warning - kDebug_ANPLogType = 2 // debug only (informational) -}; -typedef int32_t ANPLogType; - -struct ANPLogInterfaceV0 : ANPInterface { - /** dumps printf messages to the log file - e.g. interface->log(instance, kWarning_ANPLogType, "value is %d", value); - */ - void (*log)(ANPLogType, const char format[], ...); -}; - -struct ANPBitmapInterfaceV0 : ANPInterface { - /** Returns true if the specified bitmap format is supported, and if packing - is non-null, sets it to the packing info for that format. - */ - bool (*getPixelPacking)(ANPBitmapFormat, ANPPixelPacking* packing); -}; - -struct ANPMatrixInterfaceV0 : ANPInterface { - /** Return a new identity matrix - */ - ANPMatrix* (*newMatrix)(); - /** Delete a matrix previously allocated by newMatrix() - */ - void (*deleteMatrix)(ANPMatrix*); - - ANPMatrixFlag (*getFlags)(const ANPMatrix*); - - void (*copy)(ANPMatrix* dst, const ANPMatrix* src); - - /** Return the matrix values in a float array (allcoated by the caller), - where the values are treated as follows: - w = x * [6] + y * [7] + [8]; - x' = (x * [0] + y * [1] + [2]) / w; - y' = (x * [3] + y * [4] + [5]) / w; - */ - void (*get3x3)(const ANPMatrix*, float[9]); - /** Initialize the matrix from values in a float array, - where the values are treated as follows: - w = x * [6] + y * [7] + [8]; - x' = (x * [0] + y * [1] + [2]) / w; - y' = (x * [3] + y * [4] + [5]) / w; - */ - void (*set3x3)(ANPMatrix*, const float[9]); - - void (*setIdentity)(ANPMatrix*); - void (*preTranslate)(ANPMatrix*, float tx, float ty); - void (*postTranslate)(ANPMatrix*, float tx, float ty); - void (*preScale)(ANPMatrix*, float sx, float sy); - void (*postScale)(ANPMatrix*, float sx, float sy); - void (*preSkew)(ANPMatrix*, float kx, float ky); - void (*postSkew)(ANPMatrix*, float kx, float ky); - void (*preRotate)(ANPMatrix*, float degrees); - void (*postRotate)(ANPMatrix*, float degrees); - void (*preConcat)(ANPMatrix*, const ANPMatrix*); - void (*postConcat)(ANPMatrix*, const ANPMatrix*); - - /** Return true if src is invertible, and if so, return its inverse in dst. - If src is not invertible, return false and ignore dst. - */ - bool (*invert)(ANPMatrix* dst, const ANPMatrix* src); - - /** Transform the x,y pairs in src[] by this matrix, and store the results - in dst[]. The count parameter is treated as the number of pairs in the - array. It is legal for src and dst to point to the same memory, but - illegal for the two arrays to partially overlap. - */ - void (*mapPoints)(ANPMatrix*, float dst[], const float src[], - int32_t count); -}; - -struct ANPPathInterfaceV0 : ANPInterface { - /** Return a new path */ - ANPPath* (*newPath)(); - - /** Delete a path previously allocated by ANPPath() */ - void (*deletePath)(ANPPath*); - - /** Make a deep copy of the src path, into the dst path (already allocated - by the caller). - */ - void (*copy)(ANPPath* dst, const ANPPath* src); - - /** Returns true if the two paths are the same (i.e. have the same points) - */ - bool (*equal)(const ANPPath* path0, const ANPPath* path1); - - /** Remove any previous points, initializing the path back to empty. */ - void (*reset)(ANPPath*); - - /** Return true if the path is empty (has no lines, quads or cubics). */ - bool (*isEmpty)(const ANPPath*); - - /** Return the path's bounds in bounds. */ - void (*getBounds)(const ANPPath*, ANPRectF* bounds); - - void (*moveTo)(ANPPath*, float x, float y); - void (*lineTo)(ANPPath*, float x, float y); - void (*quadTo)(ANPPath*, float x0, float y0, float x1, float y1); - void (*cubicTo)(ANPPath*, float x0, float y0, float x1, float y1, - float x2, float y2); - void (*close)(ANPPath*); - - /** Offset the src path by [dx, dy]. If dst is null, apply the - change directly to the src path. If dst is not null, write the - changed path into dst, and leave the src path unchanged. In that case - dst must have been previously allocated by the caller. - */ - void (*offset)(ANPPath* src, float dx, float dy, ANPPath* dst); - - /** Transform the path by the matrix. If dst is null, apply the - change directly to the src path. If dst is not null, write the - changed path into dst, and leave the src path unchanged. In that case - dst must have been previously allocated by the caller. - */ - void (*transform)(ANPPath* src, const ANPMatrix*, ANPPath* dst); -}; - -/** ANPColor is always defined to have the same packing on all platforms, and - it is always unpremultiplied. - - This is in contrast to 32bit format(s) in bitmaps, which are premultiplied, - and their packing may vary depending on the platform, hence the need for - ANPBitmapInterface::getPixelPacking() - */ -typedef uint32_t ANPColor; -#define ANPColor_ASHIFT 24 -#define ANPColor_RSHIFT 16 -#define ANPColor_GSHIFT 8 -#define ANPColor_BSHIFT 0 -#define ANP_MAKE_COLOR(a, r, g, b) \ - (((a) << ANPColor_ASHIFT) | \ - ((r) << ANPColor_RSHIFT) | \ - ((g) << ANPColor_GSHIFT) | \ - ((b) << ANPColor_BSHIFT)) - -enum ANPPaintFlag { - kAntiAlias_ANPPaintFlag = 1 << 0, - kFilterBitmap_ANPPaintFlag = 1 << 1, - kDither_ANPPaintFlag = 1 << 2, - kUnderlineText_ANPPaintFlag = 1 << 3, - kStrikeThruText_ANPPaintFlag = 1 << 4, - kFakeBoldText_ANPPaintFlag = 1 << 5, -}; -typedef uint32_t ANPPaintFlags; - -enum ANPPaintStyles { - kFill_ANPPaintStyle = 0, - kStroke_ANPPaintStyle = 1, - kFillAndStroke_ANPPaintStyle = 2 -}; -typedef int32_t ANPPaintStyle; - -enum ANPPaintCaps { - kButt_ANPPaintCap = 0, - kRound_ANPPaintCap = 1, - kSquare_ANPPaintCap = 2 -}; -typedef int32_t ANPPaintCap; - -enum ANPPaintJoins { - kMiter_ANPPaintJoin = 0, - kRound_ANPPaintJoin = 1, - kBevel_ANPPaintJoin = 2 -}; -typedef int32_t ANPPaintJoin; - -enum ANPPaintAligns { - kLeft_ANPPaintAlign = 0, - kCenter_ANPPaintAlign = 1, - kRight_ANPPaintAlign = 2 -}; -typedef int32_t ANPPaintAlign; - -enum ANPTextEncodings { - kUTF8_ANPTextEncoding = 0, - kUTF16_ANPTextEncoding = 1, -}; -typedef int32_t ANPTextEncoding; - -enum ANPTypefaceStyles { - kBold_ANPTypefaceStyle = 1 << 0, - kItalic_ANPTypefaceStyle = 1 << 1 -}; -typedef uint32_t ANPTypefaceStyle; - -typedef uint32_t ANPFontTableTag; - -struct ANPFontMetrics { - /** The greatest distance above the baseline for any glyph (will be <= 0) */ - float fTop; - /** The recommended distance above the baseline (will be <= 0) */ - float fAscent; - /** The recommended distance below the baseline (will be >= 0) */ - float fDescent; - /** The greatest distance below the baseline for any glyph (will be >= 0) */ - float fBottom; - /** The recommended distance to add between lines of text (will be >= 0) */ - float fLeading; -}; - -struct ANPTypefaceInterfaceV0 : ANPInterface { - /** Return a new reference to the typeface that most closely matches the - requested name and style. Pass null as the name to return - the default font for the requested style. Will never return null - - The 5 generic font names "serif", "sans-serif", "monospace", "cursive", - "fantasy" are recognized, and will be mapped to their logical font - automatically by this call. - - @param name May be NULL. The name of the font family. - @param style The style (normal, bold, italic) of the typeface. - @return reference to the closest-matching typeface. Caller must call - unref() when they are done with the typeface. - */ - ANPTypeface* (*createFromName)(const char name[], ANPTypefaceStyle); - - /** Return a new reference to the typeface that most closely matches the - requested typeface and specified Style. Use this call if you want to - pick a new style from the same family of the existing typeface. - If family is NULL, this selects from the default font's family. - - @param family May be NULL. The name of the existing type face. - @param s The style (normal, bold, italic) of the type face. - @return reference to the closest-matching typeface. Call must call - unref() when they are done. - */ - ANPTypeface* (*createFromTypeface)(const ANPTypeface* family, - ANPTypefaceStyle); - - /** Return the owner count of the typeface. A newly created typeface has an - owner count of 1. When the owner count is reaches 0, the typeface is - deleted. - */ - int32_t (*getRefCount)(const ANPTypeface*); - - /** Increment the owner count on the typeface - */ - void (*ref)(ANPTypeface*); - - /** Decrement the owner count on the typeface. When the count goes to 0, - the typeface is deleted. - */ - void (*unref)(ANPTypeface*); - - /** Return the style bits for the specified typeface - */ - ANPTypefaceStyle (*getStyle)(const ANPTypeface*); - - /** Some fonts are stored in files. If that is true for the fontID, then - this returns the byte length of the full file path. If path is not null, - then the full path is copied into path (allocated by the caller), up to - length bytes. If index is not null, then it is set to the truetype - collection index for this font, or 0 if the font is not in a collection. - - Note: getFontPath does not assume that path is a null-terminated string, - so when it succeeds, it only copies the bytes of the file name and - nothing else (i.e. it copies exactly the number of bytes returned by the - function. If the caller wants to treat path[] as a C string, it must be - sure that it is allocated at least 1 byte larger than the returned size, - and it must copy in the terminating 0. - - If the fontID does not correspond to a file, then the function returns - 0, and the path and index parameters are ignored. - - @param fontID The font whose file name is being queried - @param path Either NULL, or storage for receiving up to length bytes - of the font's file name. Allocated by the caller. - @param length The maximum space allocated in path (by the caller). - Ignored if path is NULL. - @param index Either NULL, or receives the TTC index for this font. - If the font is not a TTC, then will be set to 0. - @return The byte length of th font's file name, or 0 if the font is not - baked by a file. - */ - int32_t (*getFontPath)(const ANPTypeface*, char path[], int32_t length, - int32_t* index); - - /** Return a UTF8 encoded path name for the font directory, or NULL if not - supported. If returned, this string address will be valid for the life - of the plugin instance. It will always end with a '/' character. - */ - const char* (*getFontDirectoryPath)(); -}; - -struct ANPPaintInterfaceV0 : ANPInterface { - /** Return a new paint object, which holds all of the color and style - attributes that affect how things (geometry, text, bitmaps) are drawn - in a ANPCanvas. - - The paint that is returned is not tied to any particular plugin - instance, but it must only be accessed from one thread at a time. - */ - ANPPaint* (*newPaint)(); - void (*deletePaint)(ANPPaint*); - - ANPPaintFlags (*getFlags)(const ANPPaint*); - void (*setFlags)(ANPPaint*, ANPPaintFlags); - - ANPColor (*getColor)(const ANPPaint*); - void (*setColor)(ANPPaint*, ANPColor); - - ANPPaintStyle (*getStyle)(const ANPPaint*); - void (*setStyle)(ANPPaint*, ANPPaintStyle); - - float (*getStrokeWidth)(const ANPPaint*); - float (*getStrokeMiter)(const ANPPaint*); - ANPPaintCap (*getStrokeCap)(const ANPPaint*); - ANPPaintJoin (*getStrokeJoin)(const ANPPaint*); - void (*setStrokeWidth)(ANPPaint*, float); - void (*setStrokeMiter)(ANPPaint*, float); - void (*setStrokeCap)(ANPPaint*, ANPPaintCap); - void (*setStrokeJoin)(ANPPaint*, ANPPaintJoin); - - ANPTextEncoding (*getTextEncoding)(const ANPPaint*); - ANPPaintAlign (*getTextAlign)(const ANPPaint*); - float (*getTextSize)(const ANPPaint*); - float (*getTextScaleX)(const ANPPaint*); - float (*getTextSkewX)(const ANPPaint*); - void (*setTextEncoding)(ANPPaint*, ANPTextEncoding); - void (*setTextAlign)(ANPPaint*, ANPPaintAlign); - void (*setTextSize)(ANPPaint*, float); - void (*setTextScaleX)(ANPPaint*, float); - void (*setTextSkewX)(ANPPaint*, float); - - /** Return the typeface ine paint, or null if there is none. This does not - modify the owner count of the returned typeface. - */ - ANPTypeface* (*getTypeface)(const ANPPaint*); - - /** Set the paint's typeface. If the paint already had a non-null typeface, - its owner count is decremented. If the new typeface is non-null, its - owner count is incremented. - */ - void (*setTypeface)(ANPPaint*, ANPTypeface*); - - /** Return the width of the text. If bounds is not null, return the bounds - of the text in that rectangle. - */ - float (*measureText)(ANPPaint*, const void* text, uint32_t byteLength, - ANPRectF* bounds); - - /** Return the number of unichars specifed by the text. - If widths is not null, returns the array of advance widths for each - unichar. - If bounds is not null, returns the array of bounds for each unichar. - */ - int (*getTextWidths)(ANPPaint*, const void* text, uint32_t byteLength, - float widths[], ANPRectF bounds[]); - - /** Return in metrics the spacing values for text, respecting the paint's - typeface and pointsize, and return the spacing between lines - (descent - ascent + leading). If metrics is NULL, it will be ignored. - */ - float (*getFontMetrics)(ANPPaint*, ANPFontMetrics* metrics); -}; - -struct ANPCanvasInterfaceV0 : ANPInterface { - /** Return a canvas that will draw into the specified bitmap. Note: the - canvas copies the fields of the bitmap, so it need not persist after - this call, but the canvas DOES point to the same pixel memory that the - bitmap did, so the canvas should not be used after that pixel memory - goes out of scope. In the case of creating a canvas to draw into the - pixels provided by kDraw_ANPEventType, those pixels are only while - handling that event. - - The canvas that is returned is not tied to any particular plugin - instance, but it must only be accessed from one thread at a time. - */ - ANPCanvas* (*newCanvas)(const ANPBitmap*); - void (*deleteCanvas)(ANPCanvas*); - - void (*save)(ANPCanvas*); - void (*restore)(ANPCanvas*); - void (*translate)(ANPCanvas*, float tx, float ty); - void (*scale)(ANPCanvas*, float sx, float sy); - void (*rotate)(ANPCanvas*, float degrees); - void (*skew)(ANPCanvas*, float kx, float ky); - void (*concat)(ANPCanvas*, const ANPMatrix*); - void (*clipRect)(ANPCanvas*, const ANPRectF*); - void (*clipPath)(ANPCanvas*, const ANPPath*); - - /** Return the current matrix on the canvas - */ - void (*getTotalMatrix)(ANPCanvas*, ANPMatrix*); - /** Return the current clip bounds in local coordinates, expanding it to - account for antialiasing edge effects if aa is true. If the - current clip is empty, return false and ignore the bounds argument. - */ - bool (*getLocalClipBounds)(ANPCanvas*, ANPRectF* bounds, bool aa); - /** Return the current clip bounds in device coordinates in bounds. If the - current clip is empty, return false and ignore the bounds argument. - */ - bool (*getDeviceClipBounds)(ANPCanvas*, ANPRectI* bounds); - - void (*drawColor)(ANPCanvas*, ANPColor); - void (*drawPaint)(ANPCanvas*, const ANPPaint*); - void (*drawLine)(ANPCanvas*, float x0, float y0, float x1, float y1, - const ANPPaint*); - void (*drawRect)(ANPCanvas*, const ANPRectF*, const ANPPaint*); - void (*drawOval)(ANPCanvas*, const ANPRectF*, const ANPPaint*); - void (*drawPath)(ANPCanvas*, const ANPPath*, const ANPPaint*); - void (*drawText)(ANPCanvas*, const void* text, uint32_t byteLength, - float x, float y, const ANPPaint*); - void (*drawPosText)(ANPCanvas*, const void* text, uint32_t byteLength, - const float xy[], const ANPPaint*); - void (*drawBitmap)(ANPCanvas*, const ANPBitmap*, float x, float y, - const ANPPaint*); - void (*drawBitmapRect)(ANPCanvas*, const ANPBitmap*, - const ANPRectI* src, const ANPRectF* dst, - const ANPPaint*); -}; - -struct ANPWindowInterfaceV0 : ANPInterface { - /** Registers a set of rectangles that the plugin would like to keep on - screen. The rectangles are listed in order of priority with the highest - priority rectangle in location rects[0]. The browser will attempt to keep - as many of the rectangles on screen as possible and will scroll them into - view in response to the invocation of this method and other various events. - The count specifies how many rectangles are in the array. If the count is - zero it signals the browser that any existing rectangles should be cleared - and no rectangles will be tracked. - */ - void (*setVisibleRects)(NPP instance, const ANPRectI rects[], int32_t count); - /** Clears any rectangles that are being tracked as a result of a call to - setVisibleRects. This call is equivalent to setVisibleRect(inst, NULL, 0). - */ - void (*clearVisibleRects)(NPP instance); - /** Given a boolean value of true the device will be requested to provide - a keyboard. A value of false will result in a request to hide the - keyboard. Further, the on-screen keyboard will not be displayed if a - physical keyboard is active. - */ - void (*showKeyboard)(NPP instance, bool value); - /** Called when a plugin wishes to enter into full screen mode. The plugin's - Java class (defined in the plugin's apk manifest) will be called - asynchronously to provide a View object to be displayed full screen. - */ - void (*requestFullScreen)(NPP instance); - /** Called when a plugin wishes to exit from full screen mode. As a result, - the plugin's full screen view will be discarded by the view system. - */ - void (*exitFullScreen)(NPP instance); - /** Called when a plugin wishes to be zoomed and centered in the current view. - */ - void (*requestCenterFitZoom)(NPP instance); -}; - -struct ANPWindowInterfaceV1 : ANPWindowInterfaceV0 { - /** Returns a rectangle representing the visible area of the plugin on - screen. The coordinates are relative to the size of the plugin in the - document and therefore will never be negative or exceed the plugin's size. - */ - ANPRectI (*visibleRect)(NPP instance); -}; - -/////////////////////////////////////////////////////////////////////////////// - -enum ANPSampleFormats { - kUnknown_ANPSamleFormat = 0, - kPCM16Bit_ANPSampleFormat = 1, - kPCM8Bit_ANPSampleFormat = 2 -}; -typedef int32_t ANPSampleFormat; - -/** The audio buffer is passed to the callback proc to request more samples. - It is owned by the system, and the callback may read it, but should not - maintain a pointer to it outside of the scope of the callback proc. - */ -struct ANPAudioBuffer { - // RO - repeat what was specified in newTrack() - int32_t channelCount; - // RO - repeat what was specified in newTrack() - ANPSampleFormat format; - /** This buffer is owned by the caller. Inside the callback proc, up to - "size" bytes of sample data should be written into this buffer. The - address is only valid for the scope of a single invocation of the - callback proc. - */ - void* bufferData; - /** On input, specifies the maximum number of bytes that can be written - to "bufferData". On output, specifies the actual number of bytes that - the callback proc wrote into "bufferData". - */ - uint32_t size; -}; - -enum ANPAudioEvents { - /** This event is passed to the callback proc when the audio-track needs - more sample data written to the provided buffer parameter. - */ - kMoreData_ANPAudioEvent = 0, - /** This event is passed to the callback proc if the audio system runs out - of sample data. In this event, no buffer parameter will be specified - (i.e. NULL will be passed to the 3rd parameter). - */ - kUnderRun_ANPAudioEvent = 1 -}; -typedef int32_t ANPAudioEvent; - -/** Called to feed sample data to the track. This will be called in a separate - thread. However, you may call trackStop() from the callback (but you - cannot delete the track). - - For example, when you have written the last chunk of sample data, you can - immediately call trackStop(). This will take effect after the current - buffer has been played. - - The "user" parameter is the same value that was passed to newTrack() - */ -typedef void (*ANPAudioCallbackProc)(ANPAudioEvent event, void* user, - ANPAudioBuffer* buffer); - -struct ANPAudioTrack; // abstract type for audio tracks - -struct ANPAudioTrackInterfaceV0 : ANPInterface { - /** Create a new audio track, or NULL on failure. The track is initially in - the stopped state and therefore ANPAudioCallbackProc will not be called - until the track is started. - */ - ANPAudioTrack* (*newTrack)(uint32_t sampleRate, // sampling rate in Hz - ANPSampleFormat, - int channelCount, // MONO=1, STEREO=2 - ANPAudioCallbackProc, - void* user); - /** Deletes a track that was created using newTrack. The track can be - deleted in any state and it waits for the ANPAudioCallbackProc thread - to exit before returning. - */ - void (*deleteTrack)(ANPAudioTrack*); - - void (*start)(ANPAudioTrack*); - void (*pause)(ANPAudioTrack*); - void (*stop)(ANPAudioTrack*); - /** Returns true if the track is not playing (e.g. pause or stop was called, - or start was never called. - */ - bool (*isStopped)(ANPAudioTrack*); -}; - -struct ANPAudioTrackInterfaceV1 : ANPAudioTrackInterfaceV0 { - /** Returns the track's latency in milliseconds. */ - uint32_t (*trackLatency)(ANPAudioTrack*); -}; - -/////////////////////////////////////////////////////////////////////////////// -// DEFINITION OF VALUES PASSED THROUGH NPP_HandleEvent - -enum ANPEventTypes { - kNull_ANPEventType = 0, - kKey_ANPEventType = 1, - /** Mouse events are triggered by either clicking with the navigational pad - or by tapping the touchscreen (if the kDown_ANPTouchAction is handled by - the plugin then no mouse event is generated). The kKey_ANPEventFlag has - to be set to true in order to receive these events. - */ - kMouse_ANPEventType = 2, - /** Touch events are generated when the user touches on the screen. The - kTouch_ANPEventFlag has to be set to true in order to receive these - events. - */ - kTouch_ANPEventType = 3, - /** Only triggered by a plugin using the kBitmap_ANPDrawingModel. This event - signals that the plugin needs to redraw itself into the provided bitmap. - */ - kDraw_ANPEventType = 4, - kLifecycle_ANPEventType = 5, - - /** This event type is completely defined by the plugin. - When creating an event, the caller must always set the first - two fields, the remaining data is optional. - ANPEvent evt; - evt.inSize = sizeof(ANPEvent); - evt.eventType = kCustom_ANPEventType - // other data slots are optional - evt.other[] = ...; - To post a copy of the event, call - eventInterface->postEvent(myNPPInstance, &evt); - That call makes a copy of the event struct, and post that on the event - queue for the plugin. - */ - kCustom_ANPEventType = 6, - /** MultiTouch events are generated when the user touches on the screen. The - kTouch_ANPEventFlag has to be set to true in order to receive these - events. This type is a replacement for the older kTouch_ANPEventType. - */ - kMultiTouch_ANPEventType = 7, -}; -typedef int32_t ANPEventType; - -enum ANPKeyActions { - kDown_ANPKeyAction = 0, - kUp_ANPKeyAction = 1, -}; -typedef int32_t ANPKeyAction; - -#include "ANPKeyCodes.h" -typedef int32_t ANPKeyCode; - -enum ANPKeyModifiers { - kAlt_ANPKeyModifier = 1 << 0, - kShift_ANPKeyModifier = 1 << 1, -}; -// bit-field containing some number of ANPKeyModifier bits -typedef uint32_t ANPKeyModifier; - -enum ANPMouseActions { - kDown_ANPMouseAction = 0, - kUp_ANPMouseAction = 1, -}; -typedef int32_t ANPMouseAction; - -enum ANPTouchActions { - /** This occurs when the user first touches on the screen. As such, this - action will always occur prior to any of the other touch actions. If - the plugin chooses to not handle this action then no other events - related to that particular touch gesture will be generated. - */ - kDown_ANPTouchAction = 0, - kUp_ANPTouchAction = 1, - kMove_ANPTouchAction = 2, - kCancel_ANPTouchAction = 3, - // The web view will ignore the return value from the following actions - kLongPress_ANPTouchAction = 4, - kDoubleTap_ANPTouchAction = 5, -}; -typedef int32_t ANPTouchAction; - -enum ANPLifecycleActions { - /** The web view containing this plugin has been paused. See documentation - on the android activity lifecycle for more information. - */ - kPause_ANPLifecycleAction = 0, - /** The web view containing this plugin has been resumed. See documentation - on the android activity lifecycle for more information. - */ - kResume_ANPLifecycleAction = 1, - /** The plugin has focus and is now the recipient of input events (e.g. key, - touch, etc.) - */ - kGainFocus_ANPLifecycleAction = 2, - /** The plugin has lost focus and will not receive any input events until it - regains focus. This event is always preceded by a GainFocus action. - */ - kLoseFocus_ANPLifecycleAction = 3, - /** The browser is running low on available memory and is requesting that - the plugin free any unused/inactive resources to prevent a performance - degradation. - */ - kFreeMemory_ANPLifecycleAction = 4, - /** The page has finished loading. This happens when the page's top level - frame reports that it has completed loading. - */ - kOnLoad_ANPLifecycleAction = 5, - /** The browser is honoring the plugin's request to go full screen. Upon - returning from this event the browser will resize the plugin's java - surface to full-screen coordinates. - */ - kEnterFullScreen_ANPLifecycleAction = 6, - /** The browser has exited from full screen mode. Immediately prior to - sending this event the browser has resized the plugin's java surface to - its original coordinates. - */ - kExitFullScreen_ANPLifecycleAction = 7, - /** The plugin is visible to the user on the screen. This event will always - occur after a kOffScreen_ANPLifecycleAction event. - */ - kOnScreen_ANPLifecycleAction = 8, - /** The plugin is no longer visible to the user on the screen. This event - will always occur prior to an kOnScreen_ANPLifecycleAction event. - */ - kOffScreen_ANPLifecycleAction = 9, -}; -typedef uint32_t ANPLifecycleAction; - -struct TouchPoint { - int32_t id; - float x; // relative to your "window" (0...width) - float y; // relative to your "window" (0...height) - float pressure; - float size; // normalized to a value between 0...1 -}; - -/* This is what is passed to NPP_HandleEvent() */ -struct ANPEvent { - uint32_t inSize; // size of this struct in bytes - ANPEventType eventType; - // use based on the value in eventType - union { - struct { - ANPKeyAction action; - ANPKeyCode nativeCode; - int32_t virtualCode; // windows virtual key code - ANPKeyModifier modifiers; - int32_t repeatCount; // 0 for initial down (or up) - int32_t unichar; // 0 if there is no value - } key; - struct { - ANPMouseAction action; - int32_t x; // relative to your "window" (0...width) - int32_t y; // relative to your "window" (0...height) - } mouse; - struct { - ANPTouchAction action; - ANPKeyModifier modifiers; - int32_t x; // relative to your "window" (0...width) - int32_t y; // relative to your "window" (0...height) - } touch; - struct { - ANPLifecycleAction action; - } lifecycle; - struct { - ANPDrawingModel model; - // relative to (0,0) in top-left of your plugin - ANPRectI clip; - // use based on the value in model - union { - ANPBitmap bitmap; - struct { - int32_t width; - int32_t height; - } surface; - } data; - } draw; - struct { - int64_t timestamp; - int32_t id; - ANPTouchAction action; - int32_t pointerCount; - TouchPoint* touchPoint; - } multiTouch; - int32_t other[8]; - } data; -}; - -struct ANPEventInterfaceV0 : ANPInterface { - /** Post a copy of the specified event to the plugin. The event will be - delivered to the plugin in its main thread (the thread that receives - other ANPEvents). If, after posting before delivery, the NPP instance - is torn down, the event will be discarded. - */ - void (*postEvent)(NPP inst, const ANPEvent* event); -}; - - -#endif diff --git a/WebKit/android/smoke/MessageThread.cpp b/WebKit/android/smoke/MessageThread.cpp deleted file mode 100644 index 48f2222..0000000 --- a/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; - LOG_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/WebKit/android/smoke/MessageThread.h b/WebKit/android/smoke/MessageThread.h deleted file mode 100644 index ca0115b..0000000 --- a/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 ANDROID_WEBKIT_MESSAGETHREAD_H -#define ANDROID_WEBKIT_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 // ANDROID_WEBKIT_MESSAGETHREAD_H diff --git a/WebKit/android/smoke/MessageTypes.h b/WebKit/android/smoke/MessageTypes.h deleted file mode 100644 index 7da6cb8..0000000 --- a/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 ANDROID_WEBKIT_MESSAGETYPES_H_ -#define ANDROID_WEBKIT_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 // ANDROID_WEBKIT_MESSAGETYPES_H_ diff --git a/WebKit/android/wds/Command.cpp b/WebKit/android/wds/Command.cpp deleted file mode 100644 index bd8536f..0000000 --- a/WebKit/android/wds/Command.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2008, 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 "wds" -#include "config.h" - -#include "AndroidLog.h" -#include "Command.h" -#include "Connection.h" -#include "DebugServer.h" -#include "Frame.h" -#include "RenderTreeAsText.h" -#include "RenderView.h" -#include "WebViewCore.h" -#include <utils/Log.h> -#include <wtf/text/CString.h> - -#if ENABLE(WDS) - -using namespace WebCore; - -namespace android { - -namespace WDS { - -//------------------------------------------------------------------------------ -// Actual commands -- XXX should be moved somewhere else -//------------------------------------------------------------------------------ -static bool callDumpRenderTree(const Frame* frame, const Connection* conn) { - CString str = externalRepresentation(frame->contentRenderer()).latin1(); - conn->write(str.data(), str.length()); - return true; -} - -static bool callDumpDomTree(const Frame* frame, const Connection* conn) { - WebViewCore::getWebViewCore(frame->view())->dumpDomTree(true); - - FILE* f = fopen(DOM_TREE_LOG_FILE, "r"); - if (!f) { - conn->write("Dom tree written to logcat\n"); - } else { - char buf[512]; - while (true) { - int nread = fread(buf, 1, sizeof(buf), f); - if (nread <= 0) - break; - conn->write(buf, nread); - } - fclose(f); - } - return true; -} - -class WebCoreHandler : public Handler { -public: - virtual void post(TargetThreadFunction func, void* v) const { - callOnMainThread(func, v); - } -}; -static WebCoreHandler s_webcoreHandler; - -//------------------------------------------------------------------------------ -// End command section -//------------------------------------------------------------------------------ - -class InternalCommand : public Command { -public: - InternalCommand(const Command* comm, const Frame* frame, - const Connection* connection) - : Command(*comm) - , m_frame(frame) - , m_connection(connection) {} - virtual ~InternalCommand() { delete m_connection; } - - void doCommand() const { - LOGD("Executing command '%s' (%s)", m_name, m_description); - if (!m_dispatch(m_frame, m_connection)) - // XXX: Have useful failure messages - m_connection->write("EPIC FAIL!\n", 11); - } - -private: - const Frame* m_frame; - const Connection* m_connection; -}; - -static void commandDispatcher(void* v) { - InternalCommand* c = static_cast<InternalCommand*>(v); - c->doCommand(); - delete c; -} - -void Command::dispatch() { - m_handler.post(commandDispatcher, this); -} - -Vector<const Command*>* Command::s_commands; - -void Command::Init() { - // Do not initialize twice. - if (s_commands) - return; - // XXX: Move this somewhere else. - s_commands = new Vector<const Command*>(); - s_commands->append(new Command("DDOM", "Dump Dom Tree", - callDumpDomTree, s_webcoreHandler)); - s_commands->append(new Command("DDRT", "Dump Render Tree", - callDumpRenderTree, s_webcoreHandler)); -} - -Command* Command::Find(const Connection* conn) { - char buf[COMMAND_LENGTH]; - if (conn->read(buf, sizeof(buf)) != COMMAND_LENGTH) - return NULL; - - // Linear search of commands. TODO: binary search when more commands are - // added. - Vector<const Command*>::const_iterator i = s_commands->begin(); - Vector<const Command*>::const_iterator end = s_commands->end(); - while (i != end) { - if (strncmp(buf, (*i)->name(), sizeof(buf)) == 0) - return new InternalCommand(*i, server()->getFrame(0), conn); - i++; - } - return NULL; -} - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/Command.h b/WebKit/android/wds/Command.h deleted file mode 100644 index 90861d4..0000000 --- a/WebKit/android/wds/Command.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2008, 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 WDS_COMMAND_H -#define WDS_COMMAND_H - -#include "wtf/MainThread.h" -#include "wtf/Vector.h" - -namespace WebCore { -class Frame; -} - -using namespace WTF; -using namespace WebCore; - -namespace android { - -// WebCore Debug Server -namespace WDS { - -class Connection; - -// Command identifier length -#define COMMAND_LENGTH 4 - -// The dispatcher function called with a Frame for context and the established -// connection to the client. The connection can be used to read and write to the -// client application. Return true on successful completion of the command, -// return false to indicate failure. -typedef bool (*DispatchFunction)(const Frame*, const Connection*); - -// Note: Although the type is named MainThreadFunction, it may not always be -// the main thread. The type is generic enough to reuse here but named -// something more appropriate. -typedef MainThreadFunction TargetThreadFunction; - -// Helper class to dipatch functions on a particular thread. -class Handler { -public: - virtual ~Handler() {} - virtual void post(TargetThreadFunction, void*) const = 0; -}; - -// Class for containing information about particular commands. -class Command { -public: - Command(const char* name, const char* desc, const DispatchFunction func, - const Handler& handler) - : m_name(name) - , m_description(desc) - , m_dispatch(func) - , m_handler(handler) {} - Command(const Command& comm) - : m_name(comm.m_name) - , m_description(comm.m_description) - , m_dispatch(comm.m_dispatch) - , m_handler(comm.m_handler) {} - virtual ~Command() {} - - // Initialize the debug server commands - static void Init(); - - // Find the command specified by the client request. - static Command* Find(const Connection* conn); - - // Dispatch this command - void dispatch(); - - const char* name() const { return m_name; } - -protected: - const char* m_name; - const char* m_description; - const DispatchFunction m_dispatch; - -private: - const Handler& m_handler; - static Vector<const Command*>* s_commands; -}; - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/Connection.cpp b/WebKit/android/wds/Connection.cpp deleted file mode 100644 index d7e55ac..0000000 --- a/WebKit/android/wds/Connection.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2008, 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 "wds" -#include "config.h" - -#include "DebugServer.h" // used for ENABLE_WDS -#include "Connection.h" -#include <arpa/inet.h> -#include <string.h> -#include <utils/Log.h> - -#if ENABLE(WDS) - -#define MAX_CONNECTION_QUEUE 5 -#define log_errno(x) LOGE("%s: %d", x, strerror(errno)) - -namespace android { - -namespace WDS { - -bool Socket::open() { - m_fd = socket(PF_INET, SOCK_STREAM, 0); - if (m_fd < 0) { - log_errno("Failed to create file descriptor"); - return false; - } - return true; -} - -bool ConnectionServer::connect(short port) { - if (!m_socket.open()) - return false; - int fd = m_socket.fd(); - - // Build our sockaddr_in structure use to listen to incoming connections - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - - // Try to bind to the given port - if (bind(fd, (sockaddr*) &addr, sizeof(addr)) < 0) { - log_errno("Failed to bind to local host"); - return false; - } - - // Try to listen - if (listen(fd, MAX_CONNECTION_QUEUE) < 0) { - log_errno("Failed to listen"); - return false; - } - - return true; -} - -Connection* ConnectionServer::accept() const { - int conn = ::accept(m_socket.fd(), NULL, NULL); - if (conn < 0) { - log_errno("Accept failed"); - return NULL; - } - return new Connection(conn); -} - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/Connection.h b/WebKit/android/wds/Connection.h deleted file mode 100644 index d67179e..0000000 --- a/WebKit/android/wds/Connection.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2008, 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 WDS_CONNECTION_H -#define WDS_CONNECTION_H - -#include <unistd.h> -#include <sys/socket.h> - -namespace android { - -namespace WDS { - -class Socket { -public: - Socket(): m_fd(-1) {} - Socket(int fd): m_fd(fd) {} - ~Socket() { - if (m_fd != -1) { - shutdown(m_fd, SHUT_RDWR); - close(m_fd); - } - } - // Open a new socket using PF_INET and SOCK_STREAM - bool open(); - int fd() const { return m_fd; } -private: - int m_fd; -}; - -class Connection { -public: - Connection(int conn): m_socket(conn) {} - int read(char buf[], size_t length) const { - return recv(m_socket.fd(), buf, length, 0); - } - int write(const char buf[], size_t length) const { - return send(m_socket.fd(), buf, length, 0); - } - int write(const char buf[]) const { - return write(buf, strlen(buf)); - } -private: - Socket m_socket; -}; - -class ConnectionServer { -public: - ConnectionServer() {} - - // Establish a connection to the local host on the given port. - bool connect(short port); - - // Blocks on the established socket until a new connection arrives. - Connection* accept() const; -private: - Socket m_socket; -}; - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/DebugServer.cpp b/WebKit/android/wds/DebugServer.cpp deleted file mode 100644 index f33a65b..0000000 --- a/WebKit/android/wds/DebugServer.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2008, 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 "wds" -#include "config.h" - -#include "Command.h" -#include "Connection.h" -#include "DebugServer.h" -#include "wtf/MainThread.h" -#include "wtf/Threading.h" -#include <arpa/inet.h> -#include <cutils/properties.h> -#include <errno.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <utils/Log.h> - -#if ENABLE(WDS) - -#define DEFAULT_PORT 9999 -#define log_errno(x) LOGE("%s: %d", x, strerror(errno)) - -namespace android { - -namespace WDS { - -static DebugServer* s_server = NULL; - -// Main thread function for createThread -static void* mainThread(void* v) { - DebugServer* server = static_cast<DebugServer*>(v); - server->start(); - delete server; - s_server = NULL; - return NULL; -} - -DebugServer* server() { - if (s_server == NULL) - s_server = new DebugServer(); - return s_server; -} - -DebugServer::DebugServer() { - // Read webcore.wds.enable to determine if the debug server should run - char buf[PROPERTY_VALUE_MAX]; - int ret = property_get("webcore.wds.enable", buf, NULL); - if (ret != -1 && strcmp(buf, "1") == 0) { - LOGD("WDS Enabled"); - m_threadId = createThread(mainThread, this, "WDS"); - } - // Initialize the available commands. - Command::Init(); -} - -void DebugServer::start() { - LOGD("DebugServer thread started"); - - ConnectionServer cs; - if (!cs.connect(DEFAULT_PORT)) { - LOGE("Failed to start the server socket connection"); - return; - } - - while (true ) { - LOGD("Waiting for incoming connections..."); - Connection* conn = cs.accept(); - if (!conn) { - log_errno("Failed to accept new connections"); - return; - } - LOGD("...Connection established"); - - Command* c = Command::Find(conn); - if (!c) { - LOGE("Could not find matching command"); - delete conn; - } else { - // Dispatch the command, it will handle cleaning up the connection - // when finished. - c->dispatch(); - } - } - - LOGD("DebugServer thread finished"); -} - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/DebugServer.h b/WebKit/android/wds/DebugServer.h deleted file mode 100644 index 92edad9..0000000 --- a/WebKit/android/wds/DebugServer.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2008, 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 DEBUGSERVER_H -#define DEBUGSERVER_H - -// Turn on the wds feature in webkit -#define ENABLE_WDS 0 - -#include "wtf/Threading.h" -#include "wtf/Vector.h" - -// Forward declarations. -namespace WebCore { - class Frame; -} - -using namespace WTF; -using namespace WebCore; - -namespace android { - -// WebCore Debug Server -namespace WDS { - -class DebugServer : WTFNoncopyable::Noncopyable { -public: - void start(); - void addFrame(Frame* frame) { - m_frames.append(frame); - } - void removeFrame(Frame* frame) { - size_t i = m_frames.find(frame); - if (i != notFound) - m_frames.remove(i); - } - Frame* getFrame(unsigned idx) { - if (idx < m_frames.size()) - return m_frames.at(idx); - return NULL; - } -private: - DebugServer(); - WTF::Vector<Frame*> m_frames; - ThreadIdentifier m_threadId; - friend DebugServer* server(); -}; - -DebugServer* server(); - -} // end namespace WDS - -} // end namespace android - -#endif diff --git a/WebKit/android/wds/client/AdbConnection.cpp b/WebKit/android/wds/client/AdbConnection.cpp deleted file mode 100644 index 465f9c3..0000000 --- a/WebKit/android/wds/client/AdbConnection.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "wdsclient" - -#include "AdbConnection.h" -#include "ClientUtils.h" -#include "Device.h" -#include <arpa/inet.h> -#include <errno.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <utils/Log.h> - -void AdbConnection::close() { - if (m_fd != -1) { - shutdown(m_fd, SHUT_RDWR); - ::close(m_fd); - m_fd = -1; - } -} - -// Default adb port -#define ADB_PORT 5037 - -bool AdbConnection::connect() { - // Some commands (host:devices for example) close the connection so we call - // connect after the response. - close(); - - m_fd = socket(PF_INET, SOCK_STREAM, 0); - if (m_fd < 0) { - log_errno("Failed to create socket for connecting to adb"); - return false; - } - - // Create the socket address struct - sockaddr_in adb; - createTcpSocket(adb, ADB_PORT); - - // Connect to adb - if (::connect(m_fd, (sockaddr*) &adb, sizeof(adb)) < 0) { - log_errno("Failed to connect to adb"); - return false; - } - - // Connected - return true; -} - -// Adb protocol stuff -#define MAX_COMMAND_LENGTH 1024 -#define PAYLOAD_LENGTH 4 -#define PAYLOAD_FORMAT "%04X" - -bool AdbConnection::sendRequest(const char* fmt, ...) const { - if (m_fd == -1) { - LOGE("Connection is closed"); - return false; - } - - // Build the command (service) - char buf[MAX_COMMAND_LENGTH]; - va_list args; - va_start(args, fmt); - int res = vsnprintf(buf, MAX_COMMAND_LENGTH, fmt, args); - va_end(args); - - LOGV("Sending command: %04X%.*s", res, res, buf); - - // Construct the payload length - char payloadLen[PAYLOAD_LENGTH + 1]; - snprintf(payloadLen, sizeof(payloadLen), PAYLOAD_FORMAT, res); - - // First, send the payload length - if (send(m_fd, payloadLen, PAYLOAD_LENGTH, 0) < 0) { - log_errno("Failure when sending payload"); - return false; - } - - // Send the actual command - if (send(m_fd, buf, res, 0) < 0) { - log_errno("Failure when sending command"); - return false; - } - - // Check for the OKAY from adb - return checkOkayResponse(); -} - -static void printFailureMessage(int fd) { - // Grab the payload length - char lenStr[PAYLOAD_LENGTH + 1]; - int payloadLen = recv(fd, lenStr, sizeof(lenStr) - 1, 0); - LOG_ASSERT(payloadLen == PAYLOAD_LENGTH, "Incorrect payload size"); - lenStr[PAYLOAD_LENGTH] = 0; - - // Parse the hex payload - payloadLen = strtol(lenStr, NULL, 16); - if (payloadLen < 0) - return; - - // Grab the message - char* msg = new char[payloadLen + 1]; // include null-terminator - int res = recv(fd, msg, payloadLen, 0); - if (res < 0) { - log_errno("Failure reading failure message from adb"); - return; - } else if (res != payloadLen) { - LOGE("Incorrect payload length %d - expected %d", res, payloadLen); - return; - } - msg[res] = 0; - - // Tell somebody about it - LOGE("Received failure from adb: %s", msg); - - // Cleanup - delete[] msg; -} - -#define ADB_RESPONSE_LENGTH 4 - -bool AdbConnection::checkOkayResponse() const { - LOG_ASSERT(m_fd != -1, "Connection has been closed!"); - - char buf[ADB_RESPONSE_LENGTH]; - int res = recv(m_fd, buf, sizeof(buf), 0); - if (res < 0) { - log_errno("Failure reading response from adb"); - return false; - } - - // Check for a response other than OKAY/FAIL - if ((res == ADB_RESPONSE_LENGTH) && (strncmp(buf, "OKAY", res) == 0)) { - LOGV("Command OKAY"); - return true; - } else if (strncmp(buf, "FAIL", ADB_RESPONSE_LENGTH) == 0) { - // Something happened, print out the reason for failure - printFailureMessage(m_fd); - return false; - } - LOGE("Incorrect response from adb - '%.*s'", res, buf); - return false; -} - -void AdbConnection::clearDevices() { - for (unsigned i = 0; i < m_devices.size(); i++) - delete m_devices.editItemAt(i); - m_devices.clear(); -} - -const DeviceList& AdbConnection::getDeviceList() { - // Clear the current device list - clearDevices(); - - if (m_fd == -1) { - LOGE("Connection is closed"); - return m_devices; - } - - // Try to send the device list request - if (!sendRequest("host:devices")) { - LOGE("Failed to get device list from adb"); - return m_devices; - } - - // Get the payload length - char lenStr[PAYLOAD_LENGTH + 1]; - int res = recv(m_fd, lenStr, sizeof(lenStr) - 1, 0); - if (res < 0) { - log_errno("Failure to read payload size of device list"); - return m_devices; - } - lenStr[PAYLOAD_LENGTH] = 0; - - // Parse the hex payload - int payloadLen = strtol(lenStr, NULL, 16); - if (payloadLen < 0) - return m_devices; - - // Grab the list of devices. The format is as follows: - // <serialno><tab><state><newline> - char* msg = new char[payloadLen + 1]; - res = recv(m_fd, msg, payloadLen, 0); - if (res < 0) { - log_errno("Failure reading the device list"); - return m_devices; - } else if (res != payloadLen) { - LOGE("Incorrect payload length %d - expected %d", res, payloadLen); - return m_devices; - } - msg[res] = 0; - - char serial[32]; - char state[32]; - int numRead; - char* ptr = msg; - while (sscanf(ptr, "%31s\t%31s\n%n", serial, state, &numRead) > 1) { - Device::DeviceType t = Device::DEVICE; - static const char emulator[] = "emulator-"; - if (strncmp(serial, emulator, sizeof(emulator) - 1) == 0) - t = Device::EMULATOR; - LOGV("Adding device %s (%s)", serial, state); - m_devices.add(new Device(serial, t, this)); - - // Reset for the next line - ptr += numRead; - } - // Cleanup - delete[] msg; - - return m_devices; -} diff --git a/WebKit/android/wds/client/AdbConnection.h b/WebKit/android/wds/client/AdbConnection.h deleted file mode 100644 index 58bad67..0000000 --- a/WebKit/android/wds/client/AdbConnection.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 WDS_ADB_CONNECTION_H -#define WDS_ADB_CONNECTION_H - -#include "DeviceList.h" - -class AdbConnection { -public: - AdbConnection() : m_fd(-1) {} - ~AdbConnection() { clearDevices(); } - void close(); - bool connect(); - bool sendRequest(const char* fmt, ...) const; - const DeviceList& getDeviceList(); - -private: - bool checkOkayResponse() const; - void clearDevices(); - DeviceList m_devices; - int m_fd; -}; - -#endif diff --git a/WebKit/android/wds/client/Android.mk b/WebKit/android/wds/client/Android.mk deleted file mode 100644 index db79dd4..0000000 --- a/WebKit/android/wds/client/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -## -## Copyright 2008, 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. -## - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - AdbConnection.cpp \ - ClientUtils.cpp \ - Device.cpp \ - main.cpp - -LOCAL_STATIC_LIBRARIES := liblog libutils libcutils - -LOCAL_MODULE:= wdsclient - -include $(BUILD_HOST_EXECUTABLE) diff --git a/WebKit/android/wds/client/ClientUtils.cpp b/WebKit/android/wds/client/ClientUtils.cpp deleted file mode 100644 index f8ca889..0000000 --- a/WebKit/android/wds/client/ClientUtils.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "ClientUtils.h" -#include <arpa/inet.h> -#include <string.h> - -void createTcpSocket(sockaddr_in& addr, short port) { - memset(&addr, 0, sizeof(sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); -} diff --git a/WebKit/android/wds/client/ClientUtils.h b/WebKit/android/wds/client/ClientUtils.h deleted file mode 100644 index 5da1624..0000000 --- a/WebKit/android/wds/client/ClientUtils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 WDS_CLIENT_UTILS_H -#define WDS_CLIENT_UTILS_H - -#include <arpa/inet.h> - -/* - * included for sockaddr_in structure, AF_INET definiton and etc. - */ -#ifdef __FreeBSD__ -#include <netinet/in.h> -#include <sys/socket.h> -#endif - -// Callers need to include Log.h and errno.h to use this macro -#define log_errno(str) LOGE("%s: %s", str, strerror(errno)) - -// Fill in the sockaddr_in structure for binding to the localhost on the given -// port -void createTcpSocket(sockaddr_in& addr, short port); - -#endif diff --git a/WebKit/android/wds/client/Device.cpp b/WebKit/android/wds/client/Device.cpp deleted file mode 100644 index 789a89d..0000000 --- a/WebKit/android/wds/client/Device.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 "AdbConnection.h" -#include "Device.h" - -bool Device::sendRequest(const char* req) const { - return m_connection->sendRequest("host-serial:%s:%s", m_name, req); -} diff --git a/WebKit/android/wds/client/Device.h b/WebKit/android/wds/client/Device.h deleted file mode 100644 index 39d4b12..0000000 --- a/WebKit/android/wds/client/Device.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 WDS_DEVICE_H -#define WDS_DEVICE_H - -#include <stdlib.h> - -class AdbConnection; - -class Device { -public: - // Type of device. - // TODO: Add simulator support - enum DeviceType { - NONE = -1, - EMULATOR, - DEVICE - }; - - // Takes ownership of name - Device(char* name, DeviceType type, const AdbConnection* conn) - : m_connection(conn) - , m_name(strdup(name)) - , m_type(type) {} - ~Device() { free(m_name); } - - const char* name() const { return m_name; } - DeviceType type() const { return m_type; } - - // Send a request to this device. - bool sendRequest(const char* req) const; - -private: - const AdbConnection* m_connection; - char* m_name; - DeviceType m_type; -}; - -#endif diff --git a/WebKit/android/wds/client/DeviceList.h b/WebKit/android/wds/client/DeviceList.h deleted file mode 100644 index 45bfb87..0000000 --- a/WebKit/android/wds/client/DeviceList.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 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 WDS_DEVICE_LIST_H -#define WDS_DEVICE_LIST_H - -#include <utils/Vector.h> - -class Device; - -typedef android::Vector<Device*> DeviceList; - -#endif diff --git a/WebKit/android/wds/client/main.cpp b/WebKit/android/wds/client/main.cpp deleted file mode 100644 index 1c7d856..0000000 --- a/WebKit/android/wds/client/main.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2008, 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 "wdsclient" - -#include "AdbConnection.h" -#include "ClientUtils.h" -#include "Device.h" -#include <arpa/inet.h> -#include <errno.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <utils/Log.h> - -#define DEFAULT_WDS_PORT 9999 -#define STR(x) #x -#define XSTR(x) STR(x) -#define PORT_STR XSTR(DEFAULT_WDS_PORT) - -int wds_open() { - // Create the structure for connecting to the forwarded 9999 port - sockaddr_in addr; - createTcpSocket(addr, DEFAULT_WDS_PORT); - - // Create our socket - int fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_errno("Failed to create file descriptor"); - return -1; - } - // Connect to the remote wds server thread - if (connect(fd, (sockaddr*)&addr, sizeof(addr)) < 0) { - log_errno("Failed to connect to remote debug server"); - return -1; - } - return fd; -} - -// Clean up the file descriptor and connections -void wds_close(int fd) { - if (fd != -1) { - shutdown(fd, SHUT_RDWR); - close(fd); - } -} - -int main(int argc, char** argv) { - - Device::DeviceType type = Device::NONE; - - if (argc <= 1) { - LOGE("wdsclient takes at least 1 argument"); - return 1; - } else { - // Parse the options, look for -e or -d to choose a device. - while (true) { - int c = getopt(argc, argv, "ed"); - if (c == -1) - break; - switch (c) { - case 'e': - type = Device::EMULATOR; - break; - case 'd': - type = Device::DEVICE; - break; - default: - break; - } - } - if (optind == argc) { - LOGE("No command specified"); - return 1; - } - } - - // Do the initial connection. - AdbConnection conn; - conn.connect(); - - const DeviceList& devices = conn.getDeviceList(); - // host:devices closes the connection, reconnect - conn.connect(); - - // No device specified and more than one connected, bail - if (type == Device::NONE && devices.size() > 1) { - LOGE("More than one device/emulator, please specify with -e or -d"); - return 1; - } else if (devices.size() == 0) { - LOGE("No devices connected"); - return 1; - } - - // Find the correct device - const Device* device = NULL; - if (type == Device::NONE) - device = devices[0]; // grab the only one - else { - // Search for a matching device type - for (unsigned i = 0; i < devices.size(); i++) { - if (devices[i]->type() == type) { - device = devices[i]; - break; - } - } - } - - if (!device) { - LOGE("No device found!"); - return 1; - } - - // Forward tcp:9999 - if (!device->sendRequest("forward:tcp:" PORT_STR ";tcp:" PORT_STR)) { - LOGE("Failed to send forwarding request"); - return 1; - } - - LOGV("Connecting to localhost port " PORT_STR); - - const char* command = argv[optind]; - int commandLen = strlen(command); -#define WDS_COMMAND_LENGTH 4 - if (commandLen != WDS_COMMAND_LENGTH) { - LOGE("Commands must be 4 characters '%s'", command); - return 1; - } - - // Open the wds connection - int wdsFd = wds_open(); - if (wdsFd == -1) - return 1; - - // Send the command specified - send(wdsFd, command, WDS_COMMAND_LENGTH, 0); // commands are 4 bytes - - // Read and display the response - char response[256]; - int res = 0; - while ((res = recv(wdsFd, response, sizeof(response), 0)) > 0) - printf("%.*s", res, response); - printf("\n\n"); - - // Shutdown - wds_close(wdsFd); - - return 0; -} |