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 MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
7
8 #include <string>
9
10 #include "base/callback.h"
11 #include "base/component_export.h"
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/optional.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "mojo/public/cpp/bindings/disconnect_reason.h"
18 #include "mojo/public/cpp/bindings/interface_id.h"
19
20 namespace mojo {
21
22 class AssociatedGroupController;
23
24 // ScopedInterfaceEndpointHandle refers to one end of an interface, either the
25 // implementation side or the client side.
26 // Threading: At any given time, a ScopedInterfaceEndpointHandle should only
27 // be accessed from a single sequence.
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)28 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) ScopedInterfaceEndpointHandle {
29 public:
30 // Creates a pair of handles representing the two endpoints of an interface,
31 // which are not yet associated with a message pipe.
32 static void CreatePairPendingAssociation(
33 ScopedInterfaceEndpointHandle* handle0,
34 ScopedInterfaceEndpointHandle* handle1);
35
36 // Creates an invalid endpoint handle.
37 ScopedInterfaceEndpointHandle();
38
39 ScopedInterfaceEndpointHandle(ScopedInterfaceEndpointHandle&& other);
40
41 ~ScopedInterfaceEndpointHandle();
42
43 ScopedInterfaceEndpointHandle& operator=(
44 ScopedInterfaceEndpointHandle&& other);
45
46 bool is_valid() const;
47
48 // Returns true if the interface hasn't associated with a message pipe.
49 bool pending_association() const;
50
51 // Returns kInvalidInterfaceId when in pending association state or the handle
52 // is invalid.
53 InterfaceId id() const;
54
55 // Returns null when in pending association state or the handle is invalid.
56 AssociatedGroupController* group_controller() const;
57
58 // Returns the disconnect reason if the peer handle is closed before
59 // association and specifies a custom disconnect reason.
60 const base::Optional<DisconnectReason>& disconnect_reason() const;
61
62 enum AssociationEvent {
63 // The interface has been associated with a message pipe.
64 ASSOCIATED,
65 // The peer of this object has been closed before association.
66 PEER_CLOSED_BEFORE_ASSOCIATION
67 };
68
69 using AssociationEventCallback = base::OnceCallback<void(AssociationEvent)>;
70 // Note:
71 // - |handler| won't run if the handle is invalid. Otherwise, |handler| is run
72 // on the calling sequence asynchronously, even if the interface has already
73 // been associated or the peer has been closed before association.
74 // - |handler| won't be called after this object is destroyed or reset.
75 // - A null |handler| can be used to cancel the previous callback.
76 void SetAssociationEventHandler(AssociationEventCallback handler);
77
78 void reset();
79 void ResetWithReason(uint32_t custom_reason, const std::string& description);
80
81 private:
82 friend class AssociatedGroupController;
83 friend class AssociatedGroup;
84
85 class State;
86
87 // Used by AssociatedGroupController.
88 ScopedInterfaceEndpointHandle(
89 InterfaceId id,
90 scoped_refptr<AssociatedGroupController> group_controller);
91
92 // Used by AssociatedGroupController.
93 // The peer of this handle will join |peer_group_controller|.
94 bool NotifyAssociation(
95 InterfaceId id,
96 scoped_refptr<AssociatedGroupController> peer_group_controller);
97
98 void ResetInternal(const base::Optional<DisconnectReason>& reason);
99
100 // Used by AssociatedGroup.
101 // It is safe to run the returned callback on any sequence, or after this
102 // handle is destroyed.
103 // The return value of the getter:
104 // - If the getter is retrieved when the handle is invalid, the return value
105 // of the getter will always be null.
106 // - If the getter is retrieved when the handle is valid and non-pending,
107 // the return value of the getter will be non-null and remain unchanged
108 // even if the handle is later reset.
109 // - If the getter is retrieved when the handle is valid but pending
110 // asssociation, the return value of the getter will initially be null,
111 // change to non-null when the handle is associated, and remain unchanged
112 // ever since.
113 base::Callback<AssociatedGroupController*()> CreateGroupControllerGetter()
114 const;
115
116 scoped_refptr<State> state_;
117
118 DISALLOW_COPY_AND_ASSIGN(ScopedInterfaceEndpointHandle);
119 };
120
121 } // namespace mojo
122
123 #endif // MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
124