xref: /aosp_15_r20/external/cronet/ipc/ipc_mojo_bootstrap.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef IPC_IPC_MOJO_BOOTSTRAP_H_
6*6777b538SAndroid Build Coastguard Worker #define IPC_IPC_MOJO_BOOTSTRAP_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/component_export.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
16*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
17*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc.mojom.h"
18*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel.h"
19*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_listener.h"
20*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_group.h"
21*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_remote.h"
22*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
23*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message_pipe.h"
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker namespace IPC {
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker class UrgentMessageObserver;
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker // Incoming legacy IPCs have always been dispatched to one of two threads: the
30*6777b538SAndroid Build Coastguard Worker // IO thread (when an installed MessageFilter handles the message), or the
31*6777b538SAndroid Build Coastguard Worker // thread which owns the corresponding ChannelProxy receiving the message. There
32*6777b538SAndroid Build Coastguard Worker // were no other places to route legacy IPC messages, so when a message arrived
33*6777b538SAndroid Build Coastguard Worker // the legacy IPC system would run through its MessageFilters and if the message
34*6777b538SAndroid Build Coastguard Worker // was still unhandled, it would be posted to the ChannelProxy thread for
35*6777b538SAndroid Build Coastguard Worker // further processing.
36*6777b538SAndroid Build Coastguard Worker //
37*6777b538SAndroid Build Coastguard Worker // Mojo on the other hand allows for mutually associated endpoints (that is,
38*6777b538SAndroid Build Coastguard Worker // endpoints which locally share the same message pipe) to span any number of
39*6777b538SAndroid Build Coastguard Worker // threads while still guaranteeing that each endpoint on a given thread
40*6777b538SAndroid Build Coastguard Worker // preserves FIFO order of messages dispatched there. This means that if a
41*6777b538SAndroid Build Coastguard Worker // message arrives carrying a PendingAssociatedRemote/Receiver endpoint, and
42*6777b538SAndroid Build Coastguard Worker // then another message arrives which targets that endpoint, the entire pipe
43*6777b538SAndroid Build Coastguard Worker // will be blocked from dispatch until the endpoint is bound: otherwise we have
44*6777b538SAndroid Build Coastguard Worker // no idea where to dispatch the message such that we can uphold the FIFO
45*6777b538SAndroid Build Coastguard Worker // guarantee between the new endpoint and any other endpoints on the thread it
46*6777b538SAndroid Build Coastguard Worker // ends up binding to.
47*6777b538SAndroid Build Coastguard Worker //
48*6777b538SAndroid Build Coastguard Worker // Channel-associated interfaces share a message pipe with the legacy IPC
49*6777b538SAndroid Build Coastguard Worker // Channel, and in order to avoid nasty surprises during the migration process
50*6777b538SAndroid Build Coastguard Worker // we decided to constrain how incoming Channel-associated endpoints could be
51*6777b538SAndroid Build Coastguard Worker // bound: you must either bind them immediately as they arrive on the IO thread,
52*6777b538SAndroid Build Coastguard Worker // or you must immediately post a task to the ChannelProxy thread to bind them.
53*6777b538SAndroid Build Coastguard Worker // This allows all aforementioned FIFO guaratees to be upheld without ever
54*6777b538SAndroid Build Coastguard Worker // stalling dispatch of legacy IPCs (particularly on the IO thread), because
55*6777b538SAndroid Build Coastguard Worker // when we see a message targeting an unbound endpoint we can safely post it to
56*6777b538SAndroid Build Coastguard Worker // the ChannelProxy's task runner before forging ahead to dispatch subsequent
57*6777b538SAndroid Build Coastguard Worker // messages. No stalling.
58*6777b538SAndroid Build Coastguard Worker //
59*6777b538SAndroid Build Coastguard Worker // As there are some cases where a Channel-associated endpoint really wants to
60*6777b538SAndroid Build Coastguard Worker // receive messages on a different TaskRunner, we want to allow that now. It's
61*6777b538SAndroid Build Coastguard Worker // safe as long as the application can guarantee that the endpoint in question
62*6777b538SAndroid Build Coastguard Worker // will be bound to a task runner *before* any messages are received for that
63*6777b538SAndroid Build Coastguard Worker // endpoint.
64*6777b538SAndroid Build Coastguard Worker //
65*6777b538SAndroid Build Coastguard Worker // HOWEVER, it turns out that we cannot simply adhere to the application's
66*6777b538SAndroid Build Coastguard Worker // wishes when an alternative TaskRunner is provided at binding time: over time
67*6777b538SAndroid Build Coastguard Worker // we have accumulated application code which binds Channel-associated endpoints
68*6777b538SAndroid Build Coastguard Worker // to task runners which -- while running tasks exclusively on the ChannelProxy
69*6777b538SAndroid Build Coastguard Worker // thread -- are not the ChannelProxy's own task runner. Such code now
70*6777b538SAndroid Build Coastguard Worker // implicitly relies on the behavior of Channel-associated interfaces always
71*6777b538SAndroid Build Coastguard Worker // dispatching their messages to the ChannelProxy task runner. This is tracked
72*6777b538SAndroid Build Coastguard Worker // by https://crbug.com/1209188.
73*6777b538SAndroid Build Coastguard Worker //
74*6777b538SAndroid Build Coastguard Worker // Finally, the point: if you really know you want to bind your endpoint to an
75*6777b538SAndroid Build Coastguard Worker // alternative task runner and you can really guarantee that no messages may
76*6777b538SAndroid Build Coastguard Worker // have already arrived for it on the IO thread, you can do the binding within
77*6777b538SAndroid Build Coastguard Worker // the extent of a ScopedAllowOffSequenceChannelAssociatedBindings. This will
78*6777b538SAndroid Build Coastguard Worker // flag the endpoint such that it honors your binding configuration, and its
79*6777b538SAndroid Build Coastguard Worker // incoming messages will actually dispatch to the task runner you provide.
COMPONENT_EXPORT(IPC)80*6777b538SAndroid Build Coastguard Worker class COMPONENT_EXPORT(IPC)
81*6777b538SAndroid Build Coastguard Worker     [[maybe_unused,
82*6777b538SAndroid Build Coastguard Worker       nodiscard]] ScopedAllowOffSequenceChannelAssociatedBindings {
83*6777b538SAndroid Build Coastguard Worker  public:
84*6777b538SAndroid Build Coastguard Worker   ScopedAllowOffSequenceChannelAssociatedBindings();
85*6777b538SAndroid Build Coastguard Worker   ~ScopedAllowOffSequenceChannelAssociatedBindings();
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker  private:
88*6777b538SAndroid Build Coastguard Worker   const base::AutoReset<bool> resetter_;
89*6777b538SAndroid Build Coastguard Worker };
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker // MojoBootstrap establishes a pair of associated interfaces between two
92*6777b538SAndroid Build Coastguard Worker // processes in Chrome.
93*6777b538SAndroid Build Coastguard Worker //
94*6777b538SAndroid Build Coastguard Worker // Clients should implement MojoBootstrap::Delegate to get the associated pipes
95*6777b538SAndroid Build Coastguard Worker // from MojoBootstrap object.
96*6777b538SAndroid Build Coastguard Worker //
97*6777b538SAndroid Build Coastguard Worker // This lives on IO thread other than Create(), which can be called from
98*6777b538SAndroid Build Coastguard Worker // UI thread as Channel::Create() can be.
COMPONENT_EXPORT(IPC)99*6777b538SAndroid Build Coastguard Worker class COMPONENT_EXPORT(IPC) MojoBootstrap {
100*6777b538SAndroid Build Coastguard Worker  public:
101*6777b538SAndroid Build Coastguard Worker   virtual ~MojoBootstrap() {}
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   // Create the MojoBootstrap instance, using |handle| as the message pipe, in
104*6777b538SAndroid Build Coastguard Worker   // mode as specified by |mode|. The result is passed to |delegate|.
105*6777b538SAndroid Build Coastguard Worker   static std::unique_ptr<MojoBootstrap> Create(
106*6777b538SAndroid Build Coastguard Worker       mojo::ScopedMessagePipeHandle handle,
107*6777b538SAndroid Build Coastguard Worker       Channel::Mode mode,
108*6777b538SAndroid Build Coastguard Worker       const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
109*6777b538SAndroid Build Coastguard Worker       const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner);
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   // Initialize the Channel pipe and interface endpoints. This performs all
112*6777b538SAndroid Build Coastguard Worker   // setup except actually starting to read messages off the pipe.
113*6777b538SAndroid Build Coastguard Worker   virtual void Connect(
114*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedRemote<mojom::Channel>* sender,
115*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<mojom::Channel>* receiver) = 0;
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   // Enable incoming messages to start being read off the pipe and routed to
118*6777b538SAndroid Build Coastguard Worker   // endpoints. Must not be called until the pending endpoints created by
119*6777b538SAndroid Build Coastguard Worker   // Connect() are actually bound somewhere.
120*6777b538SAndroid Build Coastguard Worker   virtual void StartReceiving() = 0;
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   // Stop transmitting messages and start queueing them instead.
123*6777b538SAndroid Build Coastguard Worker   virtual void Pause() = 0;
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   // Stop queuing new messages and start transmitting them instead.
126*6777b538SAndroid Build Coastguard Worker   virtual void Unpause() = 0;
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   // Flush outgoing messages which were queued before Start().
129*6777b538SAndroid Build Coastguard Worker   virtual void Flush() = 0;
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   virtual mojo::AssociatedGroup* GetAssociatedGroup() = 0;
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker   virtual void SetUrgentMessageObserver(UrgentMessageObserver* observer) = 0;
134*6777b538SAndroid Build Coastguard Worker };
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker #endif  // IPC_IPC_MOJO_BOOTSTRAP_H_
139