File: extension_api_frame_id_map.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (222 lines) | stat: -rw-r--r-- 8,533 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
#define EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_

#include <map>
#include <memory>
#include <set>

#include "base/lazy_instance.h"
#include "base/unguessable_token.h"
#include "base/uuid.h"
#include "content/public/browser/document_user_data.h"
#include "content/public/browser/frame_type.h"
#include "content/public/browser/global_routing_id.h"
#include "extensions/common/api/extension_types.h"

namespace content {
class NavigationHandle;
class RenderFrameHost;
class WebContents;
}  // namespace content

namespace extensions {

// Extension frame IDs are exposed through the chrome.* APIs and have the
// following characteristics:
// - The top-level frame has ID 0.
// - Any child frame has a positive ID.
// - A non-existent frame has ID -1.
// - They are only guaranteed to be unique within a tab.
// - The ID does not change during the frame's lifetime and is not re-used after
//   the frame is removed. The frame may change its current RenderFrameHost over
//   time, so multiple RenderFrameHosts may map to the same extension frame ID.
//
// This class provides a mapping from a (render_process_id, frame_routing_id)
// pair to a FrameData struct, which includes the extension's frame id (as
// described above), the parent frame id, and the tab id (the latter can be
// invalid if it's not in a tab).
//
// Unless stated otherwise, the methods can only be called on the UI thread.
//
// The non-static methods of this class use an internal cache.
class ExtensionApiFrameIdMap {
 public:
  using DocumentId = base::UnguessableToken;

  // The data for a RenderFrame. Every GlobalRenderFrameHostId maps to a
  // FrameData.
  struct FrameData {
    FrameData();
    FrameData(int frame_id,
              int parent_frame_id,
              int tab_id,
              int window_id,
              const DocumentId& document_id,
              const DocumentId& parent_document_id,
              api::extension_types::FrameType frame_type,
              api::extension_types::DocumentLifecycle document_lifecycle);
    ~FrameData();

    FrameData(const FrameData&);
    FrameData& operator=(const FrameData&);

    // The extension API frame ID of the frame.
    int frame_id;

    // The extension API frame ID of the parent of the frame.
    int parent_frame_id;

    // The id of the tab that the frame is in, or -1 if the frame isn't in a
    // tab.
    int tab_id;

    // The id of the window that the frame is in, or -1 if the frame isn't in a
    // window.
    int window_id;

    // The extension API document ID of the document in the frame.
    DocumentId document_id;

    // The extension API document ID of the parent document of the frame.
    DocumentId parent_document_id;

    // The type that this frame represents.
    api::extension_types::FrameType frame_type =
        api::extension_types::FrameType::kNone;

    // The lifecycle state the frame is currently in.
    api::extension_types::DocumentLifecycle document_lifecycle =
        api::extension_types::DocumentLifecycle::kNone;
  };

  // An invalid extension API frame ID.
  static const int kInvalidFrameId;

  // Extension API frame ID of the top-level frame.
  static const int kTopFrameId;

  ExtensionApiFrameIdMap(const ExtensionApiFrameIdMap&) = delete;
  ExtensionApiFrameIdMap& operator=(const ExtensionApiFrameIdMap&) = delete;

  static ExtensionApiFrameIdMap* Get();

  // Get the extension API frame ID for `render_frame_host`.
  static int GetFrameId(content::RenderFrameHost* render_frame_host);

  // Get the extension API frame ID for `navigation_handle`.
  static int GetFrameId(content::NavigationHandle* navigation_handle);

  // Get the extension API frame ID for the parent of `render_frame_host`.
  static int GetParentFrameId(content::RenderFrameHost* render_frame_host);

  // Get the extension API frame ID for the parent of `navigation_handle`.
  static int GetParentFrameId(content::NavigationHandle* navigation_handle);

  // Get the extension API document ID for the current document of
  // `render_frame_host`.
  static DocumentId GetDocumentId(content::RenderFrameHost* render_frame_host);

