File: message_port.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (162 lines) | stat: -rw-r--r-- 5,909 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
// Copyright 2017 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_API_MESSAGING_MESSAGE_PORT_H_
#define EXTENSIONS_BROWSER_API_MESSAGING_MESSAGE_PORT_H_

#include <optional>
#include <string>

#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "extensions/browser/activity.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/common/api/messaging/port_id.h"
#include "extensions/common/mojom/message_port.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "url/origin.h"

class GURL;

namespace content {
class RenderFrameHost;
}

namespace extensions {

struct Message;
struct MessagingEndpoint;
struct PortContext;

// One side of the communication handled by extensions::MessageService.
class MessagePort
    : public mojom::MessagePortHost
{
 public:
  // Delegate handling the channel between the port and its host.
  class ChannelDelegate {
   public:
    // Closes the message channel associated with the given port, and notifies
    // the other side.
    virtual void CloseChannel(const PortId& port_id,
                              const std::string& error_message) = 0;
    // Closes the given port in the given `port_context`. If this was the last
    // context or if `close_channel` is true, then the other side is closed as
    // well.
    virtual void ClosePort(const PortId& port_id,
                           int process_id,
                           const PortContext& port_context,
                           bool close_channel) = 0;

    // Enqueues a message on a pending channel, or sends a message to the given
    // port if the channel isn't pending.
    virtual void PostMessage(const PortId& port_id, const Message& message) = 0;

    virtual void NotifyResponsePending(const PortId& port_id) = 0;
  };

  explicit MessagePort(base::WeakPtr<ChannelDelegate> channel_delegate,
                       const PortId& port_id);
  MessagePort(const MessagePort&) = delete;
  MessagePort& operator=(const MessagePort&) = delete;

  ~MessagePort() override;

  // Called right before a channel is created for this MessagePort and `port`.
  // This allows us to ensure that the ports have no RenderFrameHost instances
  // in common.
  virtual void RemoveCommonFrames(const MessagePort& port);

  // Checks whether the given RenderFrameHost is associated with this port.
  virtual bool HasFrame(
      const content::GlobalRenderFrameHostToken& frame_token) const;

  // Called right before a port is connected to a channel. If false, the port
  // is not used and the channel is closed.
  virtual bool IsValidPort() = 0;

  // Triggers the check of whether the port is still valid. If the port is
  // determined to be invalid, the channel will be closed. This should only be
  // called for opener ports.
  virtual void RevalidatePort();

  // Notifies the port that the channel has been opened.
  virtual void DispatchOnConnect(
      mojom::ChannelType channel_type,
      const std::string& channel_name,
      std::optional<base::Value::Dict> source_tab,
      const ExtensionApiFrameIdMap::FrameData& source_frame,
      int guest_process_id,
      int guest_render_frame_routing_id,
      const MessagingEndpoint& source_endpoint,
      const std::string& target_extension_id,
      const GURL& source_url,
      std::optional<url::Origin> source_origin,
      const std::set<base::UnguessableToken>& open_channel_tracking_ids);

  // Notifies the port that the channel has been closed. If `error_message` is
  // non-empty, it indicates an error occurred while opening the connection.
  virtual void DispatchOnDisconnect(const std::string& error_message);

  // Dispatches a message to this end of the communication.
  virtual void DispatchOnMessage(const Message& message) = 0;

  // Marks the port as opened by the specific frame or service worker.
  virtual void OpenPort(int process_id, const PortContext& port_context);

  // Closes the port for the given frame or service worker.
  virtual void ClosePort(int process_id, int routing_id, int worker_thread_id);

  // MessagePorts that target extensions will need to adjust their keepalive
  // counts for their lazy background page.
  virtual void IncrementLazyKeepaliveCount(Activity::Type activity_type);
  virtual void DecrementLazyKeepaliveCount(Activity::Type activity_type);

  // Notifies the message port that one of the receivers intents to respond
  // later.
  virtual void NotifyResponsePending();

  bool should_have_strong_keepalive() const {
    return should_have_strong_keepalive_;
  }
  bool is_for_onetime_channel() const { return is_for_onetime_channel_; }

  void set_should_have_strong_keepalive(bool should_have_strong_keepalive) {
    should_have_strong_keepalive_ = should_have_strong_keepalive;
  }
  void set_is_for_onetime_channel(bool is_for_onetime_channel) {
    is_for_onetime_channel_ = is_for_onetime_channel;
  }

  void AddReceiver(
      mojo::PendingAssociatedReceiver<mojom::MessagePortHost> receiver,
      int render_process_id,
      const PortContext& port_context);

 protected:
  MessagePort();

  // mojom::MessagePortHost overrides:
  void ClosePort(bool close_hannel) override;
  void PostMessage(Message message) override;
  void ResponsePending() override;

  base::WeakPtr<ChannelDelegate> weak_channel_delegate_;
  const PortId port_id_;

 private:
  // This port should keep the service worker alive while it is open.
  bool should_have_strong_keepalive_ = false;

  // This port was created for one-time messaging channel.
  bool is_for_onetime_channel_ = false;

  mojo::AssociatedReceiverSet<mojom::MessagePortHost,
                              std::pair<int, PortContext>>
      receivers_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_MESSAGING_MESSAGE_PORT_H_