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

Side by Side Diff: extensions/browser/extension_api_frame_id_map.h

Issue 1413543005: Use FrameTreeNode ID as frameId in extension APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Call callbacks ASAP, only use cache for GetFrameIdOnIO Created 4 years, 11 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
6 #define EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
7
8 #include <list>
9 #include <map>
10
11 #include "base/callback.h"
12 #include "base/lazy_instance.h"
13 #include "base/synchronization/lock.h"
14
15 namespace content {
16 class RenderFrameHost;
17 class WebContents;
18 } // namespace content
19
20 namespace extensions {
21
22 // Extension frame IDs are exposed through the chrome.* APIs and have the
23 // following characteristics:
24 // - The top-level frame has ID 0.
25 // - Any child frame has a positive ID.
26 // - A non-existant frame has ID -1.
27 // - They are only guaranteed to be unique within a tab.
28 // - The ID does not change during the frame's lifetime and is not re-used after
29 // the frame is removed. The frame may change its current RenderFrameHost over
30 // time, so multiple RenderFrameHosts may map to the same extension frame ID.
31
32 // This class provides a mapping from a (render_process_id, frame_routing_id)
33 // pair that maps a RenderFrameHost to an extension frame ID.
34 // Unless stated otherwise, the methods can only be called on the UI thread.
35 //
36 // The non-static methods of this class use an internal cache. This cache is
37 // used to minimize IO->UI->IO round-trips of GetFrameIdOnIO. If the cost of
38 // attaching FrameTreeNode IDs to requests is negligible (crbug.com/524228),
39 // then we can remove all key caching and remove the cache from this class.
40 // TODO(robwu): Keep an eye on crbug.com/524228 and act upon the outcome.
41 class ExtensionApiFrameIdMap {
42 public:
43 using FrameIdCallback =
44 base::Callback<void(int extension_api_frame_id,
45 int extension_api_parent_frame_id)>;
46
47 // An invalid extension API frame ID.
48 static const int kInvalidFrameId;
49
50 static ExtensionApiFrameIdMap* Get();
51
52 // Get the extension API frame ID for |rfh|.
53 static int GetFrameId(content::RenderFrameHost* rfh);
54 // Get the extension API frame ID for the parent of |rfh|.
55 static int GetParentFrameId(content::RenderFrameHost* rfh);
56
57 // Find the current RenderFrameHost for a given WebContents and extension
58 // frame ID.
59 // Returns nullptr if not found.
60 static content::RenderFrameHost* GetRenderFrameHostById(
61 content::WebContents* web_contents,
62 int frame_id);
63
64 // Runs |callback| with the result that is equivalent to calling GetFrameId()
65 // on the UI thread. Thread hopping is minimized if possible. Callbacks for
66 // the same |render_process_id| and |frame_routing_id| are guaranteed to be
67 // run in order. The order of other callbacks is undefined.
68 void GetFrameIdOnIO(int render_process_id,
69 int frame_routing_id,
70 const FrameIdCallback& callback);
71
72 // Look up the frame ID and store it in the map. This method should be called
73 // as early as possible, e.g. in a WebContentsObserver::RenderFrameCreated
74 // notification.
75 void CacheFrameId(content::RenderFrameHost* rfh);
76
77 // Remove the frame ID mapping for a given frame. This method can be called at
78 // any time, but it is typical to call this method when a frame is destroyed.
79 // If this method is not called, the cached mapping for the frame is retained
80 // forever.
81 void RemoveFrameId(content::RenderFrameHost* rfh);
82
83 protected:
84 friend struct base::DefaultLazyInstanceTraits<ExtensionApiFrameIdMap>;
85
86 // A set of identifiers that uniquely identifies a RenderFrame.
87 struct RenderFrameIdKey {
88 RenderFrameIdKey();
89 RenderFrameIdKey(int render_process_id, int frame_routing_id);
90
91 // The process ID of the renderer that contains the RenderFrame.
92 int render_process_id;
93 // The routing ID of the RenderFrame.
94 int frame_routing_id;
95
96 bool operator<(const RenderFrameIdKey& other) const;
97 bool operator==(const RenderFrameIdKey& other) const;
98 };
99
100 // The cached pair of frame IDs of the frame. Every RenderFrameIdKey
101 // maps to a CachedFrameIdPair.
102 struct CachedFrameIdPair {
103 CachedFrameIdPair();
104 CachedFrameIdPair(int frame_id, int parent_frame_id);
105
106 bool operator==(const CachedFrameIdPair& other) const {
107 return frame_id == other.frame_id &&
108 parent_frame_id == other.parent_frame_id;
109 }
110
111 // The extension API frame ID of the frame.
112 int frame_id;
113 // The extension API frame ID of the parent of the frame.
114 int parent_frame_id;
115 };
116
117 struct FrameIdCallbacks {
118 FrameIdCallbacks();
119 ~FrameIdCallbacks();
120
121 // This is a std::list so that iterators are not invalidated when the list
122 // is modified during an iteration.
123 std::list<FrameIdCallback> callbacks;
124
125 // To avoid re-entrant processing of callbacks.
126 bool is_iterating;
127
128 private:
129 DISALLOW_COPY_AND_ASSIGN(FrameIdCallbacks);
130 };
131
132 using FrameIdMap = std::map<RenderFrameIdKey, CachedFrameIdPair>;
133 using FrameIdCallbacksMap = std::map<RenderFrameIdKey, FrameIdCallbacks>;
134
135 ExtensionApiFrameIdMap();
136 ~ExtensionApiFrameIdMap();
137
138 // Determines the value to be stored in |frame_id_map_| for a given key. This
139 // method is only called when |key| is not in |frame_id_map_|.
140 // virtual for testing.
141 virtual CachedFrameIdPair KeyToValue(const RenderFrameIdKey& key) const;
142
143 CachedFrameIdPair LookupFrameIdOnUI(const RenderFrameIdKey& key);
144
145 // Called as soon as the frame ID is found for the given |key|, and runs all
146 // queued callbacks with |cached_frame_id_pair|.
147 void GotFrameIdOnIO(const RenderFrameIdKey& key,
148 const CachedFrameIdPair& cached_frame_id_pair);
149
150 // Implementation of CacheFrameId(RenderFrameHost), separated for testing.
151 void CacheFrameId(const RenderFrameIdKey& key);
152 // Implementation of RemoveFrameId(RenderFrameHost), separated for testing.
153 void RemoveFrameId(const RenderFrameIdKey& key);
154
155 // Queued callbacks for use on the IO thread.
156 FrameIdCallbacksMap callbacks_map_;
157
158 // This frameId map is only modified on the UI thread and used to minimize the
159 // number of thread hops on the IO thread.
160 FrameIdMap frame_id_map_;
161
162 // This lock protects |frame_id_map| from being concurrently written on the UI
163 // thread and read on the IO thread.
164 base::Lock frame_id_map_lock_;
165
166 DISALLOW_COPY_AND_ASSIGN(ExtensionApiFrameIdMap);
Devlin 2016/01/04 17:50:23 #include "base/macros.h"
robwu 2016/01/04 18:18:58 Done.
167 };
168
169 } // namespace extensions
170
171 #endif // EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
OLDNEW
« no previous file with comments | « extensions/browser/api/web_request/web_request_api_constants.cc ('k') | extensions/browser/extension_api_frame_id_map.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698