1 /*
2 * Copyright 2007, 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 #define LOG_TAG "WebCore"
27
28 #include "config.h"
29
30 #include "ApplicationCacheStorage.h"
31 #include "ChromeClientAndroid.h"
32 #include "DatabaseTracker.h"
33 #include "Document.h"
34 #include "PlatformString.h"
35 #include "FloatRect.h"
36 #include "Frame.h"
37 #include "FrameLoader.h"
38 #include "FrameView.h"
39 #include "Geolocation.h"
40 #include "HTMLMediaElement.h"
41 #include "HTMLNames.h"
42 #include "Icon.h"
43 #include "LayerAndroid.h"
44 #include "Page.h"
45 #include "PopupMenuAndroid.h"
46 #include "ScriptController.h"
47 #include "SearchPopupMenuAndroid.h"
48 #include "WebCoreFrameBridge.h"
49 #include "WebCoreViewBridge.h"
50 #include "WebViewCore.h"
51 #include "WindowFeatures.h"
52 #include "Settings.h"
53 #include "UserGestureIndicator.h"
54 #include <wtf/text/CString.h>
55
56 namespace android {
57
58 #if ENABLE(DATABASE)
59 static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedingQuota);
60 #endif
61
62 #if USE(ACCELERATED_COMPOSITING)
63
layersSync()64 WebCore::GraphicsLayer* ChromeClientAndroid::layersSync()
65 {
66 if (m_rootGraphicsLayer && m_needsLayerSync && m_webFrame) {
67 if (FrameView* frameView = m_webFrame->page()->mainFrame()->view())
68 frameView->syncCompositingStateIncludingSubframes();
69 }
70 m_needsLayerSync = false;
71 return m_rootGraphicsLayer;
72 }
73
scheduleCompositingLayerSync()74 void ChromeClientAndroid::scheduleCompositingLayerSync()
75 {
76 if (m_needsLayerSync)
77 return;
78 m_needsLayerSync = true;
79 WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view());
80 if (webViewCore)
81 webViewCore->layersDraw();
82 }
83
setNeedsOneShotDrawingSynchronization()84 void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization()
85 {
86 // This should not be needed
87 }
88
attachRootGraphicsLayer(WebCore::Frame *,WebCore::GraphicsLayer * layer)89 void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* layer)
90 {
91 // frame is not used in Android as we should only get root graphics layer for the main frame
92 m_rootGraphicsLayer = layer;
93 if (!layer)
94 return;
95 scheduleCompositingLayerSync();
96 }
97
98 #endif
99
setWebFrame(android::WebFrame * webframe)100 void ChromeClientAndroid::setWebFrame(android::WebFrame* webframe)
101 {
102 Release(m_webFrame);
103 m_webFrame = webframe;
104 Retain(m_webFrame);
105 }
106
chromeDestroyed()107 void ChromeClientAndroid::chromeDestroyed()
108 {
109 Release(m_webFrame);
110 delete this;
111 }
112
setWindowRect(const FloatRect &)113 void ChromeClientAndroid::setWindowRect(const FloatRect&) { notImplemented(); }
114
windowRect()115 FloatRect ChromeClientAndroid::windowRect() {
116 ASSERT(m_webFrame);
117 if (!m_webFrame)
118 return FloatRect();
119 FrameView* frameView = m_webFrame->page()->mainFrame()->view();
120 if (!frameView)
121 return FloatRect();
122 const WebCoreViewBridge* bridge = frameView->platformWidget();
123 const IntRect& rect = bridge->getWindowBounds();
124 FloatRect fRect(rect.x(), rect.y(), rect.width(), rect.height());
125 return fRect;
126 }
127
pageRect()128 FloatRect ChromeClientAndroid::pageRect() { notImplemented(); return FloatRect(); }
129
scaleFactor()130 float ChromeClientAndroid::scaleFactor()
131 {
132 ASSERT(m_webFrame);
133 return m_webFrame->density();
134 }
135
focus()136 void ChromeClientAndroid::focus()
137 {
138 ASSERT(m_webFrame);
139 bool isUserGesture = UserGestureIndicator::processingUserGesture();
140
141 // Ask the application to focus this WebView if the action is intiated by the user
142 if (isUserGesture)
143 m_webFrame->requestFocus();
144 }
unfocus()145 void ChromeClientAndroid::unfocus() { notImplemented(); }
146
canTakeFocus(FocusDirection)147 bool ChromeClientAndroid::canTakeFocus(FocusDirection) { notImplemented(); return false; }
takeFocus(FocusDirection)148 void ChromeClientAndroid::takeFocus(FocusDirection) { notImplemented(); }
149
focusedNodeChanged(Node * node)150 void ChromeClientAndroid::focusedNodeChanged(Node* node)
151 {
152 android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->focusNodeChanged(node);
153 }
154
focusedFrameChanged(Frame *)155 void ChromeClientAndroid::focusedFrameChanged(Frame*) { notImplemented(); }
156
createWindow(Frame * frame,const FrameLoadRequest &,const WindowFeatures & features,const NavigationAction &)157 Page* ChromeClientAndroid::createWindow(Frame* frame, const FrameLoadRequest&,
158 const WindowFeatures& features, const NavigationAction&)
159 {
160 ASSERT(frame);
161 #ifdef ANDROID_MULTIPLE_WINDOWS
162 if (frame->settings() && !(frame->settings()->supportMultipleWindows()))
163 // If the client doesn't support multiple windows, just return the current page
164 return frame->page();
165 #endif
166
167 const WebCoreViewBridge* bridge = frame->view()->platformWidget();
168 bool dialog = features.dialog || !features.resizable
169 || (features.heightSet && features.height < bridge->height()
170 && features.widthSet && features.width < bridge->width())
171 || (!features.menuBarVisible && !features.statusBarVisible
172 && !features.toolBarVisible && !features.locationBarVisible
173 && !features.scrollbarsVisible);
174 // fullscreen definitely means no dialog
175 if (features.fullscreen)
176 dialog = false;
177 WebCore::Frame* newFrame = m_webFrame->createWindow(dialog,
178 ScriptController::processingUserGesture());
179 if (newFrame) {
180 WebCore::Page* page = newFrame->page();
181 page->setGroupName(frame->page()->groupName());
182 return page;
183 }
184 return NULL;
185 }
186
show()187 void ChromeClientAndroid::show() { notImplemented(); }
188
canRunModal()189 bool ChromeClientAndroid::canRunModal() { notImplemented(); return false; }
runModal()190 void ChromeClientAndroid::runModal() { notImplemented(); }
191
setToolbarsVisible(bool)192 void ChromeClientAndroid::setToolbarsVisible(bool) { notImplemented(); }
toolbarsVisible()193 bool ChromeClientAndroid::toolbarsVisible() { notImplemented(); return false; }
194
setStatusbarVisible(bool)195 void ChromeClientAndroid::setStatusbarVisible(bool) { notImplemented(); }
statusbarVisible()196 bool ChromeClientAndroid::statusbarVisible() { notImplemented(); return false; }
197
setScrollbarsVisible(bool)198 void ChromeClientAndroid::setScrollbarsVisible(bool) { notImplemented(); }
scrollbarsVisible()199 bool ChromeClientAndroid::scrollbarsVisible() { notImplemented(); return false; }
200
setMenubarVisible(bool)201 void ChromeClientAndroid::setMenubarVisible(bool) { notImplemented(); }
menubarVisible()202 bool ChromeClientAndroid::menubarVisible() { notImplemented(); return false; }
203
setResizable(bool)204 void ChromeClientAndroid::setResizable(bool) { notImplemented(); }
205
206 #if ENABLE(CONTEXT_MENUS)
showContextMenu()207 void ChromeClientAndroid::showContextMenu() { notImplemented(); }
208 #endif
209
210 // This function is called by the JavaScript bindings to print usually an error to
211 // a message console. Pass the message to the java side so that the client can
212 // handle it as it sees fit.
addMessageToConsole(MessageSource,MessageType,MessageLevel msgLevel,const String & message,unsigned int lineNumber,const String & sourceID)213 void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, MessageLevel msgLevel, const String& message, unsigned int lineNumber, const String& sourceID) {
214 android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel);
215 }
216
formDidBlur(const WebCore::Node * node)217 void ChromeClientAndroid::formDidBlur(const WebCore::Node* node)
218 {
219 android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node);
220 }
221
canRunBeforeUnloadConfirmPanel()222 bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; }
runBeforeUnloadConfirmPanel(const String & message,Frame * frame)223 bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) {
224 String url = frame->document()->documentURI();
225 return android::WebViewCore::getWebViewCore(frame->view())->jsUnload(url, message);
226 }
227
closeWindowSoon()228 void ChromeClientAndroid::closeWindowSoon()
229 {
230 ASSERT(m_webFrame);
231 Page* page = m_webFrame->page();
232 Frame* mainFrame = page->mainFrame();
233 // This will prevent javascript cross-scripting during unload
234 page->setGroupName(String());
235 // Stop loading but do not send the unload event
236 mainFrame->loader()->stopLoading(UnloadEventPolicyNone);
237 // Cancel all pending loaders
238 mainFrame->loader()->stopAllLoaders();
239 // Remove all event listeners so that no javascript can execute as a result
240 // of mouse/keyboard events.
241 mainFrame->document()->removeAllEventListeners();
242 // Close the window.
243 m_webFrame->closeWindow(android::WebViewCore::getWebViewCore(mainFrame->view()));
244 }
245
runJavaScriptAlert(Frame * frame,const String & message)246 void ChromeClientAndroid::runJavaScriptAlert(Frame* frame, const String& message)
247 {
248 String url = frame->document()->documentURI();
249
250 android::WebViewCore::getWebViewCore(frame->view())->jsAlert(url, message);
251 }
252
runJavaScriptConfirm(Frame * frame,const String & message)253 bool ChromeClientAndroid::runJavaScriptConfirm(Frame* frame, const String& message)
254 {
255 String url = frame->document()->documentURI();
256
257 return android::WebViewCore::getWebViewCore(frame->view())->jsConfirm(url, message);
258 }
259
260 /* This function is called for the javascript method Window.prompt(). A dialog should be shown on
261 * the screen with an input put box. First param is the text, the second is the default value for
262 * the input box, third is return param. If the function returns true, the value set in the third parameter
263 * is provided to javascript, else null is returned to the script.
264 */
runJavaScriptPrompt(Frame * frame,const String & message,const String & defaultValue,String & result)265 bool ChromeClientAndroid::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
266 {
267 String url = frame->document()->documentURI();
268 return android::WebViewCore::getWebViewCore(frame->view())->jsPrompt(url, message, defaultValue, result);
269 }
setStatusbarText(const String &)270 void ChromeClientAndroid::setStatusbarText(const String&) { notImplemented(); }
271
272 // This is called by the JavaScript interpreter when a script has been running for a long
273 // time. A dialog should be shown to the user asking them if they would like to cancel the
274 // Javascript. If true is returned, the script is cancelled.
275 // To make a device more responsive, we default to return true to disallow long running script.
276 // This implies that some of scripts will not be completed.
shouldInterruptJavaScript()277 bool ChromeClientAndroid::shouldInterruptJavaScript() {
278 FrameView* frameView = m_webFrame->page()->mainFrame()->view();
279 return android::WebViewCore::getWebViewCore(frameView)->jsInterrupt();
280 }
281
keyboardUIMode()282 KeyboardUIMode ChromeClientAndroid::keyboardUIMode()
283 {
284 return KeyboardAccessDefault;
285 }
286
windowResizerRect() const287 IntRect ChromeClientAndroid::windowResizerRect() const { return IntRect(0, 0, 0, 0); }
288
invalidateWindow(const IntRect &,bool)289 void ChromeClientAndroid::invalidateWindow(const IntRect&, bool)
290 {
291 notImplemented();
292 }
293
invalidateContentsAndWindow(const IntRect & updateRect,bool)294 void ChromeClientAndroid::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/)
295 {
296 notImplemented();
297 }
298
invalidateContentsForSlowScroll(const IntRect & updateRect,bool immediate)299 void ChromeClientAndroid::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
300 {
301 notImplemented();
302 }
303
304 // new to change 38068 (Nov 6, 2008)
scroll(const IntSize & scrollDelta,const IntRect & rectToScroll,const IntRect & clipRect)305 void ChromeClientAndroid::scroll(const IntSize& scrollDelta,
306 const IntRect& rectToScroll, const IntRect& clipRect) {
307 notImplemented();
308 }
309
310 // new to change 38068 (Nov 6, 2008)
screenToWindow(const IntPoint &) const311 IntPoint ChromeClientAndroid::screenToWindow(const IntPoint&) const {
312 notImplemented();
313 return IntPoint();
314 }
315
316 // new to change 38068 (Nov 6, 2008)
windowToScreen(const IntRect &) const317 IntRect ChromeClientAndroid::windowToScreen(const IntRect&) const {
318 notImplemented();
319 return IntRect();
320 }
321
platformPageClient() const322 PlatformPageClient ChromeClientAndroid::platformPageClient() const {
323 Page* page = m_webFrame->page();
324 Frame* mainFrame = page->mainFrame();
325 FrameView* view = mainFrame->view();
326 PlatformWidget viewBridge = view->platformWidget();
327 return viewBridge;
328 }
329
contentsSizeChanged(Frame *,const IntSize &) const330 void ChromeClientAndroid::contentsSizeChanged(Frame*, const IntSize&) const
331 {
332 notImplemented();
333 }
334
scrollRectIntoView(const IntRect &,const ScrollView *) const335 void ChromeClientAndroid::scrollRectIntoView(const IntRect&, const ScrollView*) const
336 {
337 notImplemented();
338 }
339
formStateDidChange(const Node *)340 void ChromeClientAndroid::formStateDidChange(const Node*)
341 {
342 notImplemented();
343 }
344
scrollbarsModeDidChange() const345 void ChromeClientAndroid::scrollbarsModeDidChange() const
346 {
347 notImplemented();
348 }
349
dispatchViewportDataDidChange(const ViewportArguments & input) const350 void ChromeClientAndroid::dispatchViewportDataDidChange(const ViewportArguments& input) const {
351 #ifdef ANDROID_META_SUPPORT
352 const ViewportArguments emptyArgument;
353 if (input == emptyArgument) {
354 // Empty Argument is for a page with no viewport meta tag; so reset everything.
355 m_webFrame->page()->settings()->resetMetadataSettings();
356 }
357 Document* doc = m_webFrame->page()->mainFrame()->document();
358 if (!doc->ownerElement()) {
359 FrameView* view = doc->view();
360 if (view)
361 PlatformBridge::updateViewport(view);
362 }
363 #endif
364 }
365
mouseDidMoveOverElement(const HitTestResult &,unsigned int)366 void ChromeClientAndroid::mouseDidMoveOverElement(const HitTestResult&, unsigned int) {}
setToolTip(const String &,TextDirection)367 void ChromeClientAndroid::setToolTip(const String&, TextDirection) {}
print(Frame *)368 void ChromeClientAndroid::print(Frame*) {}
369
370 /*
371 * This function is called on the main (webcore) thread by SQLTransaction::deliverQuotaIncreaseCallback.
372 * The way that the callback mechanism is designed inside SQLTransaction means that there must be a new quota
373 * (which may be equal to the old quota if the user did not allow more quota) when this function returns. As
374 * we call into the browser thread to ask what to do with the quota, we block here and get woken up when the
375 * browser calls the native WebViewCore::SetDatabaseQuota method with the new quota value.
376 */
377 #if ENABLE(DATABASE)
exceededDatabaseQuota(Frame * frame,const String & name)378 void ChromeClientAndroid::exceededDatabaseQuota(Frame* frame, const String& name)
379 {
380 SecurityOrigin* origin = frame->document()->securityOrigin();
381 DatabaseTracker& tracker = WebCore::DatabaseTracker::tracker();
382
383 m_isNewQuotaSet = false;
384
385 // This origin is being tracked and has exceeded it's quota. Call into
386 // the Java side of things to inform the user.
387 unsigned long long currentQuota = 0;
388 if (tracker.hasEntryForOrigin(origin))
389 currentQuota = tracker.quotaForOrigin(origin);
390
391 unsigned long long estimatedSize = 0;
392
393 // Only update estimatedSize if we are trying to create a a new database, i.e. the usage for the database is 0.
394 if (tracker.usageForDatabase(name, origin) == 0)
395 estimatedSize = tracker.detailsForNameAndOrigin(name, origin).expectedUsage();
396
397 if (android::WebViewCore::getWebViewCore(frame->view())->exceededDatabaseQuota(frame->document()->documentURI(), name, currentQuota, estimatedSize)) {
398 // We've sent notification to the browser so now wait for it to come back.
399 m_quotaThreadLock.lock();
400 while (!m_isNewQuotaSet) {
401 m_quotaThreadCondition.wait(m_quotaThreadLock);
402 }
403 m_quotaThreadLock.unlock();
404 } else {
405 // We failed to send the message to the UI thread to request a new quota,
406 // so just use the current quota as a default.
407 m_newQuota = currentQuota;
408 }
409
410 if (m_newQuota < currentQuota)
411 m_newQuota = currentQuota;
412
413 // If new quota is unavailable, we may be able to resolve the situation by
414 // shrinking the quota of an origin that asked for a lot but is only using a
415 // little. If we find such a site, shrink it's quota and ask Java to try
416 // again.
417 if (m_newQuota == currentQuota && !m_triedToReclaimDBQuota) {
418 m_triedToReclaimDBQuota = true; // we should only try this once per quota overflow.
419 unsigned long long reclaimedQuotaBytes = tryToReclaimDatabaseQuota(origin);
420
421 // If we were able to free up enough space, try asking Java again.
422 // Otherwise, give up and deny the new database. :(
423 if (reclaimedQuotaBytes >= estimatedSize) {
424 exceededDatabaseQuota(frame, name);
425 return;
426 }
427 }
428
429 // Update the DatabaseTracker with the new quota value (if the user declined
430 // new quota, this may equal the old quota)
431 tracker.setQuota(origin, m_newQuota);
432 m_triedToReclaimDBQuota = false;
433 }
434
tryToReclaimDatabaseQuota(SecurityOrigin * originNeedingQuota)435 static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedingQuota) {
436 DatabaseTracker& tracker = WebCore::DatabaseTracker::tracker();
437 Vector<RefPtr<SecurityOrigin> > origins;
438 tracker.origins(origins);
439 unsigned long long reclaimedQuotaBytes = 0;
440 for (unsigned i = 0; i < origins.size(); i++) {
441 SecurityOrigin* originToReclaimFrom = origins[i].get();
442
443 // Don't try to reclaim from the origin that has exceeded its quota.
444 if (originToReclaimFrom->equal(originNeedingQuota))
445 continue;
446
447 unsigned long long originUsage = tracker.usageForOrigin(originToReclaimFrom);
448 unsigned long long originQuota = tracker.quotaForOrigin(originToReclaimFrom);
449 // If the origin has a quota that is more than it's current usage +1MB, shrink it.
450 static const int ONE_MB = 1 * 1024 * 1024;
451 if (originUsage + ONE_MB < originQuota) {
452 unsigned long long newQuota = originUsage + ONE_MB;
453 tracker.setQuota(originToReclaimFrom, newQuota);
454 reclaimedQuotaBytes += originQuota - newQuota;
455 }
456 }
457 return reclaimedQuotaBytes;
458 }
459 #endif
460
461 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
reachedMaxAppCacheSize(int64_t spaceNeeded)462 void ChromeClientAndroid::reachedMaxAppCacheSize(int64_t spaceNeeded)
463 {
464 m_isNewQuotaSet = false;
465 Page* page = m_webFrame->page();
466 Frame* mainFrame = page->mainFrame();
467 FrameView* view = mainFrame->view();
468
469 // If we fail to send the message to the UI thread to request a new quota,
470 // there's nothing to do.
471 if (!android::WebViewCore::getWebViewCore(view)->reachedMaxAppCacheSize(spaceNeeded))
472 return;
473
474 // We've sent notification to the browser so now wait for it to come back.
475 m_quotaThreadLock.lock();
476 while (!m_isNewQuotaSet) {
477 m_quotaThreadCondition.wait(m_quotaThreadLock);
478 }
479 m_quotaThreadLock.unlock();
480 if (m_newQuota > 0) {
481 WebCore::cacheStorage().setMaximumSize(m_newQuota);
482 // Now the app cache will retry the saving the previously failed cache.
483 }
484 }
485 #endif
486
populateVisitedLinks()487 void ChromeClientAndroid::populateVisitedLinks()
488 {
489 Page* page = m_webFrame->page();
490 Frame* mainFrame = page->mainFrame();
491 FrameView* view = mainFrame->view();
492 android::WebViewCore::getWebViewCore(view)->populateVisitedLinks(&page->group());
493 }
494
requestGeolocationPermissionForFrame(Frame * frame,Geolocation * geolocation)495 void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
496 {
497 ASSERT(geolocation);
498 if (!m_geolocationPermissions) {
499 m_geolocationPermissions = new GeolocationPermissions(android::WebViewCore::getWebViewCore(frame->view()),
500 m_webFrame->page()->mainFrame());
501 }
502 m_geolocationPermissions->queryPermissionState(frame);
503 }
504
cancelGeolocationPermissionRequestForFrame(Frame * frame,WebCore::Geolocation *)505 void ChromeClientAndroid::cancelGeolocationPermissionRequestForFrame(Frame* frame, WebCore::Geolocation*)
506 {
507 if (m_geolocationPermissions)
508 m_geolocationPermissions->cancelPermissionStateQuery(frame);
509 }
510
provideGeolocationPermissions(const String & origin,bool allow,bool remember)511 void ChromeClientAndroid::provideGeolocationPermissions(const String &origin, bool allow, bool remember)
512 {
513 ASSERT(m_geolocationPermissions);
514 m_geolocationPermissions->providePermissionState(origin, allow, remember);
515 }
516
storeGeolocationPermissions()517 void ChromeClientAndroid::storeGeolocationPermissions()
518 {
519 GeolocationPermissions::maybeStorePermanentPermissions();
520 }
521
onMainFrameLoadStarted()522 void ChromeClientAndroid::onMainFrameLoadStarted()
523 {
524 if (m_geolocationPermissions.get())
525 m_geolocationPermissions->resetTemporaryPermissionStates();
526 }
527
runOpenPanel(Frame * frame,PassRefPtr<FileChooser> chooser)528 void ChromeClientAndroid::runOpenPanel(Frame* frame,
529 PassRefPtr<FileChooser> chooser)
530 {
531 android::WebViewCore* core = android::WebViewCore::getWebViewCore(
532 frame->view());
533 core->openFileChooser(chooser);
534 }
535
chooseIconForFiles(const Vector<WTF::String> &,FileChooser *)536 void ChromeClientAndroid::chooseIconForFiles(const Vector<WTF::String>&, FileChooser*)
537 {
538 notImplemented();
539 }
540
setCursor(const Cursor &)541 void ChromeClientAndroid::setCursor(const Cursor&)
542 {
543 notImplemented();
544 }
545
wakeUpMainThreadWithNewQuota(long long newQuota)546 void ChromeClientAndroid::wakeUpMainThreadWithNewQuota(long long newQuota) {
547 MutexLocker locker(m_quotaThreadLock);
548 m_newQuota = newQuota < 0 ? 0 : newQuota;
549 m_isNewQuotaSet = true;
550 m_quotaThreadCondition.signal();
551 }
552
553 #if ENABLE(TOUCH_EVENTS)
needTouchEvents(bool needTouchEvents)554 void ChromeClientAndroid::needTouchEvents(bool needTouchEvents)
555 {
556 FrameView* frameView = m_webFrame->page()->mainFrame()->view();
557 android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
558 if (core)
559 core->needTouchEvents(needTouchEvents);
560 }
561 #endif
562
selectItemWritingDirectionIsNatural()563 bool ChromeClientAndroid::selectItemWritingDirectionIsNatural()
564 {
565 return false;
566 }
567
selectItemAlignmentFollowsMenuWritingDirection()568 bool ChromeClientAndroid::selectItemAlignmentFollowsMenuWritingDirection()
569 {
570 return false;
571 }
572
createPopupMenu(PopupMenuClient * client) const573 PassRefPtr<PopupMenu> ChromeClientAndroid::createPopupMenu(PopupMenuClient* client) const
574 {
575 return adoptRef(new PopupMenuAndroid(static_cast<ListPopupMenuClient*>(client)));
576 }
577
createSearchPopupMenu(PopupMenuClient *) const578 PassRefPtr<SearchPopupMenu> ChromeClientAndroid::createSearchPopupMenu(PopupMenuClient*) const
579 {
580 return adoptRef(new SearchPopupMenuAndroid);
581 }
582
reachedApplicationCacheOriginQuota(SecurityOrigin *)583 void ChromeClientAndroid::reachedApplicationCacheOriginQuota(SecurityOrigin*)
584 {
585 notImplemented();
586 }
587
588 #if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
webAppCanBeInstalled()589 void ChromeClientAndroid::webAppCanBeInstalled()
590 {
591 FrameView* frameView = m_webFrame->page()->mainFrame()->view();
592 android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
593 if (core)
594 core->notifyWebAppCanBeInstalled();
595 }
596 #endif
597
598 #if ENABLE(VIDEO)
supportsFullscreenForNode(const Node * node)599 bool ChromeClientAndroid::supportsFullscreenForNode(const Node* node)
600 {
601 return node->hasTagName(HTMLNames::videoTag);
602 }
603
enterFullscreenForNode(Node * node)604 void ChromeClientAndroid::enterFullscreenForNode(Node* node)
605 {
606 if (!node->hasTagName(HTMLNames::videoTag))
607 return;
608
609 HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
610 String url = videoElement->currentSrc();
611 LayerAndroid* layer = videoElement->platformLayer();
612 if (!layer)
613 return;
614
615 FrameView* frameView = m_webFrame->page()->mainFrame()->view();
616 android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
617 m_webFrame->page()->mainFrame()->document()->webkitWillEnterFullScreenForElement(videoElement);
618 if (core)
619 core->enterFullscreenForVideoLayer(layer->uniqueId(), url);
620 }
621
exitFullscreenForNode(Node * node)622 void ChromeClientAndroid::exitFullscreenForNode(Node* node)
623 {
624 }
625 #endif
626
627 #if ENABLE(FULLSCREEN_API)
exitFullScreenForElement(Element * element)628 void ChromeClientAndroid::exitFullScreenForElement(Element* element)
629 {
630 if (!element)
631 return;
632
633 HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(element);
634 videoElement->exitFullscreen();
635 }
636 #endif
637
638 }
639