  // Get the extension API document ID for the document of `navigation_handle`.
  static DocumentId GetDocumentId(content::NavigationHandle* navigation_handle);

  // Gets the context ID (as used in `runtime.getContexts()`) for the given
  // `render_frame_host`).
  static base::Uuid GetContextId(content::RenderFrameHost* render_frame_host);

  // Get the extension API frame type for the current document of
  // `render_frame_host`.
  static api::extension_types::FrameType GetFrameType(
      content::RenderFrameHost* render_frame_host);

  // Get the extension API frame type for the frame of `navigation_handle`.
  static api::extension_types::FrameType GetFrameType(
      content::NavigationHandle* navigation_handle);

  // Get the extension API document lifecycle for the current document of
  // `render_frame_host`.
  static api::extension_types::DocumentLifecycle GetDocumentLifecycle(
      content::RenderFrameHost* render_frame_host);

  // Get the extension API document lifecycle for the frame of
  // `navigation_handle`.
  static api::extension_types::DocumentLifecycle GetDocumentLifecycle(
      content::NavigationHandle* navigation_handle);

  // Find the current RenderFrameHost for a given WebContents and extension
  // frame ID.
  // Returns nullptr if not found.
  static content::RenderFrameHost* GetRenderFrameHostById(
      content::WebContents* web_contents,
      int frame_id);

  // Find the current RenderFrameHost for given an extension frame ID.
  // Returns nullptr if not found.
  content::RenderFrameHost* GetRenderFrameHostByFrameId(int frame_id);

  // Find the current RenderFrameHost for a given extension documentID.
  // Returns nullptr if not found.
  content::RenderFrameHost* GetRenderFrameHostByDocumentId(
      const DocumentId& document_id);

  // Parses a serialized document id string to a DocumentId.
  static DocumentId DocumentIdFromString(const std::string& document_id);

  // Retrieves the FrameData for a given RenderFrameHost id.
  [[nodiscard]] FrameData GetFrameData(
      content::GlobalRenderFrameHostId render_frame_host_id);

  // Called when a render frame is deleted. Stores the FrameData for
  // `render_frame_host` in the deleted frames map so it can still be accessed
  // for beacon requests. The FrameData will be removed later in a task.
  void OnRenderFrameDeleted(content::RenderFrameHost* render_frame_host);

 protected:
  friend struct base::LazyInstanceTraitsBase<ExtensionApiFrameIdMap>;
  class ExtensionDocumentUserData
      : public content::DocumentUserData<ExtensionDocumentUserData> {
   public:
    explicit ExtensionDocumentUserData(
        content::RenderFrameHost* render_frame_host);
    ~ExtensionDocumentUserData() override;

    const DocumentId& document_id() const { return document_id_; }
    const base::Uuid& context_id() const { return context_id_; }

   private:
    friend content::DocumentUserData<ExtensionDocumentUserData>;
    DOCUMENT_USER_DATA_KEY_DECL();

    DocumentId document_id_;
    base::Uuid context_id_;
  };

  ExtensionApiFrameIdMap();
  ~ExtensionApiFrameIdMap();

  // Determines the value to be stored in `frame_data_map_` for a given key.
  // If `require_live_frame` is true, FrameData will only
  // Returns empty FrameData when the corresponding RenderFrameHost is not
  // alive and `require_live_frame` is true.
  FrameData KeyToValue(content::GlobalRenderFrameHostId key,
                       bool require_live_frame) const;
  FrameData KeyToValue(content::RenderFrameHost* render_frame_host,
                       bool require_live_frame) const;

  // Holds mappings of render frame key to FrameData from frames that have been
  // recently deleted. These are kept for a short time so beacon requests that
  // continue after a frame is unloaded can access the FrameData.
  using FrameDataMap = std::map<content::GlobalRenderFrameHostId, FrameData>;
  FrameDataMap deleted_frame_data_map_;

  // Holds mapping of DocumentIds to ExtensionDocumentUserData objects.
  using DocumentIdMap = std::map<DocumentId, ExtensionDocumentUserData*>;
  DocumentIdMap document_id_map_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_