OSDN Git Service

42656d4f352bade755eefee26f3f9c4ac9f24ffc
[android-x86/external-webkit.git] / WebKit / android / jni / WebViewCore.h
1 /*
2  * Copyright 2006, 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 #ifndef WEBVIEWCORE_H
27 #define WEBVIEWCORE_H
28
29 #include "android_npapi.h"
30 #include "FileChooser.h"
31 #include "CacheBuilder.h"
32 #include "CachedHistory.h"
33 #include "PictureSet.h"
34 #include "PlatformGraphicsContext.h"
35 #include "SkColor.h"
36 #include "SkTDArray.h"
37 #include "SkRegion.h"
38 #include "Timer.h"
39 #include "WebCoreRefObject.h"
40 #include "WebCoreJni.h"
41 #include <jni.h>
42 #include <ui/KeycodeLabels.h>
43 #include <ui/PixelFormat.h>
44
45 namespace WebCore {
46     class AtomicString;
47     class Color;
48     class FrameView;
49     class HTMLAnchorElement;
50     class HTMLSelectElement;
51     class RenderPart;
52     class RenderText;
53     class Node;
54     class PlatformKeyboardEvent;
55     class RenderTextControl;
56     class ScrollView;
57     class TimerBase;
58     class PageGroup;
59 }
60
61 #if USE(ACCELERATED_COMPOSITING)
62 namespace WebCore {
63     class GraphicsLayerAndroid;
64     class LayerAndroid;
65 }
66 #endif
67
68 struct PluginWidgetAndroid;
69 class SkPicture;
70 class SkIRect;
71
72 namespace android {
73
74     class CachedFrame;
75     class CachedNode;
76     class CachedRoot;
77     class ListBoxReply;
78
79     class WebCoreReply : public WebCoreRefObject {
80     public:
81         virtual ~WebCoreReply() {}
82
83         virtual void replyInt(int value) {
84             SkDEBUGF(("WebCoreReply::replyInt(%d) not handled\n", value));
85         }
86
87         virtual void replyIntArray(const int* array, int count) {
88             SkDEBUGF(("WebCoreReply::replyIntArray() not handled\n"));
89         }
90             // add more replyFoo signatures as needed
91     };
92
93     // one instance of WebViewCore per page for calling into Java's WebViewCore
94     class WebViewCore : public WebCoreRefObject {
95     public:
96         /**
97          * Initialize the native WebViewCore with a JNI environment, a Java
98          * WebViewCore object and the main frame.
99          */
100         WebViewCore(JNIEnv* env, jobject javaView, WebCore::Frame* mainframe);
101         ~WebViewCore();
102
103         // helper function
104         static WebViewCore* getWebViewCore(const WebCore::FrameView* view);
105         static WebViewCore* getWebViewCore(const WebCore::ScrollView* view);
106
107         // Followings are called from native WebCore to Java
108
109         /**
110          * Scroll to an absolute position.
111          * @param x The x coordinate.
112          * @param y The y coordinate.
113          * @param animate If it is true, animate to the new scroll position
114          *
115          * This method calls Java to trigger a gradual scroll event.
116          */
117         void scrollTo(int x, int y, bool animate = false);
118
119         /**
120          * Scroll to the point x,y relative to the current position.
121          * @param x The relative x position.
122          * @param y The relative y position.
123          * @param animate If it is true, animate to the new scroll position
124          */
125         void scrollBy(int x, int y, bool animate);
126
127         /**
128          * Record the invalid rectangle
129          */
130         void contentInvalidate(const WebCore::IntRect &rect);
131
132         /**
133          * Satisfy any outstanding invalidates, so that the current state
134          * of the DOM is drawn.
135          */
136         void contentDraw();
137
138 #if USE(ACCELERATED_COMPOSITING)
139         GraphicsLayerAndroid* graphicsRootLayer() const;
140         void immediateRepaint();
141         void setUIRootLayer(const LayerAndroid* layer);
142 #endif
143
144         /** Invalidate the view/screen, NOT the content/DOM, but expressed in
145          *  content/DOM coordinates (i.e. they need to eventually be scaled,
146          *  by webview into view.java coordinates
147          */
148         void viewInvalidate(const WebCore::IntRect& rect);
149
150         /**
151          * Invalidate part of the content that may be offscreen at the moment
152          */
153         void offInvalidate(const WebCore::IntRect &rect);
154
155         /**
156          * Called by webcore when the progress indicator is done
157          * used to rebuild and display any changes in focus
158          */
159         void notifyProgressFinished();
160
161         /**
162          * Notify the view that WebCore did its first layout.
163          */
164         void didFirstLayout();
165
166         /**
167          * Notify the view to update the viewport.
168          */
169         void updateViewport();
170
171         /**
172          * Notify the view to restore the screen width, which in turn restores
173          * the scale. Also restore the scale for the text wrap.
174          */
175         void restoreScale(int scale, int textWrapScale);
176
177         /**
178          * Tell the java side to update the focused textfield
179          * @param pointer   Pointer to the node for the input field.
180          * @param   changeToPassword  If true, we are changing the textfield to
181          *          a password field, and ignore the String
182          * @param text  If changeToPassword is false, this is the new text that
183          *              should go into the textfield.
184          */
185         void updateTextfield(WebCore::Node* pointer,
186                 bool changeToPassword, const WebCore::String& text);
187
188         /**
189          * Tell the java side to update the current selection in the focused
190          * textfield to the WebTextView.  This function finds the currently
191          * focused textinput, and passes its selection to java.
192          * If there is no focus, or it is not a text input, this does nothing.
193          */
194         void updateTextSelection();
195
196         void clearTextEntry();
197         // JavaScript support
198         void jsAlert(const WebCore::String& url, const WebCore::String& text);
199         bool jsConfirm(const WebCore::String& url, const WebCore::String& text);
200         bool jsPrompt(const WebCore::String& url, const WebCore::String& message,
201                 const WebCore::String& defaultValue, WebCore::String& result);
202         bool jsUnload(const WebCore::String& url, const WebCore::String& message);
203         bool jsInterrupt();
204
205         /**
206          * Tell the Java side that the origin has exceeded its database quota.
207          * @param url The URL of the page that caused the quota overflow
208          * @param databaseIdentifier the id of the database that caused the
209          *     quota overflow.
210          * @param currentQuota The current quota for the origin
211          * @param estimatedSize The estimated size of the database
212          */
213         void exceededDatabaseQuota(const WebCore::String& url,
214                                    const WebCore::String& databaseIdentifier,
215                                    const unsigned long long currentQuota,
216                                    const unsigned long long estimatedSize);
217
218         /**
219          * Tell the Java side that the appcache has exceeded its max size.
220          * @param spaceNeeded is the amount of disk space that would be needed
221          * in order for the last appcache operation to succeed.
222          */
223         void reachedMaxAppCacheSize(const unsigned long long spaceNeeded);
224
225         /**
226          * Set up the PageGroup's idea of which links have been visited,
227          * with the browser history.
228          * @param group the object to deliver the links to.
229          */
230         void populateVisitedLinks(WebCore::PageGroup*);
231
232         /**
233          * Instruct the browser to show a Geolocation permission prompt for the
234          * specified origin.
235          * @param origin The origin of the frame requesting Geolocation
236          *     permissions.
237          */
238         void geolocationPermissionsShowPrompt(const WebCore::String& origin);
239         /**
240          * Instruct the browser to hide the Geolocation permission prompt.
241          */
242         void geolocationPermissionsHidePrompt();
243
244         void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel);
245
246         /**
247          * Tell the Java side of the scrollbar mode
248          */
249         void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode);
250
251         //
252         // Followings support calls from Java to native WebCore
253         //
254
255
256         WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node);
257         WebCore::String retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node);
258         WebCore::String requestLabel(WebCore::Frame* , WebCore::Node* );
259
260         // Create a single picture to represent the drawn DOM (used by navcache)
261         void recordPicture(SkPicture* picture);
262
263         // Create a set of pictures to represent the drawn DOM, driven by
264         // the invalidated region and the time required to draw (used to draw)
265         void recordPictureSet(PictureSet* master);
266         void moveFocus(WebCore::Frame* frame, WebCore::Node* node);
267         void moveMouse(WebCore::Frame* frame, int x, int y);
268         void moveMouseIfLatest(int moveGeneration,
269             WebCore::Frame* frame, int x, int y);
270
271         // set the scroll amount that webview.java is currently showing
272         void setScrollOffset(int moveGeneration, int dx, int dy);
273
274         void setGlobalBounds(int x, int y, int h, int v);
275
276         void setSizeScreenWidthAndScale(int width, int height, int screenWidth,
277             float scale, int realScreenWidth, int screenHeight, int anchorX,
278             int anchorY, bool ignoreHeight);
279
280         /**
281          * Handle key events from Java.
282          * @return Whether keyCode was handled by this class.
283          */
284         bool key(const WebCore::PlatformKeyboardEvent& event);
285
286         /**
287          * Handle (trackball) click event from Java
288          */
289         void click(WebCore::Frame* frame, WebCore::Node* node);
290
291         /**
292          * Handle touch event
293          */
294         bool handleTouchEvent(int action, int x, int y, int metaState);
295
296         /**
297          * Handle motionUp event from the UI thread (called touchUp in the
298          * WebCore thread).
299          */
300         void touchUp(int touchGeneration, WebCore::Frame* frame,
301                 WebCore::Node* node, int x, int y);
302
303         /**
304          * Sets the index of the label from a popup
305          */
306         void popupReply(int index);
307         void popupReply(const int* array, int count);
308
309         /**
310          *  Delete text from start to end in the focused textfield.
311          *  If start == end, set the selection, but perform no deletion.
312          *  If there is no focus, silently fail.
313          *  If start and end are out of order, swap them.
314          */
315         void deleteSelection(int start, int end, int textGeneration);
316
317         /**
318          *  Set the selection of the currently focused textfield to (start, end).
319          *  If start and end are out of order, swap them.
320          */
321         void setSelection(int start, int end);
322
323         /**
324          * Modifies the current selection.
325          *
326          * alter - Specifies how to alter the selection.
327          * direction - The direction in which to alter the selection.
328          * granularity - The granularity of the selection modification.
329          *
330          * returns - The selection as string.
331          */
332         String modifySelection(const String& alter, const String& direction, const String& granularity);
333
334         /**
335          *  In the currently focused textfield, replace the characters from oldStart to oldEnd
336          *  (if oldStart == oldEnd, this will be an insert at that position) with replace,
337          *  and set the selection to (start, end).
338          */
339         void replaceTextfieldText(int oldStart,
340             int oldEnd, const WebCore::String& replace, int start, int end,
341             int textGeneration);
342         void passToJs(int generation,
343             const WebCore::String& , const WebCore::PlatformKeyboardEvent& );
344         /**
345          * Scroll the focused textfield to (x, y) in document space
346          */
347         void scrollFocusedTextInput(float x, int y);
348         /**
349          * Set the FocusController's active and focused states, so that
350          * the caret will draw (true) or not.
351          */
352         void setFocusControllerActive(WebCore::Frame*, bool active);
353
354         void saveDocumentState(WebCore::Frame* frame);
355
356         void addVisitedLink(const UChar*, int);
357
358         // TODO: I don't like this hack but I need to access the java object in
359         // order to send it as a parameter to java
360         AutoJObject getJavaObject();
361
362         // Return the parent WebView Java object associated with this
363         // WebViewCore.
364         jobject getWebViewJavaObject();
365
366         void setBackgroundColor(SkColor c);
367         void updateFrameCache();
368         void updateCacheOnNodeChange();
369         void dumpDomTree(bool);
370         void dumpRenderTree(bool);
371         void dumpNavTree();
372
373         /*  We maintain a list of active plugins. The list is edited by the
374             pluginview itself. The list is used to service invals to the plugin
375             pageflipping bitmap.
376          */
377         void addPlugin(PluginWidgetAndroid*);
378         void removePlugin(PluginWidgetAndroid*);
379         // returns true if the pluginwidgit is in our active list
380         bool isPlugin(PluginWidgetAndroid*) const;
381         void invalPlugin(PluginWidgetAndroid*);
382         void drawPlugins();
383
384         // send the current screen size/zoom to all of the plugins in our list
385         void sendPluginVisibleScreen();
386
387         // send onLoad event to plugins who are descendents of the given frame
388         void notifyPluginsOnFrameLoad(const Frame*);
389
390         // send this event to all of the plugins in our list
391         void sendPluginEvent(const ANPEvent&);
392
393         // lookup the plugin widget struct given an NPP
394         PluginWidgetAndroid* getPluginWidget(NPP npp);
395
396         // return the cursorNode if it is a plugin
397         Node* cursorNodeIsPlugin();
398
399         // Notify the Java side whether it needs to pass down the touch events
400         void needTouchEvents(bool);
401
402         void requestKeyboardWithSelection(const WebCore::Node*, int selStart, int selEnd);
403         // Notify the Java side that webkit is requesting a keyboard
404         void requestKeyboard(bool showKeyboard);
405
406         // Generates a class loader that contains classes from the plugin's apk
407         jclass getPluginClass(const WebCore::String& libName, const char* className);
408
409         // Creates a full screen surface for a plugin
410         void showFullScreenPlugin(jobject webkitPlugin, NPP npp);
411
412         // Instructs the UI thread to discard the plugin's full-screen surface
413         void hideFullScreenPlugin();
414
415         // Adds the plugin's view (aka surface) to the view hierarchy
416         jobject addSurface(jobject view, int x, int y, int width, int height);
417
418         // Updates a Surface coordinates and dimensions for a plugin
419         void updateSurface(jobject childView, int x, int y, int width, int height);
420
421         // Destroys a SurfaceView for a plugin
422         void destroySurface(jobject childView);
423
424         // Returns the context (android.content.Context) of the WebView
425         jobject getContext();
426
427         bool validNodeAndBounds(Frame* , Node* , const IntRect& );
428
429         // Make the rect (left, top, width, height) visible. If it can be fully
430         // fit, center it on the screen. Otherwise make sure the point specified
431         // by (left + xPercentInDoc * width, top + yPercentInDoc * height)
432         // pinned at the screen position (xPercentInView, yPercentInView).
433         void showRect(int left, int top, int width, int height, int contentWidth,
434             int contentHeight, float xPercentInDoc, float xPercentInView,
435             float yPercentInDoc, float yPercentInView);
436
437         // Scale the rect (x, y, width, height) to make it just fit and centered
438         // in the current view.
439         void centerFitRect(int x, int y, int width, int height);
440
441         // return a list of rects matching the touch point (x, y) with the slop
442         Vector<IntRect> getTouchHighlightRects(int x, int y, int slop);
443
444         // other public functions
445     public:
446         // Open a file chooser for selecting a file to upload
447         void openFileChooser(PassRefPtr<WebCore::FileChooser> );
448
449         // reset the picture set to empty
450         void clearContent();
451
452         // flatten the picture set to a picture
453         void copyContentToPicture(SkPicture* );
454
455         // draw the picture set with the specified background color
456         bool drawContent(SkCanvas* , SkColor );
457         bool focusBoundsChanged();
458         bool pictureReady();
459
460         // record the inval area, and the picture size
461         bool recordContent(SkRegion* , SkIPoint* );
462         int textWrapWidth() const { return m_textWrapWidth; }
463         float scale() const { return m_scale; }
464         float textWrapScale() const { return m_screenWidth * m_scale / m_textWrapWidth; }
465         WebCore::Frame* mainFrame() const { return m_mainFrame; }
466         void updateCursorBounds(const CachedRoot* root,
467                 const CachedFrame* cachedFrame, const CachedNode* cachedNode);
468         void updateFrameCacheIfLoading();
469
470         // utility to split slow parts of the picture set
471         void splitContent();
472
473         void notifyWebAppCanBeInstalled();
474
475         // these members are shared with webview.cpp
476         static Mutex gFrameCacheMutex;
477         CachedRoot* m_frameCacheKit; // nav data being built by webcore
478         SkPicture* m_navPictureKit;
479         int m_moveGeneration; // copy of state in WebViewNative triggered by move
480         int m_touchGeneration; // copy of state in WebViewNative triggered by touch
481         int m_lastGeneration; // last action using up to date cache
482         bool m_updatedFrameCache;
483         bool m_findIsUp;
484         bool m_hasCursorBounds;
485         WebCore::IntRect m_cursorBounds;
486         WebCore::IntRect m_cursorHitBounds;
487         void* m_cursorFrame;
488         IntPoint m_cursorLocation;
489         void* m_cursorNode;
490         static Mutex gCursorBoundsMutex;
491         // These two fields go together: we use the mutex to protect access to
492         // m_buttons, so that we, and webview.cpp can look/modify the m_buttons
493         // field safely from our respective threads
494         static Mutex gButtonMutex;
495         WTF::Vector<Container> m_buttons;
496         bool isPaused() const { return m_isPaused; }
497         void setIsPaused(bool isPaused) { m_isPaused = isPaused; }
498         // end of shared members
499
500         // internal functions
501     private:
502         CacheBuilder& cacheBuilder();
503         WebCore::Node* currentFocus();
504         // Compare the new set of buttons to the old one.  All of the new
505         // buttons either replace our old ones or should be added to our list.
506         // Then check the old buttons to see if any are no longer needed.
507         void updateButtonList(WTF::Vector<Container>* buttons);
508         void reset(bool fromConstructor);
509
510         void listBoxRequest(WebCoreReply* reply, const uint16_t** labels,
511                 size_t count, const int enabled[], size_t enabledCount,
512                 bool multiple, const int selected[], size_t selectedCountOrSelection);
513
514         friend class ListBoxReply;
515         struct JavaGlue;
516         struct JavaGlue*       m_javaGlue;
517         WebCore::Frame*        m_mainFrame;
518         WebCoreReply*          m_popupReply;
519         WebCore::Node* m_lastFocused;
520         WebCore::IntRect m_lastFocusedBounds;
521         int m_lastFocusedSelStart;
522         int m_lastFocusedSelEnd;
523         static Mutex m_contentMutex; // protects ui/core thread pictureset access
524         PictureSet m_content; // the set of pictures to draw (accessed by UI too)
525         SkRegion m_addInval; // the accumulated inval region (not yet drawn)
526         SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures
527         // Used in passToJS to avoid updating the UI text field until after the
528         // key event has been processed.
529         bool m_blockTextfieldUpdates;
530         bool m_focusBoundsChanged;
531         bool m_skipContentDraw;
532         // Passed in with key events to know when they were generated.  Store it
533         // with the cache so that we can ignore stale text changes.
534         int m_textGeneration;
535         CachedRoot* m_temp;
536         SkPicture* m_tempPict;
537         int m_maxXScroll;
538         int m_maxYScroll;
539         int m_scrollOffsetX; // webview.java's current scroll in X
540         int m_scrollOffsetY; // webview.java's current scroll in Y
541         WebCore::IntPoint m_mousePos;
542         bool m_frameCacheOutOfDate;
543         bool m_progressDone;
544         int m_lastPassed;
545         int m_lastVelocity;
546         CachedHistory m_history;
547         int m_screenWidth; // width of the visible rect in document coordinates
548         int m_screenHeight;// height of the visible rect in document coordinates
549         int m_textWrapWidth;
550         float m_scale;
551         unsigned m_domtree_version;
552         bool m_check_domtree_version;
553         PageGroup* m_groupForVisitedLinks;
554         bool m_isPaused;
555
556         SkTDArray<PluginWidgetAndroid*> m_plugins;
557         WebCore::Timer<WebViewCore> m_pluginInvalTimer;
558         void pluginInvalTimerFired(WebCore::Timer<WebViewCore>*) {
559             this->drawPlugins();
560         }
561
562         void doMaxScroll(CacheBuilder::Direction dir);
563         SkPicture* rebuildPicture(const SkIRect& inval);
564         void rebuildPictureSet(PictureSet* );
565         void sendNotifyProgressFinished();
566         bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
567         WebCore::HTMLAnchorElement* retrieveAnchorElement(WebCore::Frame* frame, WebCore::Node* node);
568
569 #if ENABLE(TOUCH_EVENTS)
570         bool m_forwardingTouchEvents;
571 #endif
572
573 #if DEBUG_NAV_UI
574         uint32_t m_now;
575 #endif
576
577     private:
578         // called from constructor, to add this to a global list
579         static void addInstance(WebViewCore*);
580         // called from destructor, to remove this from a global list
581         static void removeInstance(WebViewCore*);
582     public:
583         // call only from webkit thread (like add/remove), return true if inst
584         // is still alive
585         static bool isInstance(WebViewCore*);
586
587         // if there exists at least on WebViewCore instance then we return the
588         // application context, otherwise NULL is returned.
589         static jobject getApplicationContext();
590     };
591
592 }   // namespace android
593
594 #endif // WEBVIEWCORE_H