| Index: content/browser/find_request_manager.cc
|
| diff --git a/content/browser/find_request_manager.cc b/content/browser/find_request_manager.cc
|
| index ba97753698a77a8e8f00fe80181909fb083d17a5..db706a283a7ccf9267e7669048611d6fac0939c9 100644
|
| --- a/content/browser/find_request_manager.cc
|
| +++ b/content/browser/find_request_manager.cc
|
| @@ -91,11 +91,13 @@ FindRequestManager::FindRequestManager(WebContentsImpl* web_contents)
|
| : WebContentsObserver(web_contents),
|
| contents_(web_contents),
|
| current_session_id_(kInvalidId),
|
| + pending_find_next_reply_(nullptr),
|
| pending_active_match_ordinal_(false),
|
| number_of_matches_(0),
|
| active_frame_(nullptr),
|
| relative_active_match_ordinal_(0),
|
| - active_match_ordinal_(0) {}
|
| + active_match_ordinal_(0),
|
| + last_reported_id_(kInvalidId) {}
|
|
|
| FindRequestManager::~FindRequestManager() {}
|
|
|
| @@ -190,16 +192,21 @@ void FindRequestManager::OnFindReply(RenderFrameHost* rfh,
|
|
|
| // This is the final update for this frame for the current find operation.
|
|
|
| - pending_replies_.erase(rfh);
|
| - if (request_id == current_session_id_ && !pending_replies_.empty()) {
|
| + pending_initial_replies_.erase(rfh);
|
| + if (request_id == current_session_id_ && !pending_initial_replies_.empty()) {
|
| NotifyFindReply(request_id, false /* final_update */);
|
| return;
|
| }
|
| - DCHECK(request_id == current_session_id_ ||
|
| - current_request_.options.findNext);
|
|
|
| // This is the final update for the current find operation.
|
| - FinalUpdate(request_id, rfh);
|
| +
|
| + if (request_id == current_request_.id && request_id != current_session_id_) {
|
| + DCHECK(current_request_.options.findNext);
|
| + DCHECK_EQ(pending_find_next_reply_, rfh);
|
| + pending_find_next_reply_ = nullptr;
|
| + }
|
| +
|
| + FinalUpdateReceived(request_id, rfh);
|
| }
|
|
|
| void FindRequestManager::RemoveFrame(RenderFrameHost* rfh) {
|
| @@ -218,6 +225,7 @@ void FindRequestManager::RemoveFrame(RenderFrameHost* rfh) {
|
| if (active_frame_ == rfh) {
|
| active_frame_ = nullptr;
|
| relative_active_match_ordinal_ = 0;
|
| + selection_rect_ = gfx::Rect();
|
| }
|
| UpdateActiveMatchOrdinal();
|
|
|
| @@ -239,17 +247,28 @@ void FindRequestManager::RemoveFrame(RenderFrameHost* rfh) {
|
| RemoveFindMatchRectsPendingReply(rfh);
|
| #endif
|
|
|
| - if (pending_replies_.count(rfh)) {
|
| + // If no pending find replies are expected for the removed frame, then just
|
| + // report the updated results.
|
| + if (!pending_initial_replies_.count(rfh) && pending_find_next_reply_ != rfh) {
|
| + bool final_update =
|
| + pending_initial_replies_.empty() && !pending_find_next_reply_;
|
| + NotifyFindReply(current_session_id_, final_update);
|
| + return;
|
| + }
|
| +
|
| + if (pending_initial_replies_.count(rfh)) {
|
| // A reply should not be expected from the removed frame.
|
| - pending_replies_.erase(rfh);
|
| - if (pending_replies_.empty()) {
|
| - FinalUpdate(current_request_.id, rfh);
|
| - return;
|
| + pending_initial_replies_.erase(rfh);
|
| + if (pending_initial_replies_.empty()) {
|
| + FinalUpdateReceived(current_session_id_, rfh);
|
| }
|
| }
|
|
|
| - NotifyFindReply(current_session_id_,
|
| - pending_replies_.empty() /* final_update */);
|
| + if (pending_find_next_reply_ == rfh) {
|
| + // A reply should not be expected from the removed frame.
|
| + pending_find_next_reply_ = nullptr;
|
| + FinalUpdateReceived(current_request_.id, rfh);
|
| + }
|
| }
|
|
|
| #if defined(OS_ANDROID)
|
| @@ -264,7 +283,7 @@ void FindRequestManager::ActivateNearestFindResult(float x, float y) {
|
| for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) {
|
| RenderFrameHost* rfh = node->current_frame_host();
|
|
|
| - if (!CheckFrame(rfh))
|
| + if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive())
|
| continue;
|
|
|
| activate_.pending_replies.insert(rfh);
|
| @@ -299,7 +318,7 @@ void FindRequestManager::RequestFindMatchRects(int current_version) {
|
| for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) {
|
| RenderFrameHost* rfh = node->current_frame_host();
|
|
|
| - if (!CheckFrame(rfh))
|
| + if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive())
|
| continue;
|
|
|
| match_rects_.pending_replies.insert(rfh);
|
| @@ -343,7 +362,8 @@ void FindRequestManager::FrameDeleted(RenderFrameHost* rfh) {
|
| void FindRequestManager::Reset(const FindRequest& initial_request) {
|
| current_session_id_ = initial_request.id;
|
| current_request_ = initial_request;
|
| - pending_replies_.clear();
|
| + pending_initial_replies_.clear();
|
| + pending_find_next_reply_ = nullptr;
|
| pending_active_match_ordinal_ = true;
|
| matches_per_frame_.clear();
|
| number_of_matches_ = 0;
|
| @@ -351,6 +371,7 @@ void FindRequestManager::Reset(const FindRequest& initial_request) {
|
| relative_active_match_ordinal_ = 0;
|
| active_match_ordinal_ = 0;
|
| selection_rect_ = gfx::Rect();
|
| + last_reported_id_ = kInvalidId;
|
| #if defined(OS_ANDROID)
|
| activate_ = ActivateNearestFindResultState();
|
| match_rects_.pending_replies.clear();
|
| @@ -400,18 +421,31 @@ void FindRequestManager::AdvanceQueue(int request_id) {
|
|
|
| void FindRequestManager::SendFindIPC(const FindRequest& request,
|
| RenderFrameHost* rfh) {
|
| - pending_replies_.insert(rfh);
|
| + DCHECK(CheckFrame(rfh));
|
| + DCHECK(rfh->IsRenderFrameLive());
|
| +
|
| + if (request.options.findNext)
|
| + pending_find_next_reply_ = rfh;
|
| + else
|
| + pending_initial_replies_.insert(rfh);
|
| +
|
| rfh->Send(new FrameMsg_Find(rfh->GetRoutingID(), request.id,
|
| request.search_text, request.options));
|
| }
|
|
|
| -void FindRequestManager::NotifyFindReply(int request_id,
|
| - bool final_update) const {
|
| +void FindRequestManager::NotifyFindReply(int request_id, bool final_update) {
|
| if (request_id == kInvalidId) {
|
| NOTREACHED();
|
| return;
|
| }
|
|
|
| + // Ensure that replies are not reported with IDs lower than the ID of the
|
| + // latest request we have results from.
|
| + if (request_id < last_reported_id_)
|
| + request_id = last_reported_id_;
|
| + else
|
| + last_reported_id_ = request_id;
|
| +
|
| contents_->NotifyFindReply(request_id, number_of_matches_, selection_rect_,
|
| active_match_ordinal_, final_update);
|
| }
|
| @@ -437,7 +471,7 @@ RenderFrameHost* FindRequestManager::Traverse(RenderFrameHost* from_rfh,
|
| continue;
|
| RenderFrameHost* current_rfh = node->current_frame_host();
|
| if (!matches_only || matches_per_frame_.find(current_rfh)->second ||
|
| - pending_replies_.count(current_rfh)) {
|
| + pending_initial_replies_.count(current_rfh)) {
|
| // Note that if there is still a pending reply expected for this frame,
|
| // then it may have unaccounted matches and will not be skipped via
|
| // |matches_only|.
|
| @@ -466,7 +500,7 @@ void FindRequestManager::AddFrame(RenderFrameHost* rfh) {
|
| }
|
|
|
| bool FindRequestManager::CheckFrame(RenderFrameHost* rfh) const {
|
| - return rfh && rfh->IsRenderFrameLive() && matches_per_frame_.count(rfh);
|
| + return rfh && matches_per_frame_.count(rfh);
|
| }
|
|
|
| void FindRequestManager::UpdateActiveMatchOrdinal() {
|
| @@ -490,11 +524,16 @@ void FindRequestManager::UpdateActiveMatchOrdinal() {
|
| active_match_ordinal_ += relative_active_match_ordinal_;
|
| }
|
|
|
| -void FindRequestManager::FinalUpdate(int request_id, RenderFrameHost* rfh) {
|
| +void FindRequestManager::FinalUpdateReceived(int request_id,
|
| + RenderFrameHost* rfh) {
|
| if (!number_of_matches_ ||
|
| - !pending_active_match_ordinal_ ||
|
| + (active_match_ordinal_ && !pending_active_match_ordinal_) ||
|
| request_id != current_request_.id) {
|
| - NotifyFindReply(request_id, true /* final_update */);
|
| + // All the find results for |request_id| are in and ready to report. Note
|
| + // that |final_update| will be set to false if there are still pending
|
| + // replies expected from the initial find request.
|
| + NotifyFindReply(request_id,
|
| + pending_initial_replies_.empty() /* final_update */);
|
| AdvanceQueue(request_id);
|
| return;
|
| }
|
|
|