15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/browser/find_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/stop_find_action.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebFindOptions.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFindOptions; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android_webview { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindHelper::FindHelper(WebContents* web_contents) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : WebContentsObserver(web_contents), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_(NULL), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_find_started_(false), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_find_started_(false), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_request_id_counter_(0), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_request_id_(0), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_match_count_(-1), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_active_ordinal_(-1), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_(this) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindHelper::~FindHelper() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindHelper::SetListener(Listener* listener) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_ = listener; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FindHelper::FindAllAsync(const base::string16& search_string) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop any ongoing asynchronous request. 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents()->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_find_started_ = false; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_find_started_ = true; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebFindOptions options; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.forward = true; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.matchCase = false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.findNext = false; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartNewRequest(search_string); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents()->Find(current_request_id_, search_string, options); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindHelper::HandleFindReply(int request_id, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int match_count, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int active_ordinal, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool finished) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((!async_find_started_ && !sync_find_started_) || 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_id != current_request_id_) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyResults(active_ordinal, match_count, finished); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindHelper::FindNext(bool forward) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sync_find_started_ && !async_find_started_) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebFindOptions options; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.forward = forward; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.matchCase = false; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.findNext = true; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents()->Find(current_request_id_, last_search_string_, options); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindHelper::ClearMatches() { 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents()->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_find_started_ = false; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_find_started_ = false; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_search_string_.clear(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_match_count_ = -1; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_active_ordinal_ = -1; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FindHelper::StartNewRequest(const base::string16& search_string) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_request_id_ = find_request_id_counter_++; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_search_string_ = search_string; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_match_count_ = -1; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_active_ordinal_ = -1; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindHelper::NotifyResults(int active_ordinal, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int match_count, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool finished) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Match count or ordinal values set to -1 refer to the received replies. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_count == -1) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count = last_match_count_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_match_count_ = match_count; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_ordinal == -1) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_ordinal = last_active_ordinal_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_active_ordinal_ = active_ordinal; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip the update if we don't still have a valid ordinal. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The next update, final or not, should have this information. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!finished && active_ordinal == -1) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safeguard in case of errors to prevent reporting -1 to the API listeners. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_count == -1) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count = 0; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_ordinal == -1) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_ordinal = 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebView.FindListener active match ordinals are 0-based while WebKit sends 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1-based ordinals. Still we can receive 0 ordinal in case of no results. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_ordinal = std::max(active_ordinal - 1, 0); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listener_) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->OnFindResultReceived(active_ordinal, match_count, finished); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace android_webview 134