object.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright 2022 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. #ifndef MOJO_CORE_IPCZ_DRIVER_OBJECT_H_
  5. #define MOJO_CORE_IPCZ_DRIVER_OBJECT_H_
  6. #include <cstddef>
  7. #include <cstdint>
  8. #include <tuple>
  9. #include "base/containers/span.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/memory/scoped_refptr.h"
  12. #include "build/build_config.h"
  13. #include "mojo/core/ipcz_api.h"
  14. #include "mojo/public/cpp/platform/platform_handle.h"
  15. #include "third_party/ipcz/include/ipcz/ipcz.h"
  16. namespace mojo::core::ipcz_driver {
  17. class Transport;
  18. // Common base class for objects managed by Mojo's ipcz driver.
  19. class ObjectBase : public base::RefCountedThreadSafe<ObjectBase> {
  20. public:
  21. REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
  22. enum Type : uint32_t {
  23. // An ipcz transport endpoint.
  24. kTransport,
  25. // A wrapped shared memory region.
  26. kSharedBuffer,
  27. // An active mapping for a shared memory region. These objects are not
  28. // serializable and cannot be transmitted over a Transport.
  29. kSharedBufferMapping,
  30. // A PlatformHandle which can be transmitted as-is by the platform's Channel
  31. // implementation, out-of-band from message data. This is the only type of
  32. // driver object which can be emitted by the driver's Serialize(), and it's
  33. // the only type accepted by its Transmit(). This type is unused on Windows,
  34. // where all platform handles are encoded as inline message data during
  35. // serialization.
  36. kTransmissiblePlatformHandle,
  37. // A PlatformHandle which may or may not be transmissible by the platform's
  38. // Channel implementation, but which can at least be transformed into
  39. // something transmissible during serialization.
  40. kWrappedPlatformHandle,
  41. // A MojoTrap instance used to emulate a Mojo trap. These objects are not
  42. // serializable and cannot be transmitted over a Transport.
  43. kMojoTrap,
  44. // An Invitation instance used to emulate Mojo process invitations. These
  45. // objects are not serializable and cannot be transmitted over a Transport.
  46. kInvitation,
  47. };
  48. explicit ObjectBase(Type type);
  49. Type type() const { return type_; }
  50. IpczDriverHandle handle() const {
  51. return reinterpret_cast<IpczDriverHandle>(this);
  52. }
  53. static ObjectBase* FromHandle(IpczDriverHandle handle) {
  54. return reinterpret_cast<ObjectBase*>(handle);
  55. }
  56. static IpczDriverHandle ReleaseAsHandle(scoped_refptr<ObjectBase> object) {
  57. return reinterpret_cast<IpczDriverHandle>(object.release());
  58. }
  59. static scoped_refptr<ObjectBase> TakeFromHandle(IpczDriverHandle handle) {
  60. scoped_refptr<ObjectBase> object(FromHandle(handle));
  61. if (object) {
  62. // We're inheriting a ref previously owned by `handle`, so drop the extra
  63. // ref we just added.
  64. object->Release();
  65. }
  66. return object;
  67. }
  68. // Closes this object.
  69. virtual void Close();
  70. // Indicates whether this object can be serialized at all.
  71. virtual bool IsSerializable() const;
  72. // Computes the number of bytes and platform handles required to serialize
  73. // this object for transmission through `transmitter`. Returns false if the
  74. // object cannot be serialized or transmitted as such.
  75. virtual bool GetSerializedDimensions(Transport& transmitter,
  76. size_t& num_bytes,
  77. size_t& num_handles);
  78. // Attempts to serialize this object into `data` and `handles` which are
  79. // already sufficiently sized according to GetSerializedDimensions(). Returns
  80. // false if serialization fails.
  81. virtual bool Serialize(Transport& transmitter,
  82. base::span<uint8_t> data,
  83. base::span<PlatformHandle> handles);
  84. protected:
  85. virtual ~ObjectBase();
  86. // Boxes a reference to `object` and returns an IpczHandle for the box.
  87. static IpczHandle Box(scoped_refptr<ObjectBase> object);
  88. // Peeks at `box` and returns its underlying driver handle.
  89. static IpczDriverHandle PeekBox(IpczHandle box);
  90. // Unboxes `box` and returns a reference to the object it contained.
  91. static scoped_refptr<ObjectBase> Unbox(IpczHandle box);
  92. private:
  93. friend class base::RefCountedThreadSafe<ObjectBase>;
  94. const Type type_;
  95. };
  96. // Type-specific base class which builds on ObjectBase but which infers its Type
  97. // from a static object_type() method defined by T.
  98. template <typename T>
  99. class Object : public ObjectBase {
  100. public:
  101. Object() : ObjectBase(T::object_type()) {}
  102. // Constructs a new T instance with the forwarded Args, and immediately boxes
  103. // a reference to it. Returns a handle to the new box.
  104. template <typename... Args>
  105. static IpczHandle MakeBoxed(Args&&... args) {
  106. return Box(base::MakeRefCounted<T>(std::forward<Args>(args)...));
  107. }
  108. static T* FromHandle(IpczDriverHandle handle) {
  109. ObjectBase* object = ObjectBase::FromHandle(handle);
  110. if (!object || object->type() != T::object_type()) {
  111. return nullptr;
  112. }
  113. return static_cast<T*>(object);
  114. }
  115. static scoped_refptr<T> TakeFromHandle(IpczDriverHandle handle) {
  116. scoped_refptr<T> object(FromHandle(handle));
  117. if (object) {
  118. // We're inheriting a ref previously owned by `handle`, so drop the extra
  119. // ref we just added.
  120. object->Release();
  121. }
  122. return object;
  123. }
  124. // Peeks at `box` and returns a pointer to its underlying T, if the underlying
  125. // driver object is in fact a T. Does not invalidate `box`.
  126. static T* FromBox(IpczHandle box) { return FromHandle(PeekBox(box)); }
  127. // Unboxes `box` and returns a reference to its underlying T. If `box` is not
  128. // a box that contains a T, this returns null.
  129. static scoped_refptr<T> Unbox(IpczHandle box) {
  130. scoped_refptr<T> object = base::WrapRefCounted(T::FromBox(box));
  131. if (object) {
  132. std::ignore = ObjectBase::Unbox(box);
  133. }
  134. return object;
  135. }
  136. protected:
  137. ~Object() override = default;
  138. };
  139. } // namespace mojo::core::ipcz_driver
  140. #endif // MOJO_CORE_IPCZ_DRIVER_OBJECT_H_