• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~WebCoreReply()81         virtual ~WebCoreReply() {}
82 
replyInt(int value)83         virtual void replyInt(int value) {
84             SkDEBUGF(("WebCoreReply::replyInt(%d) not handled\n", value));
85         }
86 
replyIntArray(const int * array,int count)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.
174          */
175         void restoreScale(int);
176 
177         /**
178          * Notify the view to restore the scale used to calculate the screen
179          * width for wrapping the text
180          */
181         void restoreScreenWidthScale(int);
182 
183         /**
184          * Tell the java side to update the focused textfield
185          * @param pointer   Pointer to the node for the input field.
186          * @param   changeToPassword  If true, we are changing the textfield to
187          *          a password field, and ignore the String
188          * @param text  If changeToPassword is false, this is the new text that
189          *              should go into the textfield.
190          */
191         void updateTextfield(WebCore::Node* pointer,
192                 bool changeToPassword, const WebCore::String& text);
193 
194         /**
195          * Tell the java side to update the current selection in the focused
196          * textfield to the WebTextView.  This function finds the currently
197          * focused textinput, and passes its selection to java.
198          * If there is no focus, or it is not a text input, this does nothing.
199          */
200         void updateTextSelection();
201 
202         void clearTextEntry();
203         // JavaScript support
204         void jsAlert(const WebCore::String& url, const WebCore::String& text);
205         bool jsConfirm(const WebCore::String& url, const WebCore::String& text);
206         bool jsPrompt(const WebCore::String& url, const WebCore::String& message,
207                 const WebCore::String& defaultValue, WebCore::String& result);
208         bool jsUnload(const WebCore::String& url, const WebCore::String& message);
209         bool jsInterrupt();
210 
211         /**
212          * Tell the Java side that the origin has exceeded its database quota.
213          * @param url The URL of the page that caused the quota overflow
214          * @param databaseIdentifier the id of the database that caused the
215          *     quota overflow.
216          * @param currentQuota The current quota for the origin
217          * @param estimatedSize The estimated size of the database
218          */
219         void exceededDatabaseQuota(const WebCore::String& url,
220                                    const WebCore::String& databaseIdentifier,
221                                    const unsigned long long currentQuota,
222                                    const unsigned long long estimatedSize);
223 
224         /**
225          * Tell the Java side that the appcache has exceeded its max size.
226          * @param spaceNeeded is the amount of disk space that would be needed
227          * in order for the last appcache operation to succeed.
228          */
229         void reachedMaxAppCacheSize(const unsigned long long spaceNeeded);
230 
231         /**
232          * Set up the PageGroup's idea of which links have been visited,
233          * with the browser history.
234          * @param group the object to deliver the links to.
235          */
236         void populateVisitedLinks(WebCore::PageGroup*);
237 
238         /**
239          * Instruct the browser to show a Geolocation permission prompt for the
240          * specified origin.
241          * @param origin The origin of the frame requesting Geolocation
242          *     permissions.
243          */
244         void geolocationPermissionsShowPrompt(const WebCore::String& origin);
245         /**
246          * Instruct the browser to hide the Geolocation permission prompt.
247          */
248         void geolocationPermissionsHidePrompt();
249 
250         void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel);
251 
252         /**
253          * Tell the Java side of the scrollbar mode
254          */
255         void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode);
256 
257         //
258         // Followings support calls from Java to native WebCore
259         //
260 
261 
262         WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node);
263         WebCore::String retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node);
264         WebCore::String requestLabel(WebCore::Frame* , WebCore::Node* );
265 
266         // Create a single picture to represent the drawn DOM (used by navcache)
267         void recordPicture(SkPicture* picture);
268 
269         // Create a set of pictures to represent the drawn DOM, driven by
270         // the invalidated region and the time required to draw (used to draw)
271         void recordPictureSet(PictureSet* master);
272         void moveFocus(WebCore::Frame* frame, WebCore::Node* node);
273         void moveMouse(WebCore::Frame* frame, int x, int y);
274         void moveMouseIfLatest(int moveGeneration,
275             WebCore::Frame* frame, int x, int y);
276 
277         // set the scroll amount that webview.java is currently showing
278         void setScrollOffset(int moveGeneration, int dx, int dy);
279 
280         void setGlobalBounds(int x, int y, int h, int v);
281 
282         void setSizeScreenWidthAndScale(int width, int height, int screenWidth,
283             float scale, int realScreenWidth, int screenHeight, int anchorX,
284             int anchorY, bool ignoreHeight);
285 
286         /**
287          * Handle key events from Java.
288          * @return Whether keyCode was handled by this class.
289          */
290         bool key(const WebCore::PlatformKeyboardEvent& event);
291 
292         /**
293          * Handle (trackball) click event from Java
294          */
295         void click(WebCore::Frame* frame, WebCore::Node* node);
296 
297         /**
298          * Handle touch event
299          */
300         bool handleTouchEvent(int action, int x, int y, int metaState);
301 
302         /**
303          * Handle motionUp event from the UI thread (called touchUp in the
304          * WebCore thread).
305          */
306         void touchUp(int touchGeneration, WebCore::Frame* frame,
307                 WebCore::Node* node, int x, int y);
308 
309         /**
310          * Sets the index of the label from a popup
311          */
312         void popupReply(int index);
313         void popupReply(const int* array, int count);
314 
315         /**
316          *  Delete text from start to end in the focused textfield.
317          *  If start == end, set the selection, but perform no deletion.
318          *  If there is no focus, silently fail.
319          *  If start and end are out of order, swap them.
320          */
321         void deleteSelection(int start, int end, int textGeneration);
322 
323         /**
324          *  Set the selection of the currently focused textfield to (start, end).
325          *  If start and end are out of order, swap them.
326          */
327         void setSelection(int start, int end);
328         /**
329          *  In the currently focused textfield, replace the characters from oldStart to oldEnd
330          *  (if oldStart == oldEnd, this will be an insert at that position) with replace,
331          *  and set the selection to (start, end).
332          */
333         void replaceTextfieldText(int oldStart,
334             int oldEnd, const WebCore::String& replace, int start, int end,
335             int textGeneration);
336         void passToJs(int generation,
337             const WebCore::String& , const WebCore::PlatformKeyboardEvent& );
338         /**
339          * Scroll the focused textfield to (x, y) in document space
340          */
341         void scrollFocusedTextInput(float x, int y);
342         /**
343          * Set the FocusController's active and focused states, so that
344          * the caret will draw (true) or not.
345          */
346         void setFocusControllerActive(WebCore::Frame*, bool active);
347 
348         void saveDocumentState(WebCore::Frame* frame);
349 
350         void addVisitedLink(const UChar*, int);
351 
352         // TODO: I don't like this hack but I need to access the java object in
353         // order to send it as a parameter to java
354         AutoJObject getJavaObject();
355 
356         // Return the parent WebView Java object associated with this
357         // WebViewCore.
358         jobject getWebViewJavaObject();
359 
360         void setBackgroundColor(SkColor c);
361         void updateFrameCache();
362         void updateCacheOnNodeChange();
363         void dumpDomTree(bool);
364         void dumpRenderTree(bool);
365         void dumpNavTree();
366 
367         /*  We maintain a list of active plugins. The list is edited by the
368             pluginview itself. The list is used to service invals to the plugin
369             pageflipping bitmap.
370          */
371         void addPlugin(PluginWidgetAndroid*);
372         void removePlugin(PluginWidgetAndroid*);
373         // returns true if the pluginwidgit is in our active list
374         bool isPlugin(PluginWidgetAndroid*) const;
375         void invalPlugin(PluginWidgetAndroid*);
376         void drawPlugins();
377 
378         // send the current screen size/zoom to all of the plugins in our list
379         void sendPluginVisibleScreen();
380 
381 	// send onLoad event to plugins who are descendents of the given frame
382         void notifyPluginsOnFrameLoad(const Frame*);
383 
384         // send this event to all of the plugins in our list
385         void sendPluginEvent(const ANPEvent&);
386 
387         // lookup the plugin widget struct given an NPP
388         PluginWidgetAndroid* getPluginWidget(NPP npp);
389 
390         // return the cursorNode if it is a plugin
391         Node* cursorNodeIsPlugin();
392 
393         // Notify the Java side whether it needs to pass down the touch events
394         void needTouchEvents(bool);
395 
396         void requestKeyboardWithSelection(const WebCore::Node*, int selStart, int selEnd);
397         // Notify the Java side that webkit is requesting a keyboard
398         void requestKeyboard(bool showKeyboard);
399 
400         // Generates a class loader that contains classes from the plugin's apk
401         jclass getPluginClass(const WebCore::String& libName, const char* className);
402 
403         // Creates a full screen surface for a plugin
404         void showFullScreenPlugin(jobject webkitPlugin, NPP npp);
405 
406         // Instructs the UI thread to discard the plugin's full-screen surface
407         void hideFullScreenPlugin();
408 
409         // Adds the plugin's view (aka surface) to the view hierarchy
410         jobject addSurface(jobject view, int x, int y, int width, int height);
411 
412         // Updates a Surface coordinates and dimensions for a plugin
413         void updateSurface(jobject childView, int x, int y, int width, int height);
414 
415         // Destroys a SurfaceView for a plugin
416         void destroySurface(jobject childView);
417 
418         // Returns the context (android.content.Context) of the WebView
419         jobject getContext();
420 
421         bool validNodeAndBounds(Frame* , Node* , const IntRect& );
422 
423         // Make the rect (left, top, width, height) visible. If it can be fully
424         // fit, center it on the screen. Otherwise make sure the point specified
425         // by (left + xPercentInDoc * width, top + yPercentInDoc * height)
426         // pinned at the screen position (xPercentInView, yPercentInView).
427         void showRect(int left, int top, int width, int height, int contentWidth,
428             int contentHeight, float xPercentInDoc, float xPercentInView,
429             float yPercentInDoc, float yPercentInView);
430 
431         // Scale the rect (x, y, width, height) to make it just fit and centered
432         // in the current view.
433         void centerFitRect(int x, int y, int width, int height);
434 
435         // other public functions
436     public:
437         // Open a file chooser for selecting a file to upload
438         void openFileChooser(PassRefPtr<WebCore::FileChooser> );
439 
440         // reset the picture set to empty
441         void clearContent();
442 
443         // flatten the picture set to a picture
444         void copyContentToPicture(SkPicture* );
445 
446         // draw the picture set with the specified background color
447         bool drawContent(SkCanvas* , SkColor );
448         bool focusBoundsChanged();
449         bool pictureReady();
450 
451         // record the inval area, and the picture size
452         bool recordContent(SkRegion* , SkIPoint* );
screenWidth()453         int screenWidth() const { return m_screenWidth; }
screenHeight()454         int screenHeight() const { return m_screenHeight; }
scale()455         float scale() const { return m_scale; }
screenWidthScale()456         float screenWidthScale() const { return m_screenWidthScale; }
mainFrame()457         WebCore::Frame* mainFrame() const { return m_mainFrame; }
458         void updateCursorBounds(const CachedRoot* root,
459                 const CachedFrame* cachedFrame, const CachedNode* cachedNode);
460         void updateFrameCacheIfLoading();
461 
462         // utility to split slow parts of the picture set
463         void splitContent();
464 
465         // these members are shared with webview.cpp
466         static Mutex gFrameCacheMutex;
467         CachedRoot* m_frameCacheKit; // nav data being built by webcore
468         SkPicture* m_navPictureKit;
469         int m_moveGeneration; // copy of state in WebViewNative triggered by move
470         int m_touchGeneration; // copy of state in WebViewNative triggered by touch
471         int m_lastGeneration; // last action using up to date cache
472         bool m_updatedFrameCache;
473         bool m_findIsUp;
474         bool m_hasCursorBounds;
475         WebCore::IntRect m_cursorBounds;
476         WebCore::IntRect m_cursorHitBounds;
477         void* m_cursorFrame;
478         IntPoint m_cursorLocation;
479         void* m_cursorNode;
480         static Mutex gCursorBoundsMutex;
481         // These two fields go together: we use the mutex to protect access to
482         // m_buttons, so that we, and webview.cpp can look/modify the m_buttons
483         // field safely from our respective threads
484         static Mutex gButtonMutex;
485         WTF::Vector<Container> m_buttons;
isPaused()486         bool isPaused() const { return m_isPaused; }
setIsPaused(bool isPaused)487         void setIsPaused(bool isPaused) { m_isPaused = isPaused; }
488         // end of shared members
489 
490         // internal functions
491     private:
492         CacheBuilder& cacheBuilder();
493         WebCore::Node* currentFocus();
494         // Compare the new set of buttons to the old one.  All of the new
495         // buttons either replace our old ones or should be added to our list.
496         // Then check the old buttons to see if any are no longer needed.
497         void updateButtonList(WTF::Vector<Container>* buttons);
498         void reset(bool fromConstructor);
499 
500         void listBoxRequest(WebCoreReply* reply, const uint16_t** labels,
501                 size_t count, const int enabled[], size_t enabledCount,
502                 bool multiple, const int selected[], size_t selectedCountOrSelection);
503 
504         friend class ListBoxReply;
505         struct JavaGlue;
506         struct JavaGlue*       m_javaGlue;
507         WebCore::Frame*        m_mainFrame;
508         WebCoreReply*          m_popupReply;
509         WebCore::Node* m_lastFocused;
510         WebCore::IntRect m_lastFocusedBounds;
511         int m_lastFocusedSelStart;
512         int m_lastFocusedSelEnd;
513         static Mutex m_contentMutex; // protects ui/core thread pictureset access
514         PictureSet m_content; // the set of pictures to draw (accessed by UI too)
515         SkRegion m_addInval; // the accumulated inval region (not yet drawn)
516         SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures
517         // Used in passToJS to avoid updating the UI text field until after the
518         // key event has been processed.
519         bool m_blockTextfieldUpdates;
520         bool m_focusBoundsChanged;
521         bool m_skipContentDraw;
522         // Passed in with key events to know when they were generated.  Store it
523         // with the cache so that we can ignore stale text changes.
524         int m_textGeneration;
525         CachedRoot* m_temp;
526         SkPicture* m_tempPict;
527         int m_maxXScroll;
528         int m_maxYScroll;
529         int m_scrollOffsetX; // webview.java's current scroll in X
530         int m_scrollOffsetY; // webview.java's current scroll in Y
531         WebCore::IntPoint m_mousePos;
532         bool m_frameCacheOutOfDate;
533         bool m_progressDone;
534         int m_lastPassed;
535         int m_lastVelocity;
536         CachedHistory m_history;
537         int m_screenWidth; // width of the visible rect in document coordinates
538         int m_screenHeight;// height of the visible rect in document coordinates
539         float m_scale;
540         float m_screenWidthScale;
541         unsigned m_domtree_version;
542         bool m_check_domtree_version;
543         PageGroup* m_groupForVisitedLinks;
544         bool m_isPaused;
545 
546         SkTDArray<PluginWidgetAndroid*> m_plugins;
547         WebCore::Timer<WebViewCore> m_pluginInvalTimer;
pluginInvalTimerFired(WebCore::Timer<WebViewCore> *)548         void pluginInvalTimerFired(WebCore::Timer<WebViewCore>*) {
549             this->drawPlugins();
550         }
551 
552         void doMaxScroll(CacheBuilder::Direction dir);
553         SkPicture* rebuildPicture(const SkIRect& inval);
554         void rebuildPictureSet(PictureSet* );
555         void sendNotifyProgressFinished();
556         bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
557         WebCore::HTMLAnchorElement* retrieveAnchorElement(WebCore::Frame* frame, WebCore::Node* node);
558 
559 #if ENABLE(TOUCH_EVENTS)
560         bool m_forwardingTouchEvents;
561         IntPoint m_lastTouchPoint;
562 #endif
563 
564 #if DEBUG_NAV_UI
565         uint32_t m_now;
566 #endif
567 
568     private:
569         // called from constructor, to add this to a global list
570         static void addInstance(WebViewCore*);
571         // called from destructor, to remove this from a global list
572         static void removeInstance(WebViewCore*);
573     public:
574         // call only from webkit thread (like add/remove), return true if inst
575         // is still alive
576         static bool isInstance(WebViewCore*);
577 
578         // if there exists at least on WebViewCore instance then we return the
579         // application context, otherwise NULL is returned.
580         static jobject getApplicationContext();
581 
582         // Check whether a media mimeType is supported in Android media framework.
583         static bool supportsMimeType(const WebCore::String& mimeType);
584     };
585 
586 }   // namespace android
587 
588 #endif // WEBVIEWCORE_H
589