File: js_communication_host.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 (136 lines) | stat: -rw-r--r-- 5,209 bytes parent folder | download | duplicates (3)
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
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_
#define COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "components/js_injection/common/interfaces.mojom.h"
#include "components/origin_matcher/origin_matcher.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"

namespace content {
class RenderFrameHost;
}  // namespace content

namespace js_injection {

struct JsObject;
class WebMessageHostFactory;

struct DocumentStartJavaScript {
  DocumentStartJavaScript(std::u16string script,
                          origin_matcher::OriginMatcher allowed_origin_rules,
                          int32_t script_id);

  DocumentStartJavaScript(DocumentStartJavaScript&) = delete;
  DocumentStartJavaScript& operator=(DocumentStartJavaScript&) = delete;
  DocumentStartJavaScript(DocumentStartJavaScript&&) = default;
  DocumentStartJavaScript& operator=(DocumentStartJavaScript&&) = default;

  std::u16string script_;
  origin_matcher::OriginMatcher allowed_origin_rules_;
  int32_t script_id_;
};

// This class is 1:1 with WebContents, when AddWebMessageListener() is called,
// it stores the information in this class and send them to renderer side
// JsCommunication if there is any. When RenderFrameCreated() gets called, it
// needs to configure that new RenderFrame with the information stores in this
// class.
class JsCommunicationHost : public content::WebContentsObserver {
 public:
  explicit JsCommunicationHost(content::WebContents* web_contents);

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

  ~JsCommunicationHost() override;

  // Captures the result of adding script. There are two possibilities when
  // adding script: there was an error, in which case |error_message| is set,
  // otherwise the add was successful and |script_id| is set.
  struct AddScriptResult {
    AddScriptResult();
    AddScriptResult(const AddScriptResult&);
    AddScriptResult& operator=(const AddScriptResult&);
    ~AddScriptResult();

    std::optional<std::string> error_message;
    std::optional<int> script_id;
  };

  // Native side AddDocumentStartJavaScript, returns an error message if the
  // parameters didn't pass necessary checks.
  AddScriptResult AddDocumentStartJavaScript(
      const std::u16string& script,
      const std::vector<std::string>& allowed_origin_rules);

  bool RemoveDocumentStartJavaScript(int script_id);

  const std::vector<DocumentStartJavaScript>& GetDocumentStartJavascripts()
      const;

  // Adds a new WebMessageHostFactory. For any urls that match
  // |allowed_origin_rules|, |js_object_name| is registered as a JS object that
  // can be used by script on the page to send and receive messages. Returns
  // an empty string on success. On failure, the return string gives the error
  // message.
  std::u16string AddWebMessageHostFactory(
      std::unique_ptr<WebMessageHostFactory> factory,
      const std::u16string& js_object_name,
      const std::vector<std::string>& allowed_origin_rules);

  // Returns the factory previously registered under the specified name.
  void RemoveWebMessageHostFactory(const std::u16string& js_object_name);

  struct RegisteredFactory {
    std::u16string js_name;
    origin_matcher::OriginMatcher allowed_origin_rules;
    raw_ptr<WebMessageHostFactory> factory = nullptr;
  };

  // Returns the registered factories.
  std::vector<RegisteredFactory> GetWebMessageHostFactories();

  // content::WebContentsObserver implementations
  void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
  void RenderFrameHostStateChanged(
      content::RenderFrameHost* render_frame_host,
      content::RenderFrameHost::LifecycleState old_state,
      content::RenderFrameHost::LifecycleState new_state) override;
  void PrimaryPageChanged(content::Page& page) override;

 private:
  class JsToBrowserMessagingList;
  void NotifyFrameForWebMessageListener(
      content::RenderFrameHost* render_frame_host);
  void NotifyFrameForAllDocumentStartJavaScripts(
      content::RenderFrameHost* render_frame_host);
  void NotifyFrameForAddDocumentStartJavaScript(
      const DocumentStartJavaScript* script,
      content::RenderFrameHost* render_frame_host);
  void NotifyFrameForRemoveDocumentStartJavaScript(
      int32_t script_id,
      content::RenderFrameHost* render_frame_host);

  int32_t next_script_id_ = 0;
  std::vector<DocumentStartJavaScript> scripts_;
  std::vector<std::unique_ptr<JsObject>> js_objects_;
  std::map<content::GlobalRenderFrameHostId,
           std::unique_ptr<JsToBrowserMessagingList>>
      js_to_browser_messagings_;
  bool has_navigation_listener_ = false;
};

}  // namespace js_injection

#endif  // COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_