1/*
2 * Copyright 2009, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include <PlatformBridge.h>
28
29#include "CookieClient.h"
30#include "Document.h"
31#include "FileSystemClient.h"
32#include "FrameView.h"
33#include "JNIUtility.h"
34#include "JavaSharedClient.h"
35#include "KeyGeneratorClient.h"
36#include "MemoryUsage.h"
37#include "PluginView.h"
38#include "RenderLayer.h"
39#include "RenderView.h"
40#include "Settings.h"
41#include "WebCookieJar.h"
42#include "WebRequestContext.h"
43#include "WebViewCore.h"
44#include "npruntime.h"
45
46#include <gui/SurfaceComposerClient.h>
47#include <ui/DisplayInfo.h>
48#include <ui/PixelFormat.h>
49#include <wtf/android/AndroidThreading.h>
50#include <wtf/MainThread.h>
51
52#include <algorithm>
53
54using namespace android;
55
56namespace WebCore {
57
58WTF::Vector<String> PlatformBridge::getSupportedKeyStrengthList()
59{
60    KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient();
61    if (!client)
62        return WTF::Vector<String>();
63
64    return client->getSupportedKeyStrengthList();
65}
66
67String PlatformBridge::getSignedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url)
68{
69    KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient();
70    if (!client)
71        return String();
72
73    return client->getSignedPublicKeyAndChallengeString(index, challenge, url);
74}
75
76void PlatformBridge::setCookies(const Document* document, const KURL& url, const String& value)
77{
78    std::string cookieValue(value.utf8().data());
79    GURL cookieGurl(url.string().utf8().data());
80    bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
81    WebCookieJar* cookieJar = WebCookieJar::get(isPrivateBrowsing);
82    if (cookieJar->allowCookies())
83        cookieJar->cookieStore()->SetCookie(cookieGurl, cookieValue);
84}
85
86String PlatformBridge::cookies(const Document* document, const KURL& url)
87{
88    GURL cookieGurl(url.string().utf8().data());
89    bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
90    WebCookieJar* cookieJar = WebCookieJar::get(isPrivateBrowsing);
91    String cookieString;
92    if (cookieJar->allowCookies()) {
93        std::string cookies = cookieJar->cookieStore()->GetCookies(cookieGurl);
94        cookieString = cookies.c_str();
95    }
96    return cookieString;
97}
98
99bool PlatformBridge::cookiesEnabled(const Document* document)
100{
101    bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
102    return WebCookieJar::get(isPrivateBrowsing)->allowCookies();
103}
104
105NPObject* PlatformBridge::pluginScriptableObject(Widget* widget)
106{
107    if (!widget->isPluginView())
108        return 0;
109
110    PluginView* pluginView = static_cast<PluginView*>(widget);
111    return pluginView->getNPObject();
112}
113
114bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView)
115{
116    android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
117    return webViewCore->isPaused();
118}
119
120bool PlatformBridge::popupsAllowed(NPP)
121{
122    return false;
123}
124
125String PlatformBridge::resolveFilePathForContentUri(const String& contentUri)
126{
127    FileSystemClient* client = JavaSharedClient::GetFileSystemClient();
128    return client->resolveFilePathForContentUri(contentUri);
129}
130
131int PlatformBridge::PlatformBridge::screenDepth()
132{
133    android::DisplayInfo info;
134    android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info);
135    return info.pixelFormatInfo.bitsPerPixel;
136}
137
138FloatRect PlatformBridge::screenRect()
139{
140    android::DisplayInfo info;
141    android::SurfaceComposerClient::getDisplayInfo(android::DisplayID(0), &info);
142    return FloatRect(0.0, 0.0, info.w, info.h);
143}
144
145// The visible size on screen in document coordinate
146int PlatformBridge::screenWidthInDocCoord(const WebCore::FrameView* frameView)
147{
148    android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
149    return webViewCore->screenWidth();
150}
151
152int PlatformBridge::screenHeightInDocCoord(const WebCore::FrameView* frameView)
153{
154    android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
155    return webViewCore->screenHeight();
156}
157
158String PlatformBridge::computeDefaultLanguage()
159{
160    String acceptLanguages = WebRequestContext::acceptLanguage();
161    size_t length = acceptLanguages.find(',');
162    if (length == std::string::npos)
163        length = acceptLanguages.length();
164    return acceptLanguages.substring(0, length);
165}
166
167void PlatformBridge::updateViewport(FrameView* frameView)
168{
169    android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
170    webViewCore->updateViewport();
171}
172
173void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, bool changeToPassword, const WTF::String& text)
174{
175    android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
176    webViewCore->updateTextfield(nodePtr, changeToPassword, text);
177}
178
179void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) {
180    FrameView* frameView = scrollView->frameView();
181    if (!frameView) return;
182    // Check to make sure the view is the main FrameView.
183    android::WebViewCore *webViewCore = android::WebViewCore::getWebViewCore(scrollView);
184    if (webViewCore->mainFrame()->view() == scrollView) {
185        x = std::max(0, std::min(frameView->contentsWidth(), x));
186        y = std::max(0, std::min(frameView->contentsHeight(), y));
187        webViewCore->scrollTo(x, y);
188    }
189}
190
191int PlatformBridge::lowMemoryUsageMB()
192{
193    return MemoryUsage::lowMemoryUsageMb();
194}
195
196int PlatformBridge::highMemoryUsageMB()
197{
198    return MemoryUsage::highMemoryUsageMb();
199}
200
201int PlatformBridge::highUsageDeltaMB()
202{
203    return MemoryUsage::highUsageDeltaMb();
204}
205
206int PlatformBridge::memoryUsageMB()
207{
208    return MemoryUsage::memoryUsageMb(false);
209}
210
211int PlatformBridge::actualMemoryUsageMB()
212{
213    return MemoryUsage::memoryUsageMb(true);
214}
215
216bool PlatformBridge::canSatisfyMemoryAllocation(long bytes)
217{
218    JNIEnv* env = JSC::Bindings::getJNIEnv();
219    jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
220    jmethodID method = env->GetStaticMethodID(bridgeClass, "canSatisfyMemoryAllocation", "(J)Z");
221    jboolean canAllocate = env->CallStaticBooleanMethod(bridgeClass, method, static_cast<jlong>(bytes));
222    env->DeleteLocalRef(bridgeClass);
223
224    return canAllocate == JNI_TRUE;
225}
226
227}  // namespace WebCore
228
229
230// This is the implementation of AndroidThreading, which is declared in
231// JavaScriptCore/wtf/android/AndroidThreading.h. It is provided here, rather
232// than in its own source file, to avoid linker problems.
233//
234// By default, when building a shared library, the linker strips from static
235// libraries any compilation units which do not contain any code referenced from
236// that static library. Since
237// AndroidThreading::scheduleDispatchFunctionsOnMainThread is not referenced
238// from libwebcore.a, implementing it in its own compilation unit results in it
239// being stripped. This stripping can be avoided by using the linker option
240// --whole-archive for libwebcore.a, but this adds considerably to the size of
241// libwebcore.so.
242
243namespace WTF {
244
245// Callback in the main thread.
246static void timeoutFired(void*)
247{
248    dispatchFunctionsFromMainThread();
249}
250
251void AndroidThreading::scheduleDispatchFunctionsOnMainThread()
252{
253    JavaSharedClient::EnqueueFunctionPtr(timeoutFired, 0);
254}
255
256}  // namespace WTF
257