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