1 // Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_ASSOCIATED_RECEIVER_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_ASSOCIATED_RECEIVER_H_ 7 8 #include <utility> 9 10 #include "mojo/public/cpp/bindings/associated_receiver.h" 11 #include "third_party/blink/renderer/platform/context_lifecycle_observer.h" 12 #include "third_party/blink/renderer/platform/heap/heap.h" 13 #include "third_party/blink/renderer/platform/mojo/features.h" 14 #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" 15 16 namespace blink { 17 18 // HeapMojoAssociatedReceiver is a wrapper for mojo::AssociatedReceiver to be 19 // owned by a garbage-collected object. Blink is expected to use 20 // HeapMojoAssociatedReceiver by default. HeapMojoAssociatedReceiver must be 21 // associated with context. HeapMojoAssociatedReceiver's constructor takes 22 // context as a mandatory parameter. HeapMojoAssociatedReceiver resets the mojo 23 // connection when 1) the owner object is garbage-collected and 2) the 24 // associated ExecutionContext is detached. 25 26 // TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure 27 // that the interface is not used after ContextDestroyed(). 28 template <typename Interface, 29 typename Owner, 30 HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver> 31 class HeapMojoAssociatedReceiver { 32 DISALLOW_NEW(); 33 34 public: HeapMojoAssociatedReceiver(Owner * owner,ContextLifecycleNotifier * context)35 HeapMojoAssociatedReceiver(Owner* owner, ContextLifecycleNotifier* context) 36 : wrapper_(MakeGarbageCollected<Wrapper>(owner, context)) { 37 static_assert(std::is_base_of<Interface, Owner>::value, 38 "Owner should implement Interface"); 39 static_assert(IsGarbageCollectedType<Owner>::value, 40 "Owner needs to be a garbage collected object"); 41 } 42 HeapMojoAssociatedReceiver(const HeapMojoAssociatedReceiver&) = delete; 43 HeapMojoAssociatedReceiver& operator=(const HeapMojoAssociatedReceiver&) = 44 delete; 45 46 // Methods to redirect to mojo::AssociatedReceiver: is_bound()47 bool is_bound() const { return wrapper_->associated_receiver().is_bound(); } reset()48 void reset() { wrapper_->associated_receiver().reset(); } set_disconnect_handler(base::OnceClosure handler)49 void set_disconnect_handler(base::OnceClosure handler) { 50 wrapper_->associated_receiver().set_disconnect_handler(std::move(handler)); 51 } BindNewEndpointAndPassRemote(scoped_refptr<base::SequencedTaskRunner> task_runner)52 mojo::PendingAssociatedRemote<Interface> BindNewEndpointAndPassRemote( 53 scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT { 54 DCHECK(task_runner); 55 return wrapper_->associated_receiver().BindNewEndpointAndPassRemote( 56 std::move(task_runner)); 57 } Bind(mojo::PendingAssociatedReceiver<Interface> pending_associated_receiver,scoped_refptr<base::SequencedTaskRunner> task_runner)58 void Bind( 59 mojo::PendingAssociatedReceiver<Interface> pending_associated_receiver, 60 scoped_refptr<base::SequencedTaskRunner> task_runner) { 61 DCHECK(task_runner); 62 wrapper_->associated_receiver().Bind(std::move(pending_associated_receiver), 63 std::move(task_runner)); 64 } WaitForIncomingCall()65 bool WaitForIncomingCall() { 66 return wrapper_->associated_receiver().WaitForIncomingCall(); 67 } 68 SetFilter(std::unique_ptr<mojo::MessageFilter> filter)69 void SetFilter(std::unique_ptr<mojo::MessageFilter> filter) { 70 wrapper_->associated_receiver().SetFilter(std::move(filter)); 71 } 72 Trace(Visitor * visitor)73 void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); } 74 75 private: 76 FRIEND_TEST_ALL_PREFIXES(HeapMojoAssociatedReceiverGCWithContextObserverTest, 77 NoResetOnConservativeGC); 78 79 // Garbage collected wrapper class to add a prefinalizer. 80 class Wrapper final : public GarbageCollected<Wrapper>, 81 public ContextLifecycleObserver { 82 USING_PRE_FINALIZER(Wrapper, Dispose); 83 84 public: Wrapper(Owner * owner,ContextLifecycleNotifier * notifier)85 Wrapper(Owner* owner, ContextLifecycleNotifier* notifier) 86 : owner_(owner), associated_receiver_(owner) { 87 SetContextLifecycleNotifier(notifier); 88 } 89 Trace(Visitor * visitor)90 void Trace(Visitor* visitor) const override { 91 visitor->Trace(owner_); 92 ContextLifecycleObserver::Trace(visitor); 93 } 94 Dispose()95 void Dispose() { associated_receiver_.reset(); } 96 associated_receiver()97 mojo::AssociatedReceiver<Interface>& associated_receiver() { 98 return associated_receiver_; 99 } 100 101 // ContextLifecycleObserver methods ContextDestroyed()102 void ContextDestroyed() override { 103 if (Mode == HeapMojoWrapperMode::kWithContextObserver || 104 (Mode == HeapMojoWrapperMode::kWithoutContextObserver && 105 base::FeatureList::IsEnabled(kHeapMojoUseContextObserver))) 106 associated_receiver_.reset(); 107 } 108 109 private: 110 Member<Owner> owner_; 111 mojo::AssociatedReceiver<Interface> associated_receiver_; 112 }; 113 114 Member<Wrapper> wrapper_; 115 }; 116 117 } // namespace blink 118 119 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_ASSOCIATED_RECEIVER_H_ 120