Index: content/browser/find_request_manager.h |
diff --git a/content/browser/find_request_manager.h b/content/browser/find_request_manager.h |
index 0fa037eb79dc715bddb6a79c8bb0662649afd0fc..b9785944d126a9f27c776114d1c295a1b2755817 100644 |
--- a/content/browser/find_request_manager.h |
+++ b/content/browser/find_request_manager.h |
@@ -5,9 +5,14 @@ |
#ifndef CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ |
#define CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ |
+#include <map> |
+#include <queue> |
#include <set> |
+#include <utility> |
#include <vector> |
+#include "content/common/content_export.h" |
+#include "content/public/browser/web_contents_observer.h" |
#include "content/public/common/stop_find_action.h" |
#include "third_party/WebKit/public/web/WebFindOptions.h" |
#include "ui/gfx/geometry/rect.h" |
@@ -23,13 +28,13 @@ class WebContentsImpl; |
// multiple (potentially out-of-process) frames, handles the aggregation of find |
// results from each frame, and facilitates active match traversal. It is |
// instantiated once per WebContents, and is owned by that WebContents. |
-// |
-// TODO(paulmeyer): FindRequestManager is currently incomplete and does not do |
-// all of these things yet, but will soon. |
-class FindRequestManager { |
+class CONTENT_EXPORT FindRequestManager : public WebContentsObserver { |
public: |
+ // Frames can be uniquely identified by a (process ID, frame ID) pair. |
+ using FrameKey = std::pair<int, int>; |
+ |
explicit FindRequestManager(WebContentsImpl* web_contents); |
- ~FindRequestManager(); |
+ ~FindRequestManager() override; |
// Initiates a find operation for |search_text| with the options specified in |
// |options|. |request_id| uniquely identifies the find request. |
@@ -51,16 +56,27 @@ class FindRequestManager { |
int active_match_ordinal, |
bool final_update); |
+ // Removes a frame from the set of frames being searched. This should be |
+ // called whenever a frame is discovered to no longer exist. |
+ void RemoveFrame(RenderFrameHost* rfh); |
+ void RemoveFrame(const FrameKey& frame_key); |
+ |
#if defined(OS_ANDROID) |
// Selects and zooms to the find result nearest to the point (x,y) defined in |
// find-in-page coordinates. |
void ActivateNearestFindResult(float x, float y); |
+ // Called when a reply is received from a frame in response to the |
+ // GetNearestFindResult IPC. |
+ void GetNearestFindResultReply(RenderFrameHost* rfh, |
+ int nearest_find_result_request_id, |
+ float distance); |
+ |
// Requests the rects of the current find matches from the renderer process. |
void RequestFindMatchRects(int current_version); |
- // Called when a reply is received in response to a request for find match |
- // rects. |
+ // Called when a reply is received from a frame in response to a request for |
+ // find match rects. |
void OnFindMatchRectsReply(RenderFrameHost* rfh, |
int version, |
const std::vector<gfx::RectF>& rects, |
@@ -90,27 +106,134 @@ class FindRequestManager { |
: id(id), search_text(search_text), options(options) {} |
}; |
- // Send a find IPC containing the find request |request| to the RenderFrame |
+ // WebContentsObserver implementation. |
+ void RenderFrameDeleted(RenderFrameHost* rfh) override; |
+ void FrameDeleted(RenderFrameHost* rfh) override; |
+ |
+ // Resets all of the per-session state for a new find-in-page session. |
+ void Reset(const FindRequest& initial_request); |
+ |
+ // Called internally as find requests come up in the queue. |
+ void FindInternal(const FindRequest& request); |
+ |
+ // Called when an informative response (a response with enough information to |
+ // be able to route subsequent find requests) comes in for the find request |
+ // with ID |request_id|. Advances the queue if appropriate. |
+ void AdvanceQueue(int request_id); |
+ |
+ // Sends a find IPC containing the find request |request| to the RenderFrame |
// associated with |rfh|. |
void SendFindIPC(const FindRequest& request, RenderFrameHost* rfh); |
- // Send a stop finding IPC to the RenderFrame associated with |rfh|. |
+ // Sends a stop finding IPC to the RenderFrame associated with |rfh|. |
void SendStopFindingIPC(StopFindAction action, RenderFrameHost* rfh) const; |
- // Reset all of the per-session state for a new find-in-page session. |
- void Reset(const FindRequest& initial_request); |
- |
- // Send the find results (as they currently are) to the WebContents. |
+ // Sends the find results (as they currently are) to the WebContents. |
void NotifyFindReply(int request_id, bool final_update) const; |
+ // Returns the initial frame in search order. This will be either the first |
+ // frame, if searching forward, or the last frame, if searching backward. |
+ RenderFrameHost* GetInitialFrame(bool forward) const; |
+ |
+ // Traverses the frame tree to find and return the next RenderFrameHost after |
+ // |rfh| in search order. |forward| indicates whether the frame tree should be |
+ // traversed forward (if true) or backward (if false). If |matches_only| is |
+ // set, then the frame tree will be traversed until the first frame is found |
+ // for which matches have been found. If |wrap| is set, then the traversal can |
+ // wrap around past the last frame to the first one (or vice-versa, if |
+ // |forward| == false). If no frame can be found under these conditions, |
+ // nullptr is returned. |
+ RenderFrameHost* Traverse(RenderFrameHost* rfh, |
+ bool forward, |
+ bool matches_only, |
+ bool wrap) const; |
+ |
+ // Adds a frame to the set of frames that are being searched. The new frame |
+ // will automatically be searched when added, using the same options (stored |
+ // in |current_request_.options|). |
+ void AddFrame(RenderFrameHost* rfh); |
+ |
+ // Returns whether the frame associated with |rfh| is in the set of frames |
+ // being searched in the current find session. |
+ bool CheckFrame(RenderFrameHost* rfh) const; |
+ bool CheckFrame(const FrameKey& frame_key) const; |
+ |
+ // Computes and updates |active_match_ordinal_| based on |
+ // |relative_active_match_ordinal_|. |
+ void UpdateActiveMatchOrdinal(); |
+ |
+ // Called when all pending find replies have been received. |
+ void FinalUpdate(int request_id, RenderFrameHost* rfh); |
+ |
#if defined(OS_ANDROID) |
- // Request the latest find match rects from a frame. |
+ // Requests the distance to the nearest find result in the frame associated |
+ // with |rfh| from the point (x,y) defined in find-in-page coordinates. |
+ void SendGetNearestFindResultIPC(RenderFrameHost* rfh); |
+ |
+ // Called when a nearest find result reply is no longer pending for a frame. |
+ void RemoveNearestFindResultPendingReply(FrameKey frame_key); |
+ |
+ // Requests the latest find match rects from a frame. |
void SendFindMatchRectsIPC(RenderFrameHost* rfh); |
+ // Called when a find match rects reply is no longer pending for a frame. |
+ void RemoveFindMatchRectsPendingReply(FrameKey frame_key); |
+ |
+ // State related to ActivateNearestFindResult requests. |
+ struct ActivateNearestFindResultState { |
+ // An ID to uniquely identify the current nearest find result request and |
+ // its replies. |
+ int current_request_id = kInvalidId; |
+ |
+ // The x value of the requested point, in find-in-page coordinates. |
+ float x = 0.0f; |
+ |
+ // The y value of the requested point, in find-in-page coordinates. |
+ float y = 0.0f; |
+ |
+ // The distance to the nearest result found so far. |
+ float nearest_distance = FLT_MAX; |
+ |
+ // The frame containing the nearest result found so far. |
+ FrameKey nearest_frame = std::make_pair(kInvalidId, kInvalidId); |
+ |
+ // Nearest find result replies are still pending for these frames. |
+ std::set<FrameKey> pending_replies; |
+ |
+ ActivateNearestFindResultState(); |
+ ActivateNearestFindResultState(float x, float y); |
+ ~ActivateNearestFindResultState(); |
+ |
+ static int GetNextID() { |
+ static int next_id = 0; |
+ return next_id++; |
+ } |
+ } activate_; |
+ |
// State related to FindMatchRects requests. |
struct FindMatchRectsState { |
- // The latest find match rects version known by the requester. |
+ // The latest find match rects version known by the requester. This will be |
+ // compared to |fmr_version_| after polling frames for updates to their |
lfg
2016/05/13 20:15:40
Did you mean known_version instead of fmr_version_
paulmeyer
2016/05/16 15:25:11
Yes I did. There was something called fmr_version_
|
+ // match rects, in order to determine if the requester already has the |
+ // latest version of rects or not. |
int request_version = kInvalidId; |
+ |
+ // The current overall find match rects version known by FindRequestManager. |
+ int known_version = 0; |
+ |
+ // A map from each frame to its find match rects and the version number for |
+ // those rects. |
+ using RectData = std::pair<int, std::vector<gfx::RectF>>; |
+ std::map<FrameKey, RectData> rects; |
+ |
+ // The active find match rect. |
+ gfx::RectF active_rect; |
+ |
+ // Find match rects replies are still pending for these frames. |
+ std::set<FrameKey> pending_replies; |
+ |
+ FindMatchRectsState(); |
+ ~FindMatchRectsState(); |
} match_rects_; |
#endif |
@@ -127,14 +250,39 @@ class FindRequestManager { |
// The current find request. |
FindRequest current_request_; |
- // The total number of matches found in the current find-in-page session. |
+ // The set of frames that are still expected to reply to a pending find |
+ // request. Frames are removed from |pending_replies_| when their reply with |
+ // |final_update| set to true is received. |
+ std::set<FrameKey> pending_replies_; |
+ |
+ // Indicates whether an update to the active match ordinal is expected. The |
+ // value is the ID of the request for which the ordinal is pending, or |
+ // kInvalidId otherwise. |
+ int pending_active_match_ordinal_; |
+ |
+ // The number of matches found in each frame, stored by a (process ID, frame |
+ // ID) pair that uniquely identifies each frame. There will necessarily be |
+ // entries in this map for every frame that is being (or has been) searched in |
+ // the current find session, and no other frames. |
+ std::map<FrameKey, int> matches_per_frame_; |
+ |
+ // The total number of matches found in the current find-in-page session. This |
+ // should always be equal to the sum of all the entries in |
+ // |matches_per_frame_|. |
int number_of_matches_; |
+ // The active match ordinal relative to the matches found in its own frame. |
+ std::pair<FrameKey, int> relative_active_match_ordinal_; |
+ |
// The overall active match ordinal for the current find-in-page session. |
int active_match_ordinal_; |
// The rectangle around the active match, in screen coordinates. |
gfx::Rect selection_rect_; |
+ |
+ // Find requests are queued here when previous requests need to be handled |
+ // before these ones can be properly routed. |
+ std::queue<FindRequest> find_request_queue_; |
}; |
} // namespace content |