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_REMOTE_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_REMOTE_H_ 7 8 #include <utility> 9 10 #include "mojo/public/cpp/bindings/remote.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 // HeapMojoRemote is a wrapper for mojo::Remote to be owned by a 19 // garbage-collected object. Blink is expected to use HeapMojoRemote by 20 // default. HeapMojoRemote must be associated with context. 21 // HeapMojoRemote's constructor takes context as a mandatory parameter. 22 // HeapMojoRemote resets the mojo connection when the associated 23 // ExecutionContext is detached. 24 25 // TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure 26 // that the interface is not used after ContextDestroyed(). 27 template <typename Interface, 28 HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver> 29 class HeapMojoRemote { 30 DISALLOW_NEW(); 31 32 public: HeapMojoRemote(ContextLifecycleNotifier * notifier)33 explicit HeapMojoRemote(ContextLifecycleNotifier* notifier) 34 : wrapper_(MakeGarbageCollected<Wrapper>(notifier)) {} 35 HeapMojoRemote(const HeapMojoRemote&) = delete; 36 HeapMojoRemote& operator=(const HeapMojoRemote&) = delete; 37 HeapMojoRemote(HeapMojoRemote&&) = default; 38 HeapMojoRemote& operator=(HeapMojoRemote&&) = default; 39 40 // Methods to redirect to mojo::Remote. 41 using Proxy = typename Interface::Proxy_; 42 Proxy* operator->() const { return get(); } get()43 Proxy* get() const { return wrapper_->remote().get(); } is_bound()44 bool is_bound() const { return wrapper_->remote().is_bound(); } is_connected()45 bool is_connected() const { return wrapper_->remote().is_connected(); } reset()46 void reset() { wrapper_->remote().reset(); } ResetWithReason(uint32_t custom_reason,const std::string & description)47 void ResetWithReason(uint32_t custom_reason, const std::string& description) { 48 wrapper_->remote().ResetWithReason(custom_reason, description); 49 } set_disconnect_handler(base::OnceClosure handler)50 void set_disconnect_handler(base::OnceClosure handler) { 51 wrapper_->remote().set_disconnect_handler(std::move(handler)); 52 } set_disconnect_with_reason_handler(mojo::ConnectionErrorWithReasonCallback handler)53 void set_disconnect_with_reason_handler( 54 mojo::ConnectionErrorWithReasonCallback handler) { 55 wrapper_->remote().set_disconnect_with_reason_handler(std::move(handler)); 56 } BindNewPipeAndPassReceiver(scoped_refptr<base::SequencedTaskRunner> task_runner)57 mojo::PendingReceiver<Interface> BindNewPipeAndPassReceiver( 58 scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT { 59 DCHECK(task_runner); 60 return wrapper_->remote().BindNewPipeAndPassReceiver( 61 std::move(task_runner)); 62 } Bind(mojo::PendingRemote<Interface> pending_remote,scoped_refptr<base::SequencedTaskRunner> task_runner)63 void Bind(mojo::PendingRemote<Interface> pending_remote, 64 scoped_refptr<base::SequencedTaskRunner> task_runner) { 65 DCHECK(task_runner); 66 wrapper_->remote().Bind(std::move(pending_remote), std::move(task_runner)); 67 } PauseReceiverUntilFlushCompletes(mojo::PendingFlush flush)68 void PauseReceiverUntilFlushCompletes(mojo::PendingFlush flush) { 69 wrapper_->remote().PauseReceiverUntilFlushCompletes(std::move(flush)); 70 } FlushAsync()71 mojo::PendingFlush FlushAsync() { return wrapper_->remote().FlushAsync(); } FlushForTesting()72 void FlushForTesting() { return wrapper_->remote().FlushForTesting(); } 73 Trace(Visitor * visitor)74 void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); } 75 76 private: 77 // Garbage collected wrapper class to add ContextLifecycleObserver. 78 class Wrapper final : public GarbageCollected<Wrapper>, 79 public ContextLifecycleObserver { 80 public: Wrapper(ContextLifecycleNotifier * notifier)81 explicit Wrapper(ContextLifecycleNotifier* notifier) { 82 SetContextLifecycleNotifier(notifier); 83 } 84 Wrapper(const Wrapper&) = delete; 85 Wrapper& operator=(const Wrapper&) = delete; 86 Wrapper(Wrapper&&) = default; 87 Wrapper& operator=(Wrapper&&) = default; 88 Trace(Visitor * visitor)89 void Trace(Visitor* visitor) const override { 90 ContextLifecycleObserver::Trace(visitor); 91 } 92 remote()93 mojo::Remote<Interface>& remote() { return remote_; } 94 95 // ContextLifecycleObserver methods ContextDestroyed()96 void ContextDestroyed() override { 97 if (Mode == HeapMojoWrapperMode::kWithContextObserver || 98 (Mode == HeapMojoWrapperMode::kWithoutContextObserver && 99 base::FeatureList::IsEnabled(kHeapMojoUseContextObserver))) 100 remote_.reset(); 101 } 102 103 private: 104 mojo::Remote<Interface> remote_; 105 }; 106 107 Member<Wrapper> wrapper_; 108 }; 109 110 } // namespace blink 111 112 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_REMOTE_H_ 113