Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2644)

Unified Diff: content/renderer/render_view_impl.cc

Issue 10941015: [Android] Upstream the WebView find-in-page API implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« content/renderer/render_view_impl.h ('K') | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_view_impl.cc
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 224cb16f4c42e163a00131e049cb9bfa46244295..8e415c5ba48068bd93f52c327d20d2c4b8662112 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -612,6 +612,7 @@ RenderViewImpl::RenderViewImpl(
mouse_lock_dispatcher_(NULL),
#if defined(OS_ANDROID)
expected_content_intent_id_(0),
+ synchronous_find_active_match_ordinal_(-1),
#endif
session_storage_namespace_id_(session_storage_namespace_id),
handling_select_range_(false),
@@ -1054,6 +1055,9 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree)
+#if defined(OS_ANDROID)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewMsg_SynchronousFind, OnSynchronousFind)
jam 2012/09/19 16:55:43 nit: put all the android if-def'd handlers togethe
Leandro Graciá Gil 2012/09/19 18:08:59 Done.
+#endif
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
@@ -3894,30 +3898,66 @@ void RenderViewImpl::hasTouchEventHandlers(bool has_handlers) {
Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
}
jam 2012/09/19 16:55:43 the moving of functions around made this file hard
Leandro Graciá Gil 2012/09/19 18:08:59 Done.
-void RenderViewImpl::reportFindInPageMatchCount(int request_id, int count,
+void RenderViewImpl::SendFindReply(int request_id,
+ int match_count,
+ int ordinal,
+ const WebRect& selection_rect,
+ bool final_status_update) {
+#if defined(OS_ANDROID)
+ // Check if this is a synchronous find request.
+ if (synchronous_find_pending_message_.get()) {
+ if (final_status_update) {
+ ViewMsg_SynchronousFind::WriteReplyParams(
+ synchronous_find_pending_message_.get(),
+ match_count,
+ match_count ? synchronous_find_active_match_ordinal_ : 0);
+ Send(synchronous_find_pending_message_.release());
+ }
+ return;
+ }
+#endif
+
+ // Send the search result over to the browser process.
+ Send(new ViewHostMsg_Find_Reply(routing_id_,
+ request_id,
+ match_count,
+ selection_rect,
+ ordinal,
+ final_status_update));
+}
+
+void RenderViewImpl::reportFindInPageMatchCount(int request_id,
+ int count,
bool final_update) {
int active_match_ordinal = -1; // -1 = don't update active match ordinal
if (!count)
active_match_ordinal = 0;
- Send(new ViewHostMsg_Find_Reply(routing_id_,
- request_id,
- count,
- gfx::Rect(),
- active_match_ordinal,
- final_update));
+ // Send the search result over to the browser process.
+ SendFindReply(request_id,
+ count,
+ active_match_ordinal,
+ gfx::Rect(),
+ final_update);
}
void RenderViewImpl::reportFindInPageSelection(int request_id,
int active_match_ordinal,
const WebRect& selection_rect) {
- // Send the search result over to the browser process.
- Send(new ViewHostMsg_Find_Reply(routing_id_,
- request_id,
- -1,
- selection_rect,
- active_match_ordinal,
- false));
+#if defined(OS_ANDROID)
+ // If this was a SynchronousFind request, we need to remember the ordinal
+ // value here for replying when reportFindInPageMatchCount is called.
+ if (synchronous_find_pending_message_.get()) {
+ synchronous_find_active_match_ordinal_ = active_match_ordinal;
+ return;
+ }
+#endif
+
+ SendFindReply(request_id,
+ -1, /* number_of_matches */
+ active_match_ordinal,
+ selection_rect,
+ false /* final_update */);
}
void RenderViewImpl::openFileSystem(
@@ -4376,6 +4416,40 @@ void RenderViewImpl::PlayerGone(WebKit::WebMediaPlayer* player) {
DidPause(player);
}
+void RenderViewImpl::StopFinding(content::StopFindAction action) {
+ WebView* view = webview();
+ if (!view)
+ return;
+
+ WebDocument doc = view->mainFrame()->document();
+ if (doc.isPluginDocument() && GetWebPluginFromPluginDocument()) {
+ GetWebPluginFromPluginDocument()->stopFind();
+ return;
+ }
+
+ bool clear_selection = action == content::STOP_FIND_ACTION_CLEAR_SELECTION;
+ if (clear_selection)
+ view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
+
+ WebFrame* frame = view->mainFrame();
+ while (frame) {
+ frame->stopFinding(clear_selection);
+ frame = frame->traverseNext(false);
+ }
+
+ if (action == content::STOP_FIND_ACTION_ACTIVATE_SELECTION) {
+ WebFrame* focused_frame = view->focusedFrame();
+ if (focused_frame) {
+ WebDocument doc = focused_frame->document();
+ if (!doc.isNull()) {
+ WebNode node = doc.focusedNode();
+ if (!node.isNull())
+ node.simulateClick();
+ }
+ }
+ }
+}
+
void RenderViewImpl::SyncNavigationState() {
if (!webview())
return;
@@ -4440,93 +4514,8 @@ void RenderViewImpl::SyncSelectionIfRequired() {
}
}
-GURL RenderViewImpl::GetAlternateErrorPageURL(const GURL& failed_url,
- ErrorPageType error_type) {
- if (failed_url.SchemeIsSecure()) {
- // If the URL that failed was secure, then the embedding web page was not
- // expecting a network attacker to be able to manipulate its contents. As
- // we fetch alternate error pages over HTTP, we would be allowing a network
- // attacker to manipulate the contents of the response if we tried to use
- // the link doctor here.
- return GURL();
- }
-
- // Grab the base URL from the browser process.
- if (!alternate_error_page_url_.is_valid())
- return GURL();
-
- // Strip query params from the failed URL.
- GURL::Replacements remove_params;
- remove_params.ClearUsername();
- remove_params.ClearPassword();
- remove_params.ClearQuery();
- remove_params.ClearRef();
- const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
- std::string spec_to_send = url_to_send.spec();
- // Notify link doctor of the url truncation by sending of "?" at the end.
- if (failed_url.has_query())
- spec_to_send.append("?");
-
- // Construct the query params to send to link doctor.
- std::string params(alternate_error_page_url_.query());
- params.append("&url=");
- params.append(net::EscapeQueryParamValue(spec_to_send, true));
- params.append("&sourceid=chrome");
- params.append("&error=");
- switch (error_type) {
- case DNS_ERROR:
- params.append("dnserror");
- break;
-
- case HTTP_404:
- params.append("http404");
- break;
-
- case CONNECTION_ERROR:
- params.append("connectionfailure");
- break;
-
- default:
- NOTREACHED() << "unknown ErrorPageType";
- }
-
- // OK, build the final url to return.
- GURL::Replacements link_doctor_params;
- link_doctor_params.SetQueryStr(params);
- GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
- return url;
-}
-
-GURL RenderViewImpl::GetOpenerUrl() const {
- if (opener_id_ == MSG_ROUTING_NONE || opener_suppressed_)
- return GURL();
- else
- return creator_url_;
-}
-
-GURL RenderViewImpl::GetLoadingUrl(WebKit::WebFrame* frame) const {
- WebDataSource* ds = frame->dataSource();
- if (ds->hasUnreachableURL())
- return ds->unreachableURL();
-
- const WebURLRequest& request = ds->request();
- return request.url();
-}
-
-WebUIBindings* RenderViewImpl::GetWebUIBindings() {
- if (!web_ui_bindings_.get()) {
- web_ui_bindings_.reset(new WebUIBindings(
- static_cast<content::RenderView*>(this), routing_id_));
- }
- return web_ui_bindings_.get();
-}
-
-WebKit::WebPlugin* RenderViewImpl::GetWebPluginFromPluginDocument() {
- return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
-}
-
-void RenderViewImpl::OnFind(int request_id, const string16& search_text,
- const WebFindOptions& options) {
+void RenderViewImpl::Find(int request_id, const string16& search_text,
+ const WebFindOptions& options) {
WebFrame* main_frame = webview()->mainFrame();
// Check if the plugin still exists in the document.
@@ -4536,16 +4525,10 @@ void RenderViewImpl::OnFind(int request_id, const string16& search_text,
// Just navigate back/forward.
GetWebPluginFromPluginDocument()->selectFindResult(options.forward);
} else {
- if (GetWebPluginFromPluginDocument()->startFind(
+ if (!GetWebPluginFromPluginDocument()->startFind(
search_text, options.matchCase, request_id)) {
- } else {
// Send "no results".
- Send(new ViewHostMsg_Find_Reply(routing_id_,
- request_id,
- 0,
- gfx::Rect(),
- 0,
- true));
+ SendFindReply(request_id, 0, 0, gfx::Rect(), true);
}
}
return;
@@ -4618,13 +4601,8 @@ void RenderViewImpl::OnFind(int request_id, const string16& search_text,
// Otherwise the scoping effort will send more results.
bool final_status_update = !result;
- // Send the search result over to the browser process.
- Send(new ViewHostMsg_Find_Reply(routing_id_,
- request_id,
- match_count,
- selection_rect,
- ordinal,
- final_status_update));
+ SendFindReply(request_id, match_count, ordinal, selection_rect,
+ final_status_update);
// Scoping effort begins, starting with the mainframe.
search_frame = main_frame;
@@ -4653,41 +4631,133 @@ void RenderViewImpl::OnFind(int request_id, const string16& search_text,
}
}
-void RenderViewImpl::OnStopFinding(content::StopFindAction action) {
- WebView* view = webview();
- if (!view)
- return;
-
- WebDocument doc = view->mainFrame()->document();
- if (doc.isPluginDocument() && GetWebPluginFromPluginDocument()) {
- GetWebPluginFromPluginDocument()->stopFind();
- return;
+GURL RenderViewImpl::GetAlternateErrorPageURL(const GURL& failed_url,
+ ErrorPageType error_type) {
+ if (failed_url.SchemeIsSecure()) {
+ // If the URL that failed was secure, then the embedding web page was not
+ // expecting a network attacker to be able to manipulate its contents. As
+ // we fetch alternate error pages over HTTP, we would be allowing a network
+ // attacker to manipulate the contents of the response if we tried to use
+ // the link doctor here.
+ return GURL();
}
- bool clear_selection = action == content::STOP_FIND_ACTION_CLEAR_SELECTION;
- if (clear_selection)
- view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
+ // Grab the base URL from the browser process.
+ if (!alternate_error_page_url_.is_valid())
+ return GURL();
- WebFrame* frame = view->mainFrame();
- while (frame) {
- frame->stopFinding(clear_selection);
- frame = frame->traverseNext(false);
+ // Strip query params from the failed URL.
+ GURL::Replacements remove_params;
+ remove_params.ClearUsername();
+ remove_params.ClearPassword();
+ remove_params.ClearQuery();
+ remove_params.ClearRef();
+ const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
+ std::string spec_to_send = url_to_send.spec();
+ // Notify link doctor of the url truncation by sending of "?" at the end.
+ if (failed_url.has_query())
+ spec_to_send.append("?");
+
+ // Construct the query params to send to link doctor.
+ std::string params(alternate_error_page_url_.query());
+ params.append("&url=");
+ params.append(net::EscapeQueryParamValue(spec_to_send, true));
+ params.append("&sourceid=chrome");
+ params.append("&error=");
+ switch (error_type) {
+ case DNS_ERROR:
+ params.append("dnserror");
+ break;
+
+ case HTTP_404:
+ params.append("http404");
+ break;
+
+ case CONNECTION_ERROR:
+ params.append("connectionfailure");
+ break;
+
+ default:
+ NOTREACHED() << "unknown ErrorPageType";
}
- if (action == content::STOP_FIND_ACTION_ACTIVATE_SELECTION) {
- WebFrame* focused_frame = view->focusedFrame();
- if (focused_frame) {
- WebDocument doc = focused_frame->document();
- if (!doc.isNull()) {
- WebNode node = doc.focusedNode();
- if (!node.isNull())
- node.simulateClick();
- }
- }
+ // OK, build the final url to return.
+ GURL::Replacements link_doctor_params;
+ link_doctor_params.SetQueryStr(params);
+ GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
+ return url;
+}
+
+GURL RenderViewImpl::GetOpenerUrl() const {
+ if (opener_id_ == MSG_ROUTING_NONE || opener_suppressed_)
+ return GURL();
+ else
+ return creator_url_;
+}
+
+GURL RenderViewImpl::GetLoadingUrl(WebKit::WebFrame* frame) const {
+ WebDataSource* ds = frame->dataSource();
+ if (ds->hasUnreachableURL())
+ return ds->unreachableURL();
+
+ const WebURLRequest& request = ds->request();
+ return request.url();
+}
+
+WebUIBindings* RenderViewImpl::GetWebUIBindings() {
+ if (!web_ui_bindings_.get()) {
+ web_ui_bindings_.reset(new WebUIBindings(
+ static_cast<content::RenderView*>(this), routing_id_));
}
+ return web_ui_bindings_.get();
+}
+
+WebKit::WebPlugin* RenderViewImpl::GetWebPluginFromPluginDocument() {
+ return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
+}
+
+void RenderViewImpl::OnFind(int request_id, const string16& search_text,
+ const WebFindOptions& options) {
+#if defined(OS_ANDROID)
+ // Make sure any asynchronous messages do not disrupt an ongoing synchronous
+ // find request as it might lead to deadlocks. Also, these should be safe to
+ // ignore since they would belong to a previous find request.
+ if (synchronous_find_pending_message_.get())
+ return;
+#endif
+ Find(request_id, search_text, options);
+}
+
+void RenderViewImpl::OnStopFinding(content::StopFindAction action) {
+#if defined(OS_ANDROID)
+ // Make sure any asynchronous messages do not disrupt an ongoing synchronous
+ // find request as it might lead to deadlocks. Also, these should be safe to
+ // ignore since they would belong to a previous find request.
+ if (synchronous_find_pending_message_.get())
+ return;
+#endif
+
+ StopFinding(action);
}
#if defined(OS_ANDROID)
+void RenderViewImpl::OnSynchronousFind(int request_id,
+ const string16& search_string,
+ const WebFindOptions& options,
+ IPC::Message* reply_msg) {
+ // It is impossible for simultaneous blocking finds to occur.
+ DCHECK(!synchronous_find_pending_message_.get());
jam 2012/09/19 16:55:43 nit: make this a CHECK instead?
Leandro Graciá Gil 2012/09/19 18:08:59 Done.
+ synchronous_find_pending_message_.reset(reply_msg);
+
+ // Find next should be asynchronous in order to minimize blocking
+ // the UI thread as much as possible.
+ DCHECK(!options.findNext);
+ StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
+ synchronous_find_active_match_ordinal_ = -1;
+
+ Find(request_id, search_string, options);
+}
+
void RenderViewImpl::OnActivateNearestFindResult(int request_id,
float x, float y) {
if (!webview())
@@ -4705,12 +4775,11 @@ void RenderViewImpl::OnActivateNearestFindResult(int request_id,
return;
}
- Send(new ViewHostMsg_Find_Reply(routing_id_,
- request_id,
- -1 /* number_of_matches */,
- selection_rect,
- ordinal,
- true /* final_update */));
+ SendFindReply(request_id,
+ -1 /* number_of_matches */,
+ ordinal,
+ selection_rect,
+ true /* final_update */);
}
void RenderViewImpl::OnFindMatchRects(int current_version) {
« content/renderer/render_view_impl.h ('K') | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